GRASS Programmer's Manual 6.4.1(2011)
cindex_rw.c
Go to the documentation of this file.
00001 
00002 /****************************************************************************
00003 *
00004 * MODULE:       Vector library 
00005 *               
00006 * AUTHOR(S):    Radim Blazek.
00007 *
00008 * PURPOSE:      Lower level functions for reading/writing/manipulating vectors.
00009 *
00010 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
00011 *
00012 *               This program is free software under the GNU General Public
00013 *               License (>=v2). Read the file COPYING that comes with GRASS
00014 *               for details.
00015 *
00016 *****************************************************************************/
00017 #include <stdlib.h>
00018 #include <string.h>
00019 #include <grass/gis.h>
00020 #include <grass/Vect.h>
00021 
00022 int dig_write_cidx_head(GVFILE * fp, struct Plus_head *plus)
00023 {
00024     int i;
00025     unsigned char buf[5];
00026     long length = 9;
00027 
00028     G_debug(3, "dig_write_cidx_head()");
00029 
00030     dig_rewind(fp);
00031     dig_set_cur_port(&(plus->cidx_port));
00032 
00033     /* Head of header */
00034     /* bytes 1 - 5 */
00035     buf[0] = GV_CIDX_VER_MAJOR;
00036     buf[1] = GV_CIDX_VER_MINOR;
00037     buf[2] = GV_CIDX_EARLIEST_MAJOR;
00038     buf[3] = GV_CIDX_EARLIEST_MINOR;
00039     buf[4] = plus->cidx_port.byte_order;
00040     if (0 >= dig__fwrite_port_C(buf, 5, fp))
00041         return (-1);
00042 
00043     /* bytes 6 - 9 : header size */
00044     if (0 >= dig__fwrite_port_L(&length, 1, fp))
00045         return (0);
00046 
00047     /* Body of header - info about all fields */
00048     /* Number of fields */
00049     if (0 >= dig__fwrite_port_I(&(plus->n_cidx), 1, fp))
00050         return (-1);
00051 
00052     for (i = 0; i < plus->n_cidx; i++) {
00053         int t;
00054         struct Cat_index *ci;
00055 
00056         ci = &(plus->cidx[i]);
00057 
00058         G_debug(3, "cidx %d head offset: %ld", i, dig_ftell(fp));
00059 
00060         /* Field number */
00061         if (0 >= dig__fwrite_port_I(&(ci->field), 1, fp))
00062             return (-1);
00063 
00064         /* Number of categories */
00065         if (0 >= dig__fwrite_port_I(&(ci->n_cats), 1, fp))
00066             return (-1);
00067 
00068         /* Number of unique categories */
00069         if (0 >= dig__fwrite_port_I(&(ci->n_ucats), 1, fp))
00070             return (-1);
00071 
00072         /* Number of types */
00073         if (0 >= dig__fwrite_port_I(&(ci->n_types), 1, fp))
00074             return (-1);
00075 
00076         /* Types */
00077         for (t = 0; t < ci->n_types; t++) {
00078             int wtype;
00079 
00080             /* type */
00081             wtype = dig_type_to_store(ci->type[t][0]);
00082             if (0 >= dig__fwrite_port_I(&wtype, 1, fp))
00083                 return (-1);
00084 
00085             /* number of items */
00086             if (0 >= dig__fwrite_port_I(&(ci->type[t][1]), 1, fp))
00087                 return (-1);
00088 
00089         }
00090 
00091         /* Offset */
00092         if (0 >= dig__fwrite_port_L(&(ci->offset), 1, fp))
00093             return (0);
00094         G_debug(3, "cidx %d offset: %ld", i, ci->offset);
00095     }
00096 
00097     G_debug(3, "cidx body offset %ld", dig_ftell(fp));
00098 
00099     return (0);
00100 }
00101 
00102 /* return: 0 OK, -1 error */
00103 int dig_read_cidx_head(GVFILE * fp, struct Plus_head *plus)
00104 {
00105     unsigned char buf[5];
00106     int i, byte_order;
00107 
00108     dig_rewind(fp);
00109 
00110     /* bytes 1 - 5 */
00111     if (0 >= dig__fread_port_C(buf, 5, fp))
00112         return (-1);
00113     plus->cidx_Version_Major = buf[0];
00114     plus->cidx_Version_Minor = buf[1];
00115     plus->cidx_Back_Major = buf[2];
00116     plus->cidx_Back_Minor = buf[3];
00117     byte_order = buf[4];
00118 
00119     G_debug(3,
00120             "Cidx header: file version %d.%d , supported from GRASS version %d.%d",
00121             plus->cidx_Version_Major, plus->cidx_Version_Minor,
00122             plus->cidx_Back_Major, plus->cidx_Back_Minor);
00123 
00124     G_debug(3, "  byte order %d", byte_order);
00125 
00126     /* check version numbers */
00127     if (plus->cidx_Version_Major > GV_CIDX_VER_MAJOR ||
00128         plus->cidx_Version_Minor > GV_CIDX_VER_MINOR) {
00129         /* The file was created by GRASS library with higher version than this one */
00130 
00131         if (plus->cidx_Back_Major > GV_CIDX_VER_MAJOR ||
00132             plus->cidx_Back_Minor > GV_CIDX_VER_MINOR) {
00133             /* This version of GRASS lib is lower than the oldest which can read this format */
00134             G_fatal_error
00135                 ("Category index format version %d.%d is not supported by this release."
00136                  " Try to rebuild topology or upgrade GRASS.",
00137                  plus->cidx_Version_Major, plus->cidx_Version_Minor);
00138             return (-1);
00139         }
00140 
00141         G_warning
00142             ("Your GRASS version does not fully support category index format %d.%d of the vector."
00143              " Consider to rebuild topology or upgrade GRASS.",
00144              plus->cidx_Version_Major, plus->cidx_Version_Minor);
00145     }
00146 
00147     dig_init_portable(&(plus->cidx_port), byte_order);
00148     dig_set_cur_port(&(plus->cidx_port));
00149 
00150     /* bytes 6 - 9 : header size */
00151     if (0 >= dig__fread_port_L(&(plus->cidx_head_size), 1, fp))
00152         return (-1);
00153     G_debug(3, "  header size %ld", plus->cidx_head_size);
00154 
00155     /* Body of header - info about all fields */
00156     /* Number of fields */
00157     if (0 >= dig__fread_port_I(&(plus->n_cidx), 1, fp))
00158         return (-1);
00159 
00160     /* alloc space */
00161     plus->a_cidx = plus->n_cidx;
00162     plus->cidx =
00163         (struct Cat_index *)G_malloc(plus->a_cidx * sizeof(struct Cat_index));
00164 
00165     for (i = 0; i < plus->n_cidx; i++) {
00166         int t;
00167         struct Cat_index *ci;
00168 
00169         ci = &(plus->cidx[i]);
00170         ci->cat = NULL;
00171         ci->a_cats = 0;
00172 
00173         /* Field number */
00174         if (0 >= dig__fread_port_I(&(ci->field), 1, fp))
00175             return (-1);
00176 
00177         /* Number of categories */
00178         if (0 >= dig__fread_port_I(&(ci->n_cats), 1, fp))
00179             return (-1);
00180 
00181         /* Number of unique categories */
00182         if (0 >= dig__fread_port_I(&(ci->n_ucats), 1, fp))
00183             return (-1);
00184 
00185         /* Number of types */
00186         if (0 >= dig__fread_port_I(&(ci->n_types), 1, fp))
00187             return (-1);
00188 
00189         /* Types */
00190         for (t = 0; t < ci->n_types; t++) {
00191             int rtype;
00192 
00193             /* type */
00194             if (0 >= dig__fread_port_I(&rtype, 1, fp))
00195                 return (-1);
00196             ci->type[t][0] = dig_type_from_store(rtype);
00197 
00198             /* number of items */
00199             if (0 >= dig__fread_port_I(&(ci->type[t][1]), 1, fp))
00200                 return (-1);
00201         }
00202 
00203         /* Offset */
00204         if (0 >= dig__fread_port_L(&(ci->offset), 1, fp))
00205             return (0);
00206     }
00207 
00208     if (dig_fseek(fp, plus->cidx_head_size, SEEK_SET) == -1)
00209         return (-1);
00210 
00211     return (0);
00212 }
00213 
00214 /* Write spatial index */
00215 int dig_write_cidx(GVFILE * fp, struct Plus_head *plus)
00216 {
00217     int i;
00218 
00219     dig_set_cur_port(&(plus->cidx_port));
00220     dig_rewind(fp);
00221 
00222     dig_write_cidx_head(fp, plus);
00223 
00224     /* Write category-type-id for each field */
00225     for (i = 0; i < plus->n_cidx; i++) {
00226         int j;
00227         struct Cat_index *ci;
00228 
00229         ci = &(plus->cidx[i]);
00230         ci->offset = dig_ftell(fp);
00231 
00232         /* convert type  */
00233         for (j = 0; j < ci->n_cats; j++)
00234             ci->cat[j][1] = dig_type_to_store(ci->cat[j][1]);
00235 
00236         if (0 >= dig__fwrite_port_I((int *)ci->cat, 3 * ci->n_cats, fp))
00237             return (-1);
00238 
00239         /* Return back */
00240         for (j = 0; j < ci->n_cats; j++)
00241             ci->cat[j][1] = dig_type_from_store(ci->cat[j][1]);
00242     }
00243 
00244     dig_write_cidx_head(fp, plus);      /* rewrite with offsets */
00245 
00246     return 0;
00247 }
00248 
00249 /* Read spatial index file 
00250  * returns 0 - OK
00251  *         1 - error
00252  */
00253 int dig_read_cidx(GVFILE * fp, struct Plus_head *plus, int head_only)
00254 {
00255     int i;
00256 
00257     G_debug(3, "dig_read_cidx()");
00258 
00259     dig_cidx_init(plus);
00260 
00261     dig_rewind(fp);
00262     if (dig_read_cidx_head(fp, plus) == -1) {
00263         G_debug(3, "Cannot read cidx head");
00264         return 1;
00265     }
00266 
00267     if (head_only) {
00268         plus->cidx_up_to_date = 1;      /* OK ? */
00269         return 0;
00270     }
00271 
00272     dig_set_cur_port(&(plus->cidx_port));
00273 
00274     /* Read category-type-id for each field */
00275     for (i = 0; i < plus->n_cidx; i++) {
00276         int j;
00277         struct Cat_index *ci;
00278 
00279         ci = &(plus->cidx[i]);
00280         ci->a_cats = ci->n_cats;
00281         ci->cat = G_malloc(ci->a_cats * 3 * sizeof(int));
00282 
00283         if (dig_fseek(fp, ci->offset, 0) == -1)
00284             return 1;
00285 
00286         if (0 >= dig__fread_port_I((int *)ci->cat, 3 * ci->n_cats, fp))
00287             return 1;
00288 
00289         /* convert type  */
00290         for (j = 0; j < ci->n_cats; j++)
00291             ci->cat[j][1] = dig_type_from_store(ci->cat[j][1]);
00292     }
00293 
00294 
00295     plus->cidx_up_to_date = 1;
00296 
00297     return 0;
00298 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines