GRASS Programmer's Manual  6.4.2(2012)
 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 
22 int dig_write_cidx_head(GVFILE * fp, struct Plus_head *plus)
23 {
24  int i;
25  unsigned char buf[5];
26  long length = 9;
27 
28  G_debug(3, "dig_write_cidx_head()");
29 
30  dig_rewind(fp);
31  dig_set_cur_port(&(plus->cidx_port));
32 
33  /* Head of header */
34  /* bytes 1 - 5 */
35  buf[0] = GV_CIDX_VER_MAJOR;
36  buf[1] = GV_CIDX_VER_MINOR;
37  buf[2] = GV_CIDX_EARLIEST_MAJOR;
38  buf[3] = GV_CIDX_EARLIEST_MINOR;
39  buf[4] = plus->cidx_port.byte_order;
40  if (0 >= dig__fwrite_port_C(buf, 5, fp))
41  return (-1);
42 
43  /* bytes 6 - 9 : header size */
44  if (0 >= dig__fwrite_port_L(&length, 1, fp))
45  return (0);
46 
47  /* Body of header - info about all fields */
48  /* Number of fields */
49  if (0 >= dig__fwrite_port_I(&(plus->n_cidx), 1, fp))
50  return (-1);
51 
52  for (i = 0; i < plus->n_cidx; i++) {
53  int t;
54  struct Cat_index *ci;
55 
56  ci = &(plus->cidx[i]);
57 
58  G_debug(3, "cidx %d head offset: %ld", i, dig_ftell(fp));
59 
60  /* Field number */
61  if (0 >= dig__fwrite_port_I(&(ci->field), 1, fp))
62  return (-1);
63 
64  /* Number of categories */
65  if (0 >= dig__fwrite_port_I(&(ci->n_cats), 1, fp))
66  return (-1);
67 
68  /* Number of unique categories */
69  if (0 >= dig__fwrite_port_I(&(ci->n_ucats), 1, fp))
70  return (-1);
71 
72  /* Number of types */
73  if (0 >= dig__fwrite_port_I(&(ci->n_types), 1, fp))
74  return (-1);
75 
76  /* Types */
77  for (t = 0; t < ci->n_types; t++) {
78  int wtype;
79 
80  /* type */
81  wtype = dig_type_to_store(ci->type[t][0]);
82  if (0 >= dig__fwrite_port_I(&wtype, 1, fp))
83  return (-1);
84 
85  /* number of items */
86  if (0 >= dig__fwrite_port_I(&(ci->type[t][1]), 1, fp))
87  return (-1);
88 
89  }
90 
91  /* Offset */
92  if (0 >= dig__fwrite_port_L(&(ci->offset), 1, fp))
93  return (0);
94  G_debug(3, "cidx %d offset: %ld", i, ci->offset);
95  }
96 
97  G_debug(3, "cidx body offset %ld", dig_ftell(fp));
98 
99  return (0);
100 }
101 
102 /* return: 0 OK, -1 error */
103 int dig_read_cidx_head(GVFILE * fp, struct Plus_head *plus)
104 {
105  unsigned char buf[5];
106  int i, byte_order;
107 
108  dig_rewind(fp);
109 
110  /* bytes 1 - 5 */
111  if (0 >= dig__fread_port_C(buf, 5, fp))
112  return (-1);
113  plus->cidx_Version_Major = buf[0];
114  plus->cidx_Version_Minor = buf[1];
115  plus->cidx_Back_Major = buf[2];
116  plus->cidx_Back_Minor = buf[3];
117  byte_order = buf[4];
118 
119  G_debug(3,
120  "Cidx header: file version %d.%d , supported from GRASS version %d.%d",
121  plus->cidx_Version_Major, plus->cidx_Version_Minor,
122  plus->cidx_Back_Major, plus->cidx_Back_Minor);
123 
124  G_debug(3, " byte order %d", byte_order);
125 
126  /* check version numbers */
127  if (plus->cidx_Version_Major > GV_CIDX_VER_MAJOR ||
128  plus->cidx_Version_Minor > GV_CIDX_VER_MINOR) {
129  /* The file was created by GRASS library with higher version than this one */
130 
131  if (plus->cidx_Back_Major > GV_CIDX_VER_MAJOR ||
132  plus->cidx_Back_Minor > GV_CIDX_VER_MINOR) {
133  /* This version of GRASS lib is lower than the oldest which can read this format */
135  ("Category index format version %d.%d is not supported by this release."
136  " Try to rebuild topology or upgrade GRASS.",
137  plus->cidx_Version_Major, plus->cidx_Version_Minor);
138  return (-1);
139  }
140 
141  G_warning
142  ("Your GRASS version does not fully support category index format %d.%d of the vector."
143  " Consider to rebuild topology or upgrade GRASS.",
144  plus->cidx_Version_Major, plus->cidx_Version_Minor);
145  }
146 
147  dig_init_portable(&(plus->cidx_port), byte_order);
148  dig_set_cur_port(&(plus->cidx_port));
149 
150  /* bytes 6 - 9 : header size */
151  if (0 >= dig__fread_port_L(&(plus->cidx_head_size), 1, fp))
152  return (-1);
153  G_debug(3, " header size %ld", plus->cidx_head_size);
154 
155  /* Body of header - info about all fields */
156  /* Number of fields */
157  if (0 >= dig__fread_port_I(&(plus->n_cidx), 1, fp))
158  return (-1);
159 
160  /* alloc space */
161  plus->a_cidx = plus->n_cidx;
162  plus->cidx =
163  (struct Cat_index *)G_malloc(plus->a_cidx * sizeof(struct Cat_index));
164 
165  for (i = 0; i < plus->n_cidx; i++) {
166  int t;
167  struct Cat_index *ci;
168 
169  ci = &(plus->cidx[i]);
170  ci->cat = NULL;
171  ci->a_cats = 0;
172 
173  /* Field number */
174  if (0 >= dig__fread_port_I(&(ci->field), 1, fp))
175  return (-1);
176 
177  /* Number of categories */
178  if (0 >= dig__fread_port_I(&(ci->n_cats), 1, fp))
179  return (-1);
180 
181  /* Number of unique categories */
182  if (0 >= dig__fread_port_I(&(ci->n_ucats), 1, fp))
183  return (-1);
184 
185  /* Number of types */
186  if (0 >= dig__fread_port_I(&(ci->n_types), 1, fp))
187  return (-1);
188 
189  /* Types */
190  for (t = 0; t < ci->n_types; t++) {
191  int rtype;
192 
193  /* type */
194  if (0 >= dig__fread_port_I(&rtype, 1, fp))
195  return (-1);
196  ci->type[t][0] = dig_type_from_store(rtype);
197 
198  /* number of items */
199  if (0 >= dig__fread_port_I(&(ci->type[t][1]), 1, fp))
200  return (-1);
201  }
202 
203  /* Offset */
204  if (0 >= dig__fread_port_L(&(ci->offset), 1, fp))
205  return (0);
206  }
207 
208  if (dig_fseek(fp, plus->cidx_head_size, SEEK_SET) == -1)
209  return (-1);
210 
211  return (0);
212 }
213 
214 /* Write spatial index */
215 int dig_write_cidx(GVFILE * fp, struct Plus_head *plus)
216 {
217  int i;
218 
219  dig_set_cur_port(&(plus->cidx_port));
220  dig_rewind(fp);
221 
222  dig_write_cidx_head(fp, plus);
223 
224  /* Write category-type-id for each field */
225  for (i = 0; i < plus->n_cidx; i++) {
226  int j;
227  struct Cat_index *ci;
228 
229  ci = &(plus->cidx[i]);
230  ci->offset = dig_ftell(fp);
231 
232  /* convert type */
233  for (j = 0; j < ci->n_cats; j++)
234  ci->cat[j][1] = dig_type_to_store(ci->cat[j][1]);
235 
236  if (0 >= dig__fwrite_port_I((int *)ci->cat, 3 * ci->n_cats, fp))
237  return (-1);
238 
239  /* Return back */
240  for (j = 0; j < ci->n_cats; j++)
241  ci->cat[j][1] = dig_type_from_store(ci->cat[j][1]);
242  }
243 
244  dig_write_cidx_head(fp, plus); /* rewrite with offsets */
245 
246  return 0;
247 }
248 
249 /* Read spatial index file
250  * returns 0 - OK
251  * 1 - error
252  */
253 int dig_read_cidx(GVFILE * fp, struct Plus_head *plus, int head_only)
254 {
255  int i;
256 
257  G_debug(3, "dig_read_cidx()");
258 
259  dig_cidx_init(plus);
260 
261  dig_rewind(fp);
262  if (dig_read_cidx_head(fp, plus) == -1) {
263  G_debug(3, "Cannot read cidx head");
264  return 1;
265  }
266 
267  if (head_only) {
268  plus->cidx_up_to_date = 1; /* OK ? */
269  return 0;
270  }
271 
272  dig_set_cur_port(&(plus->cidx_port));
273 
274  /* Read category-type-id for each field */
275  for (i = 0; i < plus->n_cidx; i++) {
276  int j;
277  struct Cat_index *ci;
278 
279  ci = &(plus->cidx[i]);
280  ci->a_cats = ci->n_cats;
281  ci->cat = G_malloc(ci->a_cats * 3 * sizeof(int));
282 
283  if (dig_fseek(fp, ci->offset, 0) == -1)
284  return 1;
285 
286  if (0 >= dig__fread_port_I((int *)ci->cat, 3 * ci->n_cats, fp))
287  return 1;
288 
289  /* convert type */
290  for (j = 0; j < ci->n_cats; j++)
291  ci->cat[j][1] = dig_type_from_store(ci->cat[j][1]);
292  }
293 
294 
295  plus->cidx_up_to_date = 1;
296 
297  return 0;
298 }