/*! \brief Add new field/cat to category structure if doesn't exist yet. \param[in,out] Cats line_cats structure \param[in] field layer number \param[in] cat category number \return number of categories \return 0 if no space for new category in structure, n_cats would be > GV_NCATS_MAX \return -1 on out of memory \return -2 if field out of range: 1 - GV_FIELD_MAX or cat out of range: 1 - GV_CAT_MAX */ int Vect_cat_set(struct line_cats *Cats, int field, int cat) { register int n; /* check input values */ /* compiler may warn: * comparison is always 0 due to limited range of data type * but remember that limit is set to portable data type length * and machine native size may be longer */ /* if (field < 1 || field > GV_FIELD_MAX || cat < 0 || cat > GV_CAT_MAX) return (-2); */ /* go through old cats and find if field/category exists */ for (n = 0; n < Cats->n_cats; n++) { if (Cats->field[n] == field && Cats->cat[n] == cat) return (1); } /* field was not found so we shall append new cat */ /* test if space exist */ if (n >= GV_NCATS_MAX) { G_fatal_error(_("Too many categories (%d), unable to set cat %d (layer %d)"), Cats->n_cats, cat, field); } if (Cats->n_cats == Cats->alloc_cats) { if (0 > dig_alloc_cats(Cats, Cats->n_cats + 100)) return (-1); } n = Cats->n_cats; Cats->field[n] = field; Cats->cat[n] = cat; Cats->n_cats++; return (1); }
/*! \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; }