[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