[GRASS-SVN] r63404 - grass/trunk/lib/vector/Vlib
svn_grass at osgeo.org
svn_grass at osgeo.org
Sat Dec 6 14:27:03 PST 2014
Author: mmetz
Date: 2014-12-06 14:27:03 -0800 (Sat, 06 Dec 2014)
New Revision: 63404
Modified:
grass/trunk/lib/vector/Vlib/write_nat.c
Log:
Vlib write_nat.c: fix memory leak, fix compiler warnings, avoid redundant seek and read operations, implement V2_rewrite_line_nat()
Modified: grass/trunk/lib/vector/Vlib/write_nat.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_nat.c 2014-12-06 18:57:32 UTC (rev 63403)
+++ grass/trunk/lib/vector/Vlib/write_nat.c 2014-12-06 22:27:03 UTC (rev 63404)
@@ -24,10 +24,7 @@
#include "local_proto.h"
-static struct line_cats *Cats;
-static struct line_pnts *Points;
-
-static off_t V1__rewrite_line_nat(struct Map_info *, off_t, int,
+static off_t V1__write_line_nat(struct Map_info *, off_t, int,
const struct line_pnts *, const struct line_cats *);
static void V2__delete_area_cats_from_cidx_nat(struct Map_info *, int);
static void V2__add_area_cats_to_cidx_nat(struct Map_info *, int);
@@ -46,17 +43,7 @@
off_t V1_write_line_nat(struct Map_info *Map, int type,
const struct line_pnts *points, const struct line_cats *cats)
{
- off_t offset;
-
- if (dig_fseek(&(Map->dig_fp), 0L, SEEK_END) == -1) /* set to end of file */
- return -1;
-
- offset = dig_ftell(&(Map->dig_fp));
- G_debug(3, "V1_write_line_nat(): offset = %lu", offset);
- if (offset == -1)
- return -1;
-
- return V1__rewrite_line_nat(Map, offset, type, points, cats);
+ return V1__write_line_nat(Map, -1, type, points, cats);
}
/*!
@@ -113,18 +100,17 @@
const struct line_pnts *points, const struct line_cats *cats)
{
int old_type;
- struct line_pnts *old_points;
- struct line_cats *old_cats;
- off_t new_offset;
+ static struct line_pnts *old_points = NULL;
+ static struct line_cats *old_cats = NULL;
G_debug(3, "V1_rewrite_line_nat(): line = %d offset = %lu",
line, (unsigned long) offset);
- /* TODO: enable points and cats == NULL */
-
/* First compare numbers of points and cats with tha old one */
- old_points = Vect_new_line_struct();
- old_cats = Vect_new_cats_struct();
+ if (!old_points) {
+ old_points = Vect_new_line_struct();
+ old_cats = Vect_new_cats_struct();
+ }
old_type = V1_read_line_nat(Map, old_points, old_cats, offset);
if (old_type == -1)
@@ -137,22 +123,14 @@
|| ((type & GV_LINES) && (old_type & GV_LINES)))) {
/* equal -> overwrite the old */
- return V1__rewrite_line_nat(Map, offset, type, points, cats);
+ return V1__write_line_nat(Map, offset, type, points, cats);
}
else {
/* differ -> delete the old and append new */
/* delete old */
V1_delete_line_nat(Map, offset);
- /* write new */
- if (dig_fseek(&(Map->dig_fp), 0L, SEEK_END) == -1) /* end of file */
- return -1;
-
- new_offset = dig_ftell(&(Map->dig_fp));
- if (new_offset == -1)
- return -1;
-
- return V1__rewrite_line_nat(Map, new_offset, type, points, cats);
+ return V1__write_line_nat(Map, -1, type, points, cats);
}
}
@@ -183,20 +161,58 @@
* and cats was not changed or topology is not changed (nodes not moved,
* angles not changed etc.) */
+ int old_type;
off_t offset;
+ struct Plus_head *plus;
+ static struct line_cats *old_cats = NULL;
+ static struct line_pnts *old_points = NULL;
- if (0 != V2_delete_line_nat(Map, line))
+ plus = &(Map->plus);
+
+ if (plus->uplist.do_uplist) {
+ /* list of updated lines: undo needs copy on write */
+ if (0 != V2_delete_line_nat(Map, line))
+ return -1;
+
+ return V2_write_line_nat(Map, type, points, cats);
+ }
+
+ /* read the line */
+ if (!old_points) {
+ old_points = Vect_new_line_struct();
+ }
+ if (!old_cats) {
+ old_cats = Vect_new_cats_struct();
+ }
+ old_type = V2_read_line_nat(Map, old_points, old_cats, line);
+ if (old_type == -1)
return -1;
-
- G_debug(3, "V2_write_line_nat(), line = %d", line);
- /* rewrite feature in 'coor' file */
- offset = V1_rewrite_line_nat(Map, line, type, old_offset, points, cats);
- if (offset < 0)
- return -1;
+ /* rewrite feature in coor file */
+ if (old_type != -2 /* EOF -> write new line */
+ && points->n_points == old_points->n_points
+ && cats->n_cats == old_cats->n_cats
+ && (((type & GV_POINTS) && (old_type & GV_POINTS))
+ || ((type & GV_LINES) && (old_type & GV_LINES)))) {
- /* update topology */
- return V2__add_line_to_topo_nat(Map, offset, type, points, cats, -1, NULL);
+ /* equal -> overwrite the old */
+ offset = old_offset;
+ }
+ else {
+ /* differ -> delete the old and append new */
+ /* delete old */
+ V1_delete_line_nat(Map, old_offset);
+ offset = -1;
+ }
+
+ /* delete feature from topology */
+ if (0 != V2__delete_line_from_topo_nat(Map, line, type, old_points, old_cats))
+ return -1;
+
+ offset = V1__write_line_nat(Map, offset, type, points, cats);
+
+ /* update topology (build level >= GV_BUILD_BASE) */
+ return V2__add_line_to_topo_nat(Map, offset, type, points, cats, line, NULL);
}
/*!
@@ -255,6 +271,8 @@
int type;
struct P_line *Line;
struct Plus_head *plus;
+ static struct line_cats *Cats = NULL;
+ static struct line_pnts *Points = NULL;
G_debug(3, "V2_delete_line_nat(): line = %d", line);
@@ -353,6 +371,8 @@
int type;
struct Plus_head *plus;
struct P_line *Line;
+ static struct line_cats *Cats = NULL;
+ static struct line_pnts *Points = NULL;
plus = &(Map->plus);
@@ -373,7 +393,6 @@
if (0 != V1_restore_line_nat(Map, offset))
return -1;
-
/* read feature geometry */
if (!Points)
Points = Vect_new_line_struct();
@@ -390,8 +409,10 @@
/*** static or internal subroutines bellow ****/
/*!
- \brief Rewrites feature at the given offset
+ \brief Writes feature at the given offset or at the end of the file
+ Internal use only
+
\param Map pointer to Map_info structure
\param offset feature offset
\param type feature type (GV_POINT, GV_LINE, ...)
@@ -401,9 +422,9 @@
\return feature offset
\return -1 on error
*/
-off_t V1__rewrite_line_nat(struct Map_info *Map,
- off_t offset, int type,
- const struct line_pnts *points, const struct line_cats *cats)
+off_t V1__write_line_nat(struct Map_info *Map, off_t offset, int type,
+ const struct line_pnts *points,
+ const struct line_cats *cats)
{
int i, n_points;
char rhead, nc;
@@ -413,9 +434,24 @@
dig_set_cur_port(&(Map->head.port));
dig_fp = &(Map->dig_fp);
- if (dig_fseek(dig_fp, offset, 0) == -1)
- return -1;
+ /* if the given offset is smaller than the coor header size,
+ * append new feature to the end of the coor file,
+ * else overwrite whatever exists at offset */
+ if (offset < Map->head.head_size) {
+ if (dig_fseek(&(Map->dig_fp), 0L, SEEK_END) == -1) /* set to end of file */
+ return -1;
+
+ offset = dig_ftell(&(Map->dig_fp));
+ G_debug(3, "V1__rewrite_line_nat(): offset = %lu", offset);
+ if (offset == -1)
+ return -1;
+ }
+ else {
+ if (dig_fseek(dig_fp, offset, 0) == -1)
+ return -1;
+ }
+
/* first byte: 0 bit: 1 - alive, 0 - dead
* 1 bit: 1 - categories, 0 - no category
* 2-3 bit: store type
@@ -580,7 +616,7 @@
int V2__delete_line_from_topo_nat(struct Map_info *Map, int line, int type,
const struct line_pnts *points, const struct line_cats *cats)
{
- int i, first;
+ int i, first = 1;
int adjacent[4], n_adjacent;
struct bound_box box, abox;
More information about the grass-commit
mailing list