GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
cindex_rw.c
Go to the documentation of this file.
1 
2 /****************************************************************************
3 *
4 * MODULE: Vector library
5 *
6 * AUTHOR(S): Radim Blazek.
7 *
8 * PURPOSE: Lower level functions for reading/writing/manipulating vectors.
9 *
10 * COPYRIGHT: (C) 2001 by the GRASS Development Team
11 *
12 * This program is free software under the GNU General Public
13 * License (>=v2). Read the file COPYING that comes with GRASS
14 * for details.
15 *
16 *****************************************************************************/
17 #include <stdlib.h>
18 #include <string.h>
19 #include <grass/gis.h>
20 #include <grass/Vect.h>
21 #include <grass/version.h>
22 
23 int dig_write_cidx_head(GVFILE * fp, struct Plus_head *plus)
24 {
25  int i;
26  unsigned char buf[5];
27  long length = 9;
28 
29  G_debug(3, "dig_write_cidx_head()");
30 
31  dig_rewind(fp);
32  dig_set_cur_port(&(plus->cidx_port));
33 
34  /* Head of header */
35  /* bytes 1 - 5 */
36  buf[0] = GV_CIDX_VER_MAJOR;
37  buf[1] = GV_CIDX_VER_MINOR;
38  buf[2] = GV_CIDX_EARLIEST_MAJOR;
39  buf[3] = GV_CIDX_EARLIEST_MINOR;
40  buf[4] = plus->cidx_port.byte_order;
41  if (0 >= dig__fwrite_port_C(buf, 5, fp))
42  return (-1);
43 
44  /* bytes 6 - 9 : header size */
45  if (0 >= dig__fwrite_port_L(&length, 1, fp))
46  return (0);
47 
48  /* Body of header - info about all fields */
49  /* Number of fields */
50  if (0 >= dig__fwrite_port_I(&(plus->n_cidx), 1, fp))
51  return (-1);
52 
53  for (i = 0; i < plus->n_cidx; i++) {
54  int t;
55  struct Cat_index *ci;
56 
57  ci = &(plus->cidx[i]);
58 
59  G_debug(3, "cidx %d head offset: %ld", i, dig_ftell(fp));
60 
61  /* Field number */
62  if (0 >= dig__fwrite_port_I(&(ci->field), 1, fp))
63  return (-1);
64 
65  /* Number of categories */
66  if (0 >= dig__fwrite_port_I(&(ci->n_cats), 1, fp))
67  return (-1);
68 
69  /* Number of unique categories */
70  if (0 >= dig__fwrite_port_I(&(ci->n_ucats), 1, fp))
71  return (-1);
72 
73  /* Number of types */
74  if (0 >= dig__fwrite_port_I(&(ci->n_types), 1, fp))
75  return (-1);
76 
77  /* Types */
78  for (t = 0; t < ci->n_types; t++) {
79  int wtype;
80 
81  /* type */
82  wtype = dig_type_to_store(ci->type[t][0]);
83  if (0 >= dig__fwrite_port_I(&wtype, 1, fp))
84  return (-1);
85 
86  /* number of items */
87  if (0 >= dig__fwrite_port_I(&(ci->type[t][1]), 1, fp))
88  return (-1);
89 
90  }
91 
92  /* Offset */
93  if (0 >= dig__fwrite_port_L(&(ci->offset), 1, fp))
94  return (0);
95  G_debug(3, "cidx %d offset: %ld", i, ci->offset);
96  }
97 
98  G_debug(3, "cidx body offset %ld", dig_ftell(fp));
99 
100  return (0);
101 }
102 
103 /* return: 0 OK, -1 error */
104 int dig_read_cidx_head(GVFILE * fp, struct Plus_head *plus)
105 {
106  unsigned char buf[5];
107  int i, byte_order;
108 
109  dig_rewind(fp);
110 
111  /* bytes 1 - 5 */
112  if (0 >= dig__fread_port_C(buf, 5, fp))
113  return (-1);
114  plus->cidx_Version_Major = buf[0];
115  plus->cidx_Version_Minor = buf[1];
116  plus->cidx_Back_Major = buf[2];
117  plus->cidx_Back_Minor = buf[3];
118  byte_order = buf[4];
119 
120  G_debug(3,
121  "Cidx header: file version %d.%d , supported from GRASS version %d.%d",
122  plus->cidx_Version_Major, plus->cidx_Version_Minor,
123  plus->cidx_Back_Major, plus->cidx_Back_Minor);
124 
125  G_debug(3, " byte order %d", byte_order);
126 
127  /* check version numbers */
128  if (plus->cidx_Version_Major > GV_CIDX_VER_MAJOR ||
129  plus->cidx_Version_Minor > GV_CIDX_VER_MINOR) {
130  /* The file was created by GRASS library with higher version than this one */
131 
132  if (plus->cidx_Back_Major > GV_CIDX_VER_MAJOR ||
133  plus->cidx_Back_Minor > GV_CIDX_VER_MINOR) {
134  /* This version of GRASS lib is lower than the oldest which can read this format */
135  G_debug(1, "Category index format version %d.%d",
136  plus->cidx_Version_Major, plus->cidx_Version_Minor);
138  ("This version of GRASS (%d.%d) is too old to read this category index format."
139  " Try to rebuild topology or upgrade GRASS to at least version %d.",
140  GRASS_VERSION_MAJOR, GRASS_VERSION_MINOR, GRASS_VERSION_MAJOR + 1);
141  return (-1);
142  }
143 
144  G_warning
145  ("Your GRASS version does not fully support category index format %d.%d of the vector."
146  " Consider to rebuild topology or upgrade GRASS.",
147  plus->cidx_Version_Major, plus->cidx_Version_Minor);
148  }
149 
150  dig_init_portable(&(plus->cidx_port), byte_order);
151  dig_set_cur_port(&(plus->cidx_port));
152 
153  /* bytes 6 - 9 : header size */
154  if (0 >= dig__fread_port_L(&(plus->cidx_head_size), 1, fp))
155  return (-1);
156  G_debug(3, " header size %ld", plus->cidx_head_size);
157 
158  /* Body of header - info about all fields */
159  /* Number of fields */
160  if (0 >= dig__fread_port_I(&(plus->n_cidx), 1, fp))
161  return (-1);
162 
163  /* alloc space */
164  plus->a_cidx = plus->n_cidx;
165  plus->cidx =
166  (struct Cat_index *)G_malloc(plus->a_cidx * sizeof(struct Cat_index));
167 
168  for (i = 0; i < plus->n_cidx; i++) {
169  int t;
170  struct Cat_index *ci;
171 
172  ci = &(plus->cidx[i]);
173  ci->cat = NULL;
174  ci->a_cats = 0;
175 
176  /* Field number */
177  if (0 >= dig__fread_port_I(&(ci->field), 1, fp))
178  return (-1);
179 
180  /* Number of categories */
181  if (0 >= dig__fread_port_I(&(ci->n_cats), 1, fp))
182  return (-1);
183 
184  /* Number of unique categories */
185  if (0 >= dig__fread_port_I(&(ci->n_ucats), 1, fp))
186  return (-1);
187 
188  /* Number of types */
189  if (0 >= dig__fread_port_I(&(ci->n_types), 1, fp))
190  return (-1);
191 
192  /* Types */
193  for (t = 0; t < ci->n_types; t++) {
194  int rtype;
195 
196  /* type */
197  if (0 >= dig__fread_port_I(&rtype, 1, fp))
198  return (-1);
199  ci->type[t][0] = dig_type_from_store(rtype);
200 
201  /* number of items */
202  if (0 >= dig__fread_port_I(&(ci->type[t][1]), 1, fp))
203  return (-1);
204  }
205 
206  /* Offset */
207  if (0 >= dig__fread_port_L(&(ci->offset), 1, fp))
208  return (0);
209  }
210 
211  if (dig_fseek(fp, plus->cidx_head_size, SEEK_SET) == -1)
212  return (-1);
213 
214  return (0);
215 }
216 
217 /* Write spatial index */
218 int dig_write_cidx(GVFILE * fp, struct Plus_head *plus)
219 {
220  int i;
221 
222  dig_set_cur_port(&(plus->cidx_port));
223  dig_rewind(fp);
224 
225  dig_write_cidx_head(fp, plus);
226 
227  /* Write category-type-id for each field */
228  for (i = 0; i < plus->n_cidx; i++) {
229  int j;
230  struct Cat_index *ci;
231 
232  ci = &(plus->cidx[i]);
233  ci->offset = dig_ftell(fp);
234 
235  /* convert type */
236  for (j = 0; j < ci->n_cats; j++)
237  ci->cat[j][1] = dig_type_to_store(ci->cat[j][1]);
238 
239  if (0 >= dig__fwrite_port_I((int *)ci->cat, 3 * ci->n_cats, fp))
240  return (-1);
241 
242  /* Return back */
243  for (j = 0; j < ci->n_cats; j++)
244  ci->cat[j][1] = dig_type_from_store(ci->cat[j][1]);
245  }
246 
247  dig_write_cidx_head(fp, plus); /* rewrite with offsets */
248 
249  return 0;
250 }
251 
252 /* Read spatial index file
253  * returns 0 - OK
254  * 1 - error
255  */
256 int dig_read_cidx(GVFILE * fp, struct Plus_head *plus, int head_only)
257 {
258  int i;
259 
260  G_debug(3, "dig_read_cidx()");
261 
262  dig_cidx_init(plus);
263 
264  dig_rewind(fp);
265  if (dig_read_cidx_head(fp, plus) == -1) {
266  G_debug(3, "Cannot read cidx head");
267  return 1;
268  }
269 
270  if (head_only) {
271  plus->cidx_up_to_date = 1; /* OK ? */
272  return 0;
273  }
274 
275  dig_set_cur_port(&(plus->cidx_port));
276 
277  /* Read category-type-id for each field */
278  for (i = 0; i < plus->n_cidx; i++) {
279  int j;
280  struct Cat_index *ci;
281 
282  ci = &(plus->cidx[i]);
283  ci->a_cats = ci->n_cats;
284  ci->cat = G_malloc(ci->a_cats * 3 * sizeof(int));
285 
286  if (dig_fseek(fp, ci->offset, 0) == -1)
287  return 1;
288 
289  if (0 >= dig__fread_port_I((int *)ci->cat, 3 * ci->n_cats, fp))
290  return 1;
291 
292  /* convert type */
293  for (j = 0; j < ci->n_cats; j++)
294  ci->cat[j][1] = dig_type_from_store(ci->cat[j][1]);
295  }
296 
297 
298  plus->cidx_up_to_date = 1;
299 
300  return 0;
301 }
int dig_set_cur_port(struct Port_info *port)
Definition: portable.c:640
void dig_init_portable(struct Port_info *port, int byte_order)
Definition: portable.c:568
int dig__fread_port_L(long *buf, int cnt, GVFILE *fp)
Definition: portable.c:137
int dig__fwrite_port_I(int *buf, int cnt, GVFILE *fp)
Definition: portable.c:465
int dig_fseek(GVFILE *file, long offset, int whence)
Set GVFILE position.
Definition: file.c:60
int dig_write_cidx_head(GVFILE *fp, struct Plus_head *plus)
Definition: cindex_rw.c:23
int dig_read_cidx_head(GVFILE *fp, struct Plus_head *plus)
Definition: cindex_rw.c:104
int dig__fwrite_port_L(long *buf, int cnt, GVFILE *fp)
Definition: portable.c:422
int dig_type_from_store(int stype)
Convert type from store type.
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
int dig_cidx_init(struct Plus_head *Plus)
Definition: diglib/cindex.c:29
int dig_read_cidx(GVFILE *fp, struct Plus_head *plus, int head_only)
Definition: cindex_rw.c:256
int dig__fread_port_C(char *buf, int cnt, GVFILE *fp)
Definition: portable.c:347
return NULL
Definition: dbfopen.c:1394
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int dig_type_to_store(int type)
Convert type to store type.
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
void dig_rewind(GVFILE *file)
Rewind GVFILE position.
Definition: file.c:85
int dig_write_cidx(GVFILE *fp, struct Plus_head *plus)
Definition: cindex_rw.c:218
int dig__fwrite_port_C(char *buf, int cnt, GVFILE *fp)
Definition: portable.c:558
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
long dig_ftell(GVFILE *file)
Get GVFILE position.
Definition: file.c:36
int dig__fread_port_I(int *buf, int cnt, GVFILE *fp)
Definition: portable.c:207