1 
2 /**
3  * \file plus.c
4  *
5  * \brief Vector library - update topo structure (lower level functions)
6  *
7  * Lower level functions for reading/writing/manipulating vectors.
8  *
9  * This program is free software under the GNU General Public License
10  * (>=v2). Read the file COPYING that comes with GRASS for details.
11  *
12  * \author CERL (probably Dave Gerdes), Radim Blazek
13  *
14  * \date 2001-2006
15  */
16 
17 #include <sys/types.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <grass/vector.h>
22 #include <grass/glocale.h>
23 
24 /*!
25  * \brief Initialize Plus_head structure
26  *
27  * \param[in,out] Plus pointer to Plus_head structure
28  *
29  * \return 1
30  */
dig_init_plus(struct Plus_head * Plus)31 int dig_init_plus(struct Plus_head *Plus)
32 {
33 
34     G_debug(3, "dig_init_plus()");
35 
36     G_zero(Plus, sizeof(struct Plus_head));
37 
38     Plus->built = GV_BUILD_NONE;
39 
40     dig_spidx_init(Plus);
41     dig_cidx_init(Plus);
42 
43     return 1;
44 }
45 
46 /*!
47  * \brief Free Plus->Node structure
48  *
49  * \param[in] Plus pointer to Plus_head structure
50  */
dig_free_plus_nodes(struct Plus_head * Plus)51 void dig_free_plus_nodes(struct Plus_head *Plus)
52 {
53     int i;
54     struct P_node *Node;
55 
56     G_debug(2, "dig_free_plus_nodes()");
57 
58     /* Nodes */
59     if (Plus->Node) {		/* it may be that header only is loaded */
60 	for (i = 1; i <= Plus->n_nodes; i++) {
61 	    Node = Plus->Node[i];
62 	    if (Node == NULL)
63 		continue;
64 
65 	    dig_free_node(Node);
66 	}
67 	G_free(Plus->Node);
68     }
69     Plus->Node = NULL;
70     Plus->n_nodes = 0;
71     Plus->alloc_nodes = 0;
72 }
73 
74 /*!
75  * \brief Free Plus->Line structure
76  *
77  * \param[in] Plus pointer to Plus_head structure
78  */
dig_free_plus_lines(struct Plus_head * Plus)79 void dig_free_plus_lines(struct Plus_head *Plus)
80 {
81     int i;
82     struct P_line *Line;
83 
84     G_debug(2, "dig_free_plus_lines()");
85 
86     /* Lines */
87     if (Plus->Line) {		/* it may be that header only is loaded */
88 	for (i = 1; i <= Plus->n_lines; i++) {
89 	    Line = Plus->Line[i];
90 	    if (Line == NULL)
91 		continue;
92 
93 	    dig_free_line(Line);
94 	}
95 	G_free(Plus->Line);
96     }
97 
98     Plus->Line = NULL;
99     Plus->n_lines = 0;
100     Plus->alloc_lines = 0;
101 
102     Plus->n_plines = 0;
103     Plus->n_llines = 0;
104     Plus->n_blines = 0;
105     Plus->n_clines = 0;
106     Plus->n_flines = 0;
107     Plus->n_klines = 0;
108 }
109 
110 /*!
111  * \brief Free Plus->Area structure
112  *
113  * \param[in] Plus pointer to Plus_head structure
114  */
dig_free_plus_areas(struct Plus_head * Plus)115 void dig_free_plus_areas(struct Plus_head *Plus)
116 {
117     int i;
118     struct P_area *Area;
119 
120     G_debug(2, "dig_free_plus_areas()");
121 
122     /* Areas */
123     if (Plus->Area) {		/* it may be that header only is loaded */
124 	for (i = 1; i <= Plus->n_areas; i++) {
125 	    Area = Plus->Area[i];
126 	    if (Area == NULL)
127 		continue;
128 
129 	    dig_free_area(Area);
130 	}
131 	G_free(Plus->Area);
132     }
133     Plus->Area = NULL;
134     Plus->n_areas = 0;
135     Plus->alloc_areas = 0;
136 }
137 
138 /*!
139  * \brief Free Plus->Isle structure
140  *
141  * \param[in] Plus pointer to Plus_head structure
142  */
dig_free_plus_isles(struct Plus_head * Plus)143 void dig_free_plus_isles(struct Plus_head *Plus)
144 {
145     int i;
146     struct P_isle *Isle;
147 
148     G_debug(2, "dig_free_plus_isles()");
149 
150     /* Isles */
151     if (Plus->Isle) {		/* it may be that header only is loaded */
152 	for (i = 1; i <= Plus->n_isles; i++) {
153 	    Isle = Plus->Isle[i];
154 	    if (Isle == NULL)
155 		continue;
156 
157 	    dig_free_isle(Isle);
158 	}
159 	G_free(Plus->Isle);
160     }
161 
162     Plus->Isle = NULL;
163     Plus->n_isles = 0;
164     Plus->alloc_isles = 0;
165 }
166 
167 /*!
168  * \brief Free Plus structure.
169  *
170  * Structure is not inited and dig_init_plus() should follow.
171  *
172  * \param[in] Plus pointer to Plus_head structure
173  */
dig_free_plus(struct Plus_head * Plus)174 void dig_free_plus(struct Plus_head *Plus)
175 {
176     G_debug(2, "dig_free_plus()");
177     dig_free_plus_nodes(Plus);
178     dig_free_plus_lines(Plus);
179     dig_free_plus_areas(Plus);
180     dig_free_plus_isles(Plus);
181 
182     dig_spidx_free(Plus);
183     dig_cidx_free(Plus);
184 }
185 
186 /*!
187  * \brief Reads topo file to topo structure.
188  *
189  * \param[in,out] Plus pointer to Plus_head structure
190  * \param[in] plus topo file
191  * \param[in] head_only read only head
192  *
193  * \return 1 on success
194  * \return 0 on error
195  */
dig_load_plus(struct Plus_head * Plus,struct gvfile * plus,int head_only)196 int dig_load_plus(struct Plus_head *Plus, struct gvfile * plus, int head_only)
197 {
198     int i;
199 
200     G_debug(1, "dig_load_plus()");
201     /* TODO
202        if (do_checks)
203        dig_do_file_checks (map, map->plus_file, map->digit_file);
204      */
205 
206     /* free and init old */
207     dig_free_plus(Plus);
208     dig_init_plus(Plus);
209 
210     /* Now let's begin reading the Plus file nodes, lines, areas and isles */
211 
212     if (dig_Rd_Plus_head(plus, Plus) == -1)
213 	return 0;
214 
215     if (head_only)
216 	return 1;
217 
218     dig_set_cur_port(&(Plus->port));
219 
220     /* Nodes */
221     if (dig_fseek(plus, Plus->Node_offset, 0) == -1)
222 	G_fatal_error(_("Unable read topology for nodes"));
223 
224     dig_alloc_nodes(Plus, Plus->n_nodes);
225     for (i = 1; i <= Plus->n_nodes; i++) {
226 	if (dig_Rd_P_node(Plus, i, plus) == -1)
227 	    G_fatal_error(_("Unable to read topology for node %d"), i);
228     }
229 
230     /* Lines */
231     if (dig_fseek(plus, Plus->Line_offset, 0) == -1)
232 	G_fatal_error(_("Unable read topology for lines"));
233 
234     dig_alloc_lines(Plus, Plus->n_lines);
235     for (i = 1; i <= Plus->n_lines; i++) {
236 	if (dig_Rd_P_line(Plus, i, plus) == -1)
237 	    G_fatal_error(_("Unable to read topology for line %d"), i);
238     }
239 
240     /* Areas */
241     if (dig_fseek(plus, Plus->Area_offset, 0) == -1)
242 	G_fatal_error(_("Unable to read topo for areas"));
243 
244     dig_alloc_areas(Plus, Plus->n_areas);
245     for (i = 1; i <= Plus->n_areas; i++) {
246 	if (dig_Rd_P_area(Plus, i, plus) == -1)
247 	    G_fatal_error(_("Unable read topology for area %d"), i);
248     }
249 
250     /* Isles */
251     if (dig_fseek(plus, Plus->Isle_offset, 0) == -1)
252 	G_fatal_error(_("Unable to read topology for isles"));
253 
254     dig_alloc_isles(Plus, Plus->n_isles);
255     for (i = 1; i <= Plus->n_isles; i++) {
256 	if (dig_Rd_P_isle(Plus, i, plus) == -1)
257 	    G_fatal_error(_("Unable to read topology for isle %d"), i);
258     }
259 
260     return (1);
261 }
262 
263 /*!
264  * \brief Writes topo structure to topo file
265  *
266  * \param[in,out] fp_plus topo file
267  * \param[in] Plus pointer to Plus_head structure
268  *
269  * \return 0 on success
270  * \return -1 on error
271  */
dig_write_plus_file(struct gvfile * fp_plus,struct Plus_head * Plus)272 int dig_write_plus_file(struct gvfile * fp_plus, struct Plus_head *Plus)
273 {
274 
275     dig_set_cur_port(&(Plus->port));
276     dig_rewind(fp_plus);
277 
278     if (dig_Wr_Plus_head(fp_plus, Plus) < 0) {
279 	G_warning(_("Unable to write head to plus file"));
280 	return (-1);
281     }
282 
283     if (dig_write_nodes(fp_plus, Plus) < 0) {
284 	G_warning(_("Unable to write nodes to plus file"));
285 	return (-1);
286     }
287 
288     if (dig_write_lines(fp_plus, Plus) < 0) {
289 	G_warning(_("Unable to write lines to plus file"));
290 	return (-1);
291     }
292 
293     if (dig_write_areas(fp_plus, Plus) < 0) {
294 	G_warning(_("Unable to write areas to plus file"));
295 	return (-1);
296     }
297 
298     if (dig_write_isles(fp_plus, Plus) < 0) {
299 	G_warning(_("Unable to write isles to plus file"));
300 	return (-1);
301     }
302 
303     dig_rewind(fp_plus);
304     if (dig_Wr_Plus_head(fp_plus, Plus) < 0) {
305 	G_warning(_("Unable to write head to plus file"));
306 	return (-1);
307     }
308 
309     dig_fflush(fp_plus);
310     return (0);
311 }				/*  write_plus_file()  */
312 
313 /*!
314  * \brief Writes topo structure (nodes) to topo file
315  *
316  * \param[in,out] plus topo file
317  * \param[in] Plus pointer to Plus_head structure
318  *
319  * \return 0 on success
320  * \return -1 on error
321  */
dig_write_nodes(struct gvfile * plus,struct Plus_head * Plus)322 int dig_write_nodes(struct gvfile * plus, struct Plus_head *Plus)
323 {
324     int i;
325 
326 
327     Plus->Node_offset = dig_ftell(plus);
328 
329     for (i = 1; i <= Plus->n_nodes; i++) {
330 	if (dig_Wr_P_node(Plus, i, plus) < 0)
331 	    return (-1);
332     }
333 
334     return (0);
335 }				/*  write_nodes()  */
336 
337 /*!
338  * \brief Writes topo structure (lines) to topo file
339  *
340  * \param[in,out] plus topo file
341  * \param[in] Plus pointer to Plus_head structure
342  *
343  * \return 0 on success
344  * \return -1 on error
345  */
dig_write_lines(struct gvfile * plus,struct Plus_head * Plus)346 int dig_write_lines(struct gvfile * plus, struct Plus_head *Plus)
347 {
348     int i;
349 
350 
351     Plus->Line_offset = dig_ftell(plus);
352 
353     for (i = 1; i <= Plus->n_lines; i++) {
354 	if (dig_Wr_P_line(Plus, i, plus) < 0)
355 	    return (-1);
356     }
357 
358     return (0);
359 
360 }				/*  write_line()  */
361 
362 /*!
363  * \brief Writes topo structure (areas) to topo file
364  *
365  * \param[in,out] plus topo file
366  * \param[in] Plus pointer to Plus_head structure
367  *
368  * \return 0 on success
369  * \return -1 on error
370  */
dig_write_areas(struct gvfile * plus,struct Plus_head * Plus)371 int dig_write_areas(struct gvfile * plus, struct Plus_head *Plus)
372 {
373     int i;
374 
375 
376     Plus->Area_offset = dig_ftell(plus);
377 
378     for (i = 1; i <= Plus->n_areas; i++) {
379 	if (dig_Wr_P_area(Plus, i, plus) < 0)
380 	    return (-1);
381     }
382 
383     return (0);
384 
385 }				/*  write_areas()  */
386 
387 /*!
388  * \brief Writes topo structure (isles) to topo file
389  *
390  * \param[in,out] plus topo file
391  * \param[in] Plus pointer to Plus_head structure
392  *
393  * \return 0 on success
394  * \return -1 on error
395  */
dig_write_isles(struct gvfile * plus,struct Plus_head * Plus)396 int dig_write_isles(struct gvfile * plus, struct Plus_head *Plus)
397 {
398     int i;
399 
400 
401     Plus->Isle_offset = dig_ftell(plus);
402 
403     for (i = 1; i <= Plus->n_isles; i++) {
404 	if (dig_Wr_P_isle(Plus, i, plus) < 0)
405 	    return (-1);
406     }
407 
408     return (0);
409 
410 }				/*  write_isles()  */
411