int dig_Rd_P_node(struct Plus_head *Plus, int n, struct gvfile * fp) { int cnt, n_edges; struct P_node *ptr; G_debug(4, "dig_Rd_P_node()"); if (0 >= dig__fread_port_P(&cnt, 1, fp)) return (-1); if (cnt == 0) { /* dead */ G_debug(4, " node is dead"); Plus->Node[n] = NULL; return 0; } ptr = dig_alloc_node(); ptr->n_lines = cnt; if (dig_node_alloc_line(ptr, ptr->n_lines) == -1) return -1; if (ptr->n_lines) { if (0 >= dig__fread_port_P(ptr->lines, ptr->n_lines, fp)) return (-1); if (0 >= dig__fread_port_F(ptr->angles, ptr->n_lines, fp)) return (-1); } if (Plus->with_z) if (0 >= dig__fread_port_P(&n_edges, 1, fp)) /* reserved for edges */ return (-1); /* here will be edges */ if (0 >= dig__fread_port_D(&(ptr->x), 1, fp)) return (-1); if (0 >= dig__fread_port_D(&(ptr->y), 1, fp)) return (-1); if (Plus->with_z) { if (0 >= dig__fread_port_D(&(ptr->z), 1, fp)) return (-1); } else ptr->z = 0; Plus->Node[n] = ptr; return (0); }
/* read node from file */ static void rtree_read_node(struct NodeBuffer *nb, off_t nodepos, struct RTree *t, struct Plus_head *Plus) { int i, maxcard; off_t pos; struct gvfile *file = &(Plus->spidx_fp); dig_fseek(file, nodepos, SEEK_SET); /* read with dig__fread_port_* fns */ dig__fread_port_I(&(nb->n.count), 1, file); dig__fread_port_I(&(nb->n.level), 1, file); maxcard = nb->n.level ? t->nodecard : t->leafcard; for (i = 0; i < maxcard; i++) { dig__fread_port_D(nb->n.branch[i].rect.boundary, NUMSIDES, file); dig__fread_port_O(&pos, 1, file, Plus->spidx_port.off_t_size); /* leaf node: vector object IDs are stored in child.id */ if (nb->n.level == 0) { nb->n.branch[i].child.id = (int)pos; } else { nb->n.branch[i].child.pos = pos; } } }
/* read_line() reads element from file returns element type */ int read_line(struct gvfile * Gvf, struct line_pnts *nline) { int n_points; long itype; if (0 >= dig__fread_port_L(&itype, 1, Gvf)) return (-2); itype = dig_old_to_new_type((char)itype); if (0 >= dig__fread_port_I(&n_points, 1, Gvf)) return (-2); if (0 > dig_alloc_points(nline, n_points)) G_fatal_error("Cannot allocate points"); nline->n_points = n_points; if (0 >= dig__fread_port_D(nline->x, n_points, Gvf)) return (-2); if (0 >= dig__fread_port_D(nline->y, n_points, Gvf)) return (-2); return ((int)itype); }
/*! \brief Read Plus_head from file \param fp pointer to gvfile structure \param[in,out] ptr pointer to Plus_head structure \return -1 error \return 0 OK */ int dig_Rd_Plus_head(struct gvfile * fp, struct Plus_head *ptr) { unsigned char buf[5]; int byte_order; dig_rewind(fp); /* bytes 1 - 5 */ if (0 >= dig__fread_port_C((char *)buf, 5, fp)) return (-1); ptr->version.topo.major = buf[0]; ptr->version.topo.minor = buf[1]; ptr->version.topo.back_major = buf[2]; ptr->version.topo.back_minor = buf[3]; byte_order = buf[4]; G_debug(2, "Topo header: file version %d.%d , supported from GRASS version %d.%d", ptr->version.topo.major, ptr->version.topo.minor, ptr->version.topo.back_major, ptr->version.topo.back_minor); G_debug(2, " byte order %d", byte_order); /* check version numbers */ if (ptr->version.topo.major > GV_TOPO_VER_MAJOR || ptr->version.topo.minor > GV_TOPO_VER_MINOR) { /* The file was created by GRASS library with higher version than this one */ if (ptr->version.topo.back_major > GV_TOPO_VER_MAJOR || ptr->version.topo.back_minor > GV_TOPO_VER_MINOR) { /* This version of GRASS lib is lower than the oldest which can read this format */ G_debug(1, "Topology format version %d.%d", ptr->version.topo.major, ptr->version.topo.minor); G_fatal_error (_("This version of GRASS (%d.%d) is too old to read this topology format." " Try to rebuild topology or upgrade GRASS to at least version %d."), GRASS_VERSION_MAJOR, GRASS_VERSION_MINOR, GRASS_VERSION_MAJOR + 1); return (-1); } G_warning(_("Your GRASS version does not fully support topology format %d.%d of the vector." " Consider to rebuild topology or upgrade GRASS."), ptr->version.topo.major, ptr->version.topo.minor); } if (ptr->version.topo.major < GV_TOPO_VER_MAJOR || (ptr->version.topo.major == GV_TOPO_VER_MAJOR && ptr->version.topo.minor < GV_TOPO_VER_MINOR)) { /* The file was created by GRASS library with lower version than this one */ /* This version of GRASS lib can not read this old format */ G_warning(_("Old topology format version %d.%d is not supported by this release." " Try to rebuild topology using v.build or v.build.all module."), ptr->version.topo.major, ptr->version.topo.minor); return (-1); } /* init Port_info structure and set as default */ dig_init_portable(&(ptr->port), byte_order); dig_set_cur_port(&(ptr->port)); /* bytes 6 - 9 : header size */ if (0 >= dig__fread_port_L(&(ptr->head_size), 1, fp)) return (-1); G_debug(2, " header size %ld", ptr->head_size); /* determine required offset size from header size */ /* this is not safe in case new fields get added in later versions */ /* better: add a new field with off_t_size after byte_order? */ if (ptr->head_size >= 142 + 32) /* keep in sync with dig_Wr_Plus_head() */ ptr->off_t_size = 8; else ptr->off_t_size = 4; if (sizeof(off_t) < ptr->off_t_size) { G_warning(_("Vector exceeds supported file size limit")); return (-1); } G_debug(2, "topo off_t size = %d", ptr->off_t_size); /* byte 10 : dimension 2D or 3D */ if (0 >= dig__fread_port_C((char *)buf, 1, fp)) return (-1); ptr->with_z = buf[0]; G_debug(2, " with_z %d", ptr->with_z); /* bytes 11 - 58 : bound box */ if (0 >= dig__fread_port_D(&(ptr->box.N), 1, fp)) return (-1); if (0 >= dig__fread_port_D(&(ptr->box.S), 1, fp)) return (-1); if (0 >= dig__fread_port_D(&(ptr->box.E), 1, fp)) return (-1); if (0 >= dig__fread_port_D(&(ptr->box.W), 1, fp)) return (-1); if (0 >= dig__fread_port_D(&(ptr->box.T), 1, fp)) return (-1); if (0 >= dig__fread_port_D(&(ptr->box.B), 1, fp)) return (-1); /* bytes 59 - 86 : number of structures */ if (0 >= dig__fread_port_P(&(ptr->n_nodes), 1, fp)) return (-1); if (0 >= dig__fread_port_P(&(ptr->n_edges), 1, fp)) return (-1); if (0 >= dig__fread_port_P(&(ptr->n_lines), 1, fp)) return (-1); if (0 >= dig__fread_port_P(&(ptr->n_areas), 1, fp)) return (-1); if (0 >= dig__fread_port_P(&(ptr->n_isles), 1, fp)) return (-1); if (0 >= dig__fread_port_P(&(ptr->n_volumes), 1, fp)) return (-1); if (0 >= dig__fread_port_P(&(ptr->n_holes), 1, fp)) return (-1); /* bytes 87 - 110 : number of line types */ if (0 >= dig__fread_port_P(&(ptr->n_plines), 1, fp)) return (-1); if (0 >= dig__fread_port_P(&(ptr->n_llines), 1, fp)) return (-1); if (0 >= dig__fread_port_P(&(ptr->n_blines), 1, fp)) return (-1); if (0 >= dig__fread_port_P(&(ptr->n_clines), 1, fp)) return (-1); if (0 >= dig__fread_port_P(&(ptr->n_flines), 1, fp)) return (-1); if (0 >= dig__fread_port_P(&(ptr->n_klines), 1, fp)) return (-1); /* bytes 111 - 138 : Offset */ if (0 >= dig__fread_port_O(&(ptr->Node_offset), 1, fp, ptr->off_t_size)) return (-1); if (0 >= dig__fread_port_O(&(ptr->Edge_offset), 1, fp, ptr->off_t_size)) return (-1); if (0 >= dig__fread_port_O(&(ptr->Line_offset), 1, fp, ptr->off_t_size)) return (-1); if (0 >= dig__fread_port_O(&(ptr->Area_offset), 1, fp, ptr->off_t_size)) return (-1); if (0 >= dig__fread_port_O(&(ptr->Isle_offset), 1, fp, ptr->off_t_size)) return (-1); if (0 >= dig__fread_port_O(&(ptr->Volume_offset), 1, fp, ptr->off_t_size)) return (-1); if (0 >= dig__fread_port_O(&(ptr->Hole_offset), 1, fp, ptr->off_t_size)) return (-1); /* bytes 139 - 142 : Coor size and time */ if (0 >= dig__fread_port_O(&(ptr->coor_size), 1, fp, ptr->off_t_size)) return (-1); G_debug(2, " coor size %"PRI_OFF_T, ptr->coor_size); dig_fseek(fp, ptr->head_size, SEEK_SET); return (0); }
static void rtree_load_to_memory(struct gvfile *fp, off_t rootpos, struct RTree *t, int off_t_size) { struct RTree_Node *newnode = NULL; int i, j, loadnode, maxcard; struct spidxstack *last; static struct spidxstack *s = NULL; int top = 0; if (!s) { s = G_malloc(MAXLEVEL * sizeof(struct spidxstack)); for (i = 0; i < MAXLEVEL; i++) { s[i].sn.branch = G_malloc(MAXCARD * sizeof(struct RTree_Branch)); for (j = 0; j < MAXCARD; j++) { s[i].sn.branch[j].rect.boundary = G_malloc(6 * sizeof(RectReal)); } } } /* stack size of t->rootlevel + 1 would be enough because of * depth-first postorder traversal: * only one node per level on stack at any given time */ /* add root node position to stack */ last = &(s[top]); G_fseek(fp->file, rootpos, SEEK_SET); /* read with dig__fread_port_* fns */ dig__fread_port_I(&(s[top].sn.count), 1, fp); dig__fread_port_I(&(s[top].sn.level), 1, fp); maxcard = s[top].sn.level ? t->nodecard : t->leafcard; for (j = 0; j < maxcard; j++) { dig__fread_port_D(s[top].sn.branch[j].rect.boundary, NUMSIDES, fp); dig__fread_port_O(&(s[top].pos[j]), 1, fp, off_t_size); /* leaf node: vector object IDs are stored in child.id */ if (s[top].sn.level == 0) { s[top].sn.branch[j].child.id = (int)s[top].pos[j]; } else { s[top].sn.branch[j].child.ptr = NULL; } } s[top].branch_id = i = 0; /* some sort of postorder traversal */ /* root node is loaded last and returned */ while (top >= 0) { last = &(s[top]); loadnode = 1; /* this is an internal node in the RTree * all its children are read first, * before it is transferred to the RTree in memory */ if (s[top].sn.level > 0) { for (i = s[top].branch_id; i < t->nodecard; i++) { if (s[top].pos[i] > 0) { s[top++].branch_id = i + 1; G_fseek(fp->file, last->pos[i], SEEK_SET); /* read with dig__fread_port_* fns */ dig__fread_port_I(&(s[top].sn.count), 1, fp); dig__fread_port_I(&(s[top].sn.level), 1, fp); maxcard = s[top].sn.level ? t->nodecard : t->leafcard; for (j = 0; j < maxcard; j++) { dig__fread_port_D(s[top].sn.branch[j].rect.boundary, NUMSIDES, fp); dig__fread_port_O(&(s[top].pos[j]), 1, fp, off_t_size); /* leaf node * vector object IDs are stored in file as * off_t but always fit into an int, see dig_structs.h * vector object IDs are transferred to child.id */ if (s[top].sn.level == 0) { s[top].sn.branch[j].child.id = (int)s[top].pos[j]; } else { s[top].sn.branch[j].child.ptr = NULL; } } s[top].branch_id = 0; loadnode = 0; break; } else if (last->pos[i] < 0) G_fatal_error("corrupt spatial index"); } if (loadnode) { /* nothing else found, ready to load */ s[top].branch_id = t->nodecard; } } if (loadnode) { /* ready to load node to memory */ newnode = RTreeAllocNode(t, s[top].sn.level); /* copy from stack node */ RTreeCopyNode(newnode, &(s[top].sn), t); top--; /* update child of parent node * this node is only updated if its level is > 0, i.e. * this is an internal node * children of internal nodes do not have an ID, instead * they point to the next nodes down the tree */ if (top >= 0) { s[top].sn.branch[s[top].branch_id - 1].child.ptr = newnode; } } } t->root = newnode; }
/*! \brief Search spatial index file Can't use regular RTreeSearch() here because sidx must be read with dig__fread_port_*() functions \param t pointer to RTree \param r search rectangle \param shcb user-provided callback \param cbarg argument for shcb \param Plus pointer to Plus_head structure \return number of qualifying rectangles */ int rtree_search(struct RTree *t, struct RTree_Rect *r, SearchHitCallback shcb, void *cbarg, struct Plus_head *Plus) { int hitCount = 0, found; /* int j, maxcard; */ int i; struct spidxpstack s[MAXLEVEL]; int top = 0, level; off_t lastpos; assert(r); assert(t); /* stack size of t->rootlevel + 1 is enough because of depth first search */ /* only one node per level on stack at any given time */ dig_set_cur_port(&(Plus->spidx_port)); /* add root node position to stack */ s[top].sn = rtree_get_node(t->rootpos, t->rootlevel, t, Plus); #if 0 dig_fseek(&(Plus->spidx_fp), t->rootpos, SEEK_SET); /* read with dig__fread_port_* fns */ dig__fread_port_I(&(s[top].sn.count), 1, &(Plus->spidx_fp)); dig__fread_port_I(&(s[top].sn.level), 1, &(Plus->spidx_fp)); maxcard = t->rootlevel ? t->nodecard : t->leafcard; for (j = 0; j < maxcard; j++) { dig__fread_port_D(s[top].sn.branch[j].rect.boundary, NUMSIDES, &(Plus->spidx_fp)); dig__fread_port_O(&(s[top].pos[j]), 1, &(Plus->spidx_fp), Plus->spidx_port.off_t_size); /* leaf node: vector object IDs are stored in child.id */ if (s[top].sn.level == 0) { s[top].sn.branch[j].child.id = (int)s[top].pos[j]; } else { s[top].sn.branch[j].child.pos = s[top].pos[j]; } } #endif s[top].branch_id = i = 0; while (top >= 0) { level = s[top].sn->level; if (level > 0) { /* this is an internal node in the tree */ found = 1; for (i = s[top].branch_id; i < t->nodecard; i++) { lastpos = s[top].sn->branch[i].child.pos; if (lastpos > 0 && RTreeOverlap(r, &(s[top].sn->branch[i].rect), t)) { s[top++].branch_id = i + 1; s[top].sn = rtree_get_node(lastpos, level - 1, t, Plus); #if 0 dig_fseek(&(Plus->spidx_fp), lastpos, SEEK_SET); /* read with dig__fread_port_* fns */ dig__fread_port_I(&(s[top].sn.count), 1, &(Plus->spidx_fp)); dig__fread_port_I(&(s[top].sn.level), 1, &(Plus->spidx_fp)); maxcard = s[top].sn.level ? t->nodecard : t->leafcard; for (j = 0; j < maxcard; j++) { dig__fread_port_D(s[top].sn.branch[j].rect.boundary, NUMSIDES, &(Plus->spidx_fp)); dig__fread_port_O(&(s[top].pos[j]), 1, &(Plus->spidx_fp), Plus->spidx_port.off_t_size); if (s[top].sn.level == 0) { s[top].sn.branch[j].child.id = (int)s[top].pos[j]; } else { s[top].sn.branch[j].child.pos = s[top].pos[j]; } } #endif s[top].branch_id = 0; found = 0; break; } } if (found) { /* nothing else found, go back up */ s[top].branch_id = t->nodecard; top--; } } else { /* this is a leaf node */ for (i = 0; i < t->leafcard; i++) { if (s[top].sn->branch[i].child.id && RTreeOverlap(r, &(s[top].sn->branch[i].rect), t)) { hitCount++; if (shcb) { /* call the user-provided callback */ if (!shcb((int)s[top].sn->branch[i].child.id, &s[top].sn->branch[i].rect, cbarg)) { /* callback wants to terminate search early */ return hitCount; } } } } top--; } } return hitCount; }
/* read old 3.0 or 4.0 dig file into array returns number of elements read into array or -1 on error */ int read_dig(FILE * Digin, struct Map_info *Mapout, struct Line **plines, int endian, int att) { char buf[100]; struct dig_head In_head; int lalloc, line = 0, type, portable = 1; int npoints = 0, nlines = 0, nbounds = 0; int ndpoints = 0, ndlines = 0, ndbounds = 0, nunknown = 0; struct Line *lines; struct line_pnts *nline; struct line_cats *cat_out; double dbuf; int ibuf; long lbuf; struct gvfile gvf; dig_file_init(&gvf); gvf.file = Digin; Vect__init_head(Mapout); /* set conversion matrices */ dig_init_portable(&(In_head.port), endian); /* Version 3 dig files were not portable and some version 4 * files may be also non portable */ G_message(_("Reading dig file...")); /* read and copy head */ dig_fseek(&gvf, 0L, SEEK_SET); /* set to beginning */ if (0 >= dig__fread_port_C(buf, DIG4_ORGAN_LEN, &gvf)) return -1; buf[DIG4_ORGAN_LEN - 1] = '\0'; Vect_set_organization(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_DATE_LEN, &gvf)) return -1; buf[DIG4_DATE_LEN - 1] = '\0'; Vect_set_date(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_YOUR_NAME_LEN, &gvf)) return -1; buf[DIG4_YOUR_NAME_LEN - 1] = '\0'; Vect_set_person(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_MAP_NAME_LEN, &gvf)) return -1; buf[DIG4_MAP_NAME_LEN - 1] = '\0'; Vect_set_map_name(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_SOURCE_DATE_LEN, &gvf)) return -1; buf[DIG4_SOURCE_DATE_LEN - 1] = '\0'; Vect_set_map_date(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_LINE_3_LEN, &gvf)) return -1; buf[DIG4_LINE_3_LEN - 1] = '\0'; Vect_set_comment(Mapout, buf); if (0 >= dig__fread_port_C(buf, VERS_4_DATA_SIZE, &gvf)) return -1; if (buf[0] != '%' || buf[1] != '%') { /* Version3.0 */ In_head.Version_Major = 3; portable = 0; /* input vector is not portable format */ G_message(_("Input file is version 3.")); } else { In_head.Version_Major = 4; G_message(_("Input file is version 4.")); /* determine if in portable format or not */ if (buf[6] == 1 && (~buf[6] & 0xff) == (buf[7] & 0xff)) { /* portable ? */ portable = 1; /* input vector is portable format */ } else { portable = 0; /* input vector is not portable format */ } } if (portable == 1) { G_message(_("Input file is portable.")); } else { G_warning(_("Input file is not portable. " "We will attempt to convert anyway but conversion may fail. " "Please read manual for detail information.")); } /* set Cur_Head because it is used by dig__*_convert() called by dig__fread_port_*() */ dig_set_cur_port(&(In_head.port)); if (0 >= dig__fread_port_L(&lbuf, 1, &gvf)) return -1; Vect_set_scale(Mapout, (int)lbuf); if (0 >= dig__fread_port_I(&ibuf, 1, &gvf)) return -1; Vect_set_zone(Mapout, ibuf); if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; /* W */ if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; /* E */ if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; /* S */ if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; /* N */ if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; Vect_set_thresh(Mapout, dbuf); /* reading dig file body (elements) */ nline = Vect_new_line_struct(); cat_out = Vect_new_cats_struct(); lalloc = 0; lines = NULL; line = 0; while (1) { type = read_line(&gvf, nline); G_debug(3, "read line = %d, type = %d", line, type); if (type == -2) break; /* EOF */ switch (type) { case GV_POINT: npoints++; break; case GV_LINE: nlines++; break; case GV_BOUNDARY: nbounds++; break; case 0: /* dead */ break; default: nunknown++; break; } if (!(type & (GV_POINT | GV_LINE | GV_BOUNDARY))) continue; if ((type & GV_BOUNDARY) || !att) { Vect_write_line(Mapout, type, nline, cat_out); /* reset In_head */ dig_set_cur_port(&(In_head.port)); } else { /* GV_POINT or GV_LINE */ if (line >= lalloc) { lalloc += 10000; lines = (struct Line *)G_realloc(lines, lalloc * sizeof(struct Line)); } lines[line].type = type; lines[line].n_points = nline->n_points; lines[line].cat = -1; lines[line].x = (double *)G_malloc(nline->n_points * sizeof(double)); lines[line].y = (double *)G_malloc(nline->n_points * sizeof(double)); memcpy((void *)lines[line].x, (void *)nline->x, nline->n_points * sizeof(double)); memcpy((void *)lines[line].y, (void *)nline->y, nline->n_points * sizeof(double)); line++; } } if (att) { G_message(_("[%d] points read to memory"), npoints); G_message(_("[%d] lines read to memory"), nlines); } else { G_message(_("[%d] points read and written to output"), npoints); G_message(_("[%d] lines read and written to output"), nlines); } G_message(_("[%d] area boundaries read and written to output"), nbounds); G_message(_("[%d] dead points skipped"), ndpoints); G_message(_("[%d] dead lines skipped"), ndlines); G_message(_("[%d] dead area boundaries skipped"), ndbounds); G_message(_("[%d] elements of unknown type skipped"), nunknown); G_message(_("[%d] elements read to memory"), line); *plines = lines; return (line); }
/*! \brief Read line from coor file \param Map vector map layer \param[out] p container used to store line points within \param[out] c container used to store line categories within \param offset given offset \return line type ( > 0 ) \return 0 dead line \return -1 out of memory \return -2 end of file */ int read_line_nat(struct Map_info *Map, struct line_pnts *p, struct line_cats *c, off_t offset) { register int i, dead = 0; int n_points; off_t size; int n_cats, do_cats; int type; char rhead, nc; short field; G_debug(3, "Vect__Read_line_nat: offset = %lu", (unsigned long) offset); Map->head.last_offset = offset; /* reads must set in_head, but writes use default */ dig_set_cur_port(&(Map->head.port)); dig_fseek(&(Map->dig_fp), offset, 0); if (0 >= dig__fread_port_C(&rhead, 1, &(Map->dig_fp))) return (-2); if (!(rhead & 0x01)) /* dead line */ dead = 1; if (rhead & 0x02) /* categories exists */ do_cats = 1; /* do not return here let file offset moves forward to next */ else /* line */ do_cats = 0; rhead >>= 2; type = dig_type_from_store((int)rhead); G_debug(3, " type = %d, do_cats = %d dead = %d", type, do_cats, dead); if (c != NULL) c->n_cats = 0; if (do_cats) { if (Map->head.Version_Minor == 1) { /* coor format 5.1 */ if (0 >= dig__fread_port_I(&n_cats, 1, &(Map->dig_fp))) return (-2); } else { /* coor format 5.0 */ if (0 >= dig__fread_port_C(&nc, 1, &(Map->dig_fp))) return (-2); n_cats = (int)nc; } G_debug(3, " n_cats = %d", n_cats); if (c != NULL) { c->n_cats = n_cats; if (n_cats > 0) { if (0 > dig_alloc_cats(c, (int)n_cats + 1)) return (-1); if (Map->head.Version_Minor == 1) { /* coor format 5.1 */ if (0 >= dig__fread_port_I(c->field, n_cats, &(Map->dig_fp))) return (-2); } else { /* coor format 5.0 */ for (i = 0; i < n_cats; i++) { if (0 >= dig__fread_port_S(&field, 1, &(Map->dig_fp))) return (-2); c->field[i] = (int)field; } } if (0 >= dig__fread_port_I(c->cat, n_cats, &(Map->dig_fp))) return (-2); } } else { if (Map->head.Version_Minor == 1) { /* coor format 5.1 */ size = (off_t) (2 * PORT_INT) * n_cats; } else { /* coor format 5.0 */ size = (off_t) (PORT_SHORT + PORT_INT) * n_cats; } dig_fseek(&(Map->dig_fp), size, SEEK_CUR); } } if (type & GV_POINTS) { n_points = 1; } else { if (0 >= dig__fread_port_I(&n_points, 1, &(Map->dig_fp))) return (-2); } G_debug(3, " n_points = %d", n_points); if (p != NULL) { if (0 > dig_alloc_points(p, n_points + 1)) return (-1); p->n_points = n_points; if (0 >= dig__fread_port_D(p->x, n_points, &(Map->dig_fp))) return (-2); if (0 >= dig__fread_port_D(p->y, n_points, &(Map->dig_fp))) return (-2); if (Map->head.with_z) { if (0 >= dig__fread_port_D(p->z, n_points, &(Map->dig_fp))) return (-2); } else { for (i = 0; i < n_points; i++) p->z[i] = 0.0; } } else { if (Map->head.with_z) size = (off_t) n_points * 3 * PORT_DOUBLE; else size = (off_t) n_points * 2 * PORT_DOUBLE; dig_fseek(&(Map->dig_fp), size, SEEK_CUR); } G_debug(3, " off = %lu", (unsigned long) dig_ftell(&(Map->dig_fp))); if (dead) return 0; return type; }