GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
cindex_rw.c
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * MODULE: Vector library
4 *
5 * AUTHOR(S): Radim Blazek.
6 *
7 * PURPOSE: Lower level functions for reading/writing/manipulating vectors.
8 *
9 * COPYRIGHT: (C) 2001 by the GRASS Development Team
10 *
11 * This program is free software under the GNU General Public
12 * License (>=v2). Read the file COPYING that comes with
13 * GRASS for details.
14 *
15 *****************************************************************************/
16
17#include <inttypes.h>
18#include <stdlib.h>
19#include <sys/types.h>
20#include <string.h>
21#include <grass/vector.h>
22#include <grass/glocale.h>
23#include <grass/version.h>
24
25int dig_write_cidx_head(struct gvfile *fp, struct Plus_head *plus)
26{
27 int i;
28 unsigned char buf[5];
29 long length = 9;
30
31 G_debug(3, "dig_write_cidx_head()");
32
33 dig_rewind(fp);
35
36 /* Head of header */
37 /* bytes 1 - 5 */
38 buf[0] = GV_CIDX_VER_MAJOR;
39 buf[1] = GV_CIDX_VER_MINOR;
42 buf[4] = plus->cidx_port.byte_order;
43 if (0 >= dig__fwrite_port_C((const char *)buf, 5, fp))
44 return (-1);
45
46 /* get required offset size */
47 if (plus->off_t_size == 0) {
48 /* should not happen, topo is written first */
49 if (plus->coor_size > (off_t)PORT_LONG_MAX)
50 plus->off_t_size = 8;
51 else
52 plus->off_t_size = 4;
53 }
54
55 /* bytes 6 - 9 : header size */
56 if (0 >= dig__fwrite_port_L(&length, 1, fp))
57 return (0);
58
59 /* Body of header - info about all fields */
60 /* Number of fields */
61 if (0 >= dig__fwrite_port_I(&(plus->n_cidx), 1, fp))
62 return (-1);
63
64 for (i = 0; i < plus->n_cidx; i++) {
65 int t;
66 struct Cat_index *ci;
67
68 ci = &(plus->cidx[i]);
69
70 G_debug(3, "cidx %d head offset: %" PRId64, i, dig_ftell(fp));
71
72 /* Field number */
73 if (0 >= dig__fwrite_port_I(&(ci->field), 1, fp))
74 return (-1);
75
76 /* Number of categories */
77 if (0 >= dig__fwrite_port_I(&(ci->n_cats), 1, fp))
78 return (-1);
79
80 /* Number of unique categories */
81 if (0 >= dig__fwrite_port_I(&(ci->n_ucats), 1, fp))
82 return (-1);
83
84 /* Number of types */
85 if (0 >= dig__fwrite_port_I(&(ci->n_types), 1, fp))
86 return (-1);
87
88 /* Types */
89 for (t = 0; t < ci->n_types; t++) {
90 int wtype;
91
92 /* type */
93 wtype = dig_type_to_store(ci->type[t][0]);
94 if (0 >= dig__fwrite_port_I(&wtype, 1, fp))
95 return (-1);
96
97 /* number of items */
98 if (0 >= dig__fwrite_port_I(&(ci->type[t][1]), 1, fp))
99 return (-1);
100 }
101
102 /* Offset */
103 if (0 >= dig__fwrite_port_O(&(ci->offset), 1, fp, plus->off_t_size))
104 return (0);
105 G_debug(3, "cidx %d offset: %" PRId64, i, ci->offset);
106 }
107
108 G_debug(3, "cidx body offset %" PRId64, dig_ftell(fp));
109
110 return (0);
111}
112
113/*!
114 \brief Read header of cidx file
115
116 \param fp pointer to gvfile structure
117 \param plus pointer to Plus_head structure
118
119 \return 0 OK
120 \return -1 error
121 */
122int dig_read_cidx_head(struct gvfile *fp, struct Plus_head *plus)
123{
124 unsigned char buf[5];
125 int i, byte_order;
126
127 dig_rewind(fp);
128
129 /* bytes 1 - 5 */
130 if (0 >= dig__fread_port_C((char *)buf, 5, fp))
131 return (-1);
132 plus->version.cidx.major = buf[0];
133 plus->version.cidx.minor = buf[1];
134 plus->version.cidx.back_major = buf[2];
135 plus->version.cidx.back_minor = buf[3];
136 byte_order = buf[4];
137
138 G_debug(
139 3,
140 "Cidx header: file version %d.%d , supported from GRASS version %d.%d",
141 plus->version.cidx.major, plus->version.cidx.minor,
142 plus->version.cidx.back_major, plus->version.cidx.back_minor);
143
144 G_debug(3, " byte order %d", byte_order);
145
146 /* check version numbers */
147 if (plus->version.cidx.major > GV_CIDX_VER_MAJOR ||
148 plus->version.cidx.minor > GV_CIDX_VER_MINOR) {
149 /* The file was created by GRASS library with higher version than this
150 * one */
151
152 if (plus->version.cidx.back_major > GV_CIDX_VER_MAJOR ||
153 plus->version.cidx.back_minor > GV_CIDX_VER_MINOR) {
154 /* This version of GRASS lib is lower than the oldest which can read
155 * this format */
156 G_debug(1, "Category index format version %d.%d",
157 plus->version.cidx.major, plus->version.cidx.minor);
158 G_fatal_error(_("This version of GRASS (%d.%d) is too old to read "
159 "this category index format."
160 " Try to rebuild topology or upgrade GRASS to at "
161 "least version %d."),
164 return (-1);
165 }
166
167 G_warning("Your GRASS version does not fully support category index "
168 "format %d.%d of the vector."
169 " Consider to rebuild topology or upgrade GRASS.",
170 plus->version.cidx.major, plus->version.cidx.minor);
171 }
172
173 dig_init_portable(&(plus->cidx_port), byte_order);
174 dig_set_cur_port(&(plus->cidx_port));
175
176 /* bytes 6 - 9 : header size */
177 if (0 >= dig__fread_port_L(&(plus->cidx_head_size), 1, fp))
178 return (-1);
179 G_debug(3, " header size %ld", plus->cidx_head_size);
180
181 /* get required offset size */
182 if (plus->off_t_size == 0) {
183 /* should not happen, topo is opened first */
184 if (plus->coor_size > (off_t)PORT_LONG_MAX)
185 plus->off_t_size = 8;
186 else
187 plus->off_t_size = 4;
188 }
189
190 /* Body of header - info about all fields */
191 /* Number of fields */
192 if (0 >= dig__fread_port_I(&(plus->n_cidx), 1, fp))
193 return (-1);
194
195 /* alloc space */
196 if (plus->a_cidx < plus->n_cidx) {
197 plus->a_cidx = plus->n_cidx;
198 plus->cidx = (struct Cat_index *)G_realloc(
199 plus->cidx, plus->a_cidx * sizeof(struct Cat_index));
200 }
201
202 for (i = 0; i < plus->n_cidx; i++) {
203 int t;
204 struct Cat_index *ci;
205
206 ci = &(plus->cidx[i]);
207 ci->cat = NULL;
208 ci->a_cats = 0;
209
210 /* Field number */
211 if (0 >= dig__fread_port_I(&(ci->field), 1, fp))
212 return (-1);
213
214 /* Number of categories */
215 if (0 >= dig__fread_port_I(&(ci->n_cats), 1, fp))
216 return (-1);
217
218 /* Number of unique categories */
219 if (0 >= dig__fread_port_I(&(ci->n_ucats), 1, fp))
220 return (-1);
221
222 /* Number of types */
223 if (0 >= dig__fread_port_I(&(ci->n_types), 1, fp))
224 return (-1);
225
226 /* Types */
227 for (t = 0; t < ci->n_types; t++) {
228 int rtype;
229
230 /* type */
231 if (0 >= dig__fread_port_I(&rtype, 1, fp))
232 return (-1);
233 ci->type[t][0] = dig_type_from_store(rtype);
234
235 /* number of items */
236 if (0 >= dig__fread_port_I(&(ci->type[t][1]), 1, fp))
237 return (-1);
238 }
239
240 /* Offset */
241 if (0 >= dig__fread_port_O(&(ci->offset), 1, fp, plus->off_t_size))
242 return (0);
243 }
244
245 if (dig_fseek(fp, plus->cidx_head_size, SEEK_SET) == -1)
246 return (-1);
247
248 return (0);
249}
250
251/* Write spatial index */
252int dig_write_cidx(struct gvfile *fp, struct Plus_head *plus)
253{
254 int i;
255
256 dig_set_cur_port(&(plus->cidx_port));
257 dig_rewind(fp);
258
259 dig_write_cidx_head(fp, plus);
260
261 /* Write category-type-id for each field */
262 for (i = 0; i < plus->n_cidx; i++) {
263 int j;
264 struct Cat_index *ci;
265
266 ci = &(plus->cidx[i]);
267 ci->offset = dig_ftell(fp);
268
269 /* convert type */
270 for (j = 0; j < ci->n_cats; j++)
271 ci->cat[j][1] = dig_type_to_store(ci->cat[j][1]);
272
273 if (0 >= dig__fwrite_port_I((int *)ci->cat, 3 * ci->n_cats, fp))
274 return (-1);
275
276 /* Return back */
277 for (j = 0; j < ci->n_cats; j++)
278 ci->cat[j][1] = dig_type_from_store(ci->cat[j][1]);
279 }
280
281 dig_write_cidx_head(fp, plus); /* rewrite with offsets */
282
283 return 0;
284}
285
286/*!
287 \brief Read spatial index file
288
289 \param fp pointer to gvfile structure
290 \param[in,out] plus pointer to Plus_head structure
291 \param head_only non-zero to read only head
292
293 \return 0 OK
294 \return 1 error
295 */
296int dig_read_cidx(struct gvfile *fp, struct Plus_head *plus, int head_only)
297{
298 int i;
299
300 G_debug(3, "dig_read_cidx()");
301
302 dig_cidx_free(plus);
303 dig_cidx_init(plus);
304
305 dig_rewind(fp);
306 if (dig_read_cidx_head(fp, plus) == -1) {
307 G_debug(3, "Cannot read cidx head");
308 return 1;
309 }
310
311 if (head_only) {
312 plus->cidx_up_to_date = 1; /* OK ? */
313 return 0;
314 }
315
316 dig_set_cur_port(&(plus->cidx_port));
317
318 /* Read category-type-id for each field */
319 for (i = 0; i < plus->n_cidx; i++) {
320 int j;
321 struct Cat_index *ci;
322
323 ci = &(plus->cidx[i]);
324 ci->a_cats = ci->n_cats;
325 ci->cat = G_malloc(ci->a_cats * 3 * sizeof(int));
326
327 if (dig_fseek(fp, ci->offset, 0) == -1)
328 return 1;
329
330 if (0 >= dig__fread_port_I((int *)ci->cat, 3 * ci->n_cats, fp))
331 return 1;
332
333 /* convert type */
334 for (j = 0; j < ci->n_cats; j++)
335 ci->cat[j][1] = dig_type_from_store(ci->cat[j][1]);
336 }
337
338 plus->cidx_up_to_date = 1;
339
340 return 0;
341}
#define NULL
Definition ccmath.h:32
int dig_write_cidx(struct gvfile *fp, struct Plus_head *plus)
Definition cindex_rw.c:252
int dig_read_cidx(struct gvfile *fp, struct Plus_head *plus, int head_only)
Read spatial index file.
Definition cindex_rw.c:296
int dig_write_cidx_head(struct gvfile *fp, struct Plus_head *plus)
Definition cindex_rw.c:25
int dig_read_cidx_head(struct gvfile *fp, struct Plus_head *plus)
Read header of cidx file.
Definition cindex_rw.c:122
#define G_realloc(p, n)
Definition defs/gis.h:141
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
#define G_malloc(n)
Definition defs/gis.h:139
int G_debug(int, const char *,...) __attribute__((format(printf
#define GV_CIDX_VER_MINOR
#define PORT_LONG_MAX
Definition dig_defines.h:70
#define GV_CIDX_EARLIEST_MINOR
#define GV_CIDX_EARLIEST_MAJOR
#define GV_CIDX_VER_MAJOR
int dig__fread_port_O(off_t *, size_t, struct gvfile *, size_t)
Read off_ts from the Portable Vector Format.
Definition portable.c:167
int dig__fwrite_port_C(const char *, size_t, struct gvfile *)
Write chars to the Portable Vector Format.
Definition portable.c:886
void dig_init_portable(struct Port_info *, int)
Set Port_info structure to byte order of file.
Definition portable.c:900
int dig__fread_port_L(long *, size_t, struct gvfile *)
Read longs from the Portable Vector Format.
Definition portable.c:262
int dig__fwrite_port_L(const long *, size_t, struct gvfile *)
Write longs to the Portable Vector Format.
Definition portable.c:703
int dig__fwrite_port_I(const int *, size_t, struct gvfile *)
Write integers to the Portable Vector Format.
Definition portable.c:758
off_t dig_ftell(struct gvfile *file)
Get struct gvfile position.
Definition file.c:36
int dig_set_cur_port(struct Port_info *)
Set current Port_info structure.
Definition portable.c:996
void dig_cidx_free(struct Plus_head *)
void dig_rewind(struct gvfile *file)
Rewind file position.
Definition file.c:87
int dig__fread_port_C(char *, size_t, struct gvfile *)
Read chars from the Portable Vector Format.
Definition portable.c:511
int dig_cidx_init(struct Plus_head *)
Initialize Plus_head structure (cidx)
int dig__fread_port_I(int *, size_t, struct gvfile *)
Read integers from the Portable Vector Format.
Definition portable.c:345
int dig_fseek(struct gvfile *file, off_t offset, int whence)
Set struct gvfile position.
Definition file.c:60
int dig_type_from_store(int)
Convert type from store type.
int dig__fwrite_port_O(const off_t *, size_t, struct gvfile *, size_t)
Write off_ts to the Portable Vector Format.
Definition portable.c:636
int dig_type_to_store(int)
Convert type to store type.
#define _(str)
Definition glocale.h:10
double t
Definition r_raster.c:39
Category index.
Basic topology-related info.
int n_cidx
Number of category indexes (one for each field/layer)
struct Port_info cidx_port
Portability information for category index.
off_t coor_size
Size of coor file.
struct Plus_head::@9 version
Backward compatibility version info.
int off_t_size
Offset size.
int a_cidx
Allocated space for category indexes.
int cidx_up_to_date
Category index to be updated.
struct Version_info cidx
Version info for category index file.
long cidx_head_size
Category index header size.
File definition.
Definition dig_structs.h:92
#define GRASS_VERSION_MINOR
Definition version.h:3
#define GRASS_VERSION_MAJOR
Definition version.h:2