cindex_rw.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /****************************************************************************
  2. *
  3. * MODULE: Vector library
  4. *
  5. * AUTHOR(S): Radim Blazek.
  6. *
  7. * PURPOSE: Lower level functions for reading/writing/manipulating vectors.
  8. *
  9. * COPYRIGHT: (C) 2001 by the GRASS Development Team
  10. *
  11. * This program is free software under the GNU General Public
  12. * License (>=v2). Read the file COPYING that comes with GRASS
  13. * for details.
  14. *
  15. *****************************************************************************/
  16. #include <stdlib.h>
  17. #include <sys/types.h>
  18. #include <string.h>
  19. #include <grass/vector.h>
  20. int dig_write_cidx_head(struct gvfile * fp, struct Plus_head *plus)
  21. {
  22. int i;
  23. unsigned char buf[5];
  24. long length = 9;
  25. G_debug(3, "dig_write_cidx_head()");
  26. dig_rewind(fp);
  27. dig_set_cur_port(&(plus->cidx_port));
  28. /* Head of header */
  29. /* bytes 1 - 5 */
  30. buf[0] = GV_CIDX_VER_MAJOR;
  31. buf[1] = GV_CIDX_VER_MINOR;
  32. buf[2] = GV_CIDX_EARLIEST_MAJOR;
  33. buf[3] = GV_CIDX_EARLIEST_MINOR;
  34. buf[4] = plus->cidx_port.byte_order;
  35. if (0 >= dig__fwrite_port_C((const char *)buf, 5, fp))
  36. return (-1);
  37. /* get required offset size */
  38. if (plus->off_t_size == 0) {
  39. /* should not happen, topo is written first */
  40. if (plus->coor_size > (off_t)PORT_LONG_MAX)
  41. plus->off_t_size = 8;
  42. else
  43. plus->off_t_size = 4;
  44. }
  45. /* bytes 6 - 9 : header size */
  46. if (0 >= dig__fwrite_port_L(&length, 1, fp))
  47. return (0);
  48. /* Body of header - info about all fields */
  49. /* Number of fields */
  50. if (0 >= dig__fwrite_port_I(&(plus->n_cidx), 1, fp))
  51. return (-1);
  52. for (i = 0; i < plus->n_cidx; i++) {
  53. int t;
  54. struct Cat_index *ci;
  55. ci = &(plus->cidx[i]);
  56. G_debug(3, "cidx %d head offset: %"PRI_OFF_T, i, dig_ftell(fp));
  57. /* Field number */
  58. if (0 >= dig__fwrite_port_I(&(ci->field), 1, fp))
  59. return (-1);
  60. /* Number of categories */
  61. if (0 >= dig__fwrite_port_I(&(ci->n_cats), 1, fp))
  62. return (-1);
  63. /* Number of unique categories */
  64. if (0 >= dig__fwrite_port_I(&(ci->n_ucats), 1, fp))
  65. return (-1);
  66. /* Number of types */
  67. if (0 >= dig__fwrite_port_I(&(ci->n_types), 1, fp))
  68. return (-1);
  69. /* Types */
  70. for (t = 0; t < ci->n_types; t++) {
  71. int wtype;
  72. /* type */
  73. wtype = dig_type_to_store(ci->type[t][0]);
  74. if (0 >= dig__fwrite_port_I(&wtype, 1, fp))
  75. return (-1);
  76. /* number of items */
  77. if (0 >= dig__fwrite_port_I(&(ci->type[t][1]), 1, fp))
  78. return (-1);
  79. }
  80. /* Offset */
  81. if (0 >= dig__fwrite_port_O(&(ci->offset), 1, fp, plus->off_t_size))
  82. return (0);
  83. G_debug(3, "cidx %d offset: %"PRI_OFF_T, i, ci->offset);
  84. }
  85. G_debug(3, "cidx body offset %"PRI_OFF_T, dig_ftell(fp));
  86. return (0);
  87. }
  88. /*!
  89. \brief Read header of cidx file
  90. \param fp pointer to gvfile structure
  91. \param plus pointer to Plus_head strcuture
  92. \return 0 OK
  93. \return -1 error
  94. */
  95. int dig_read_cidx_head(struct gvfile * fp, struct Plus_head *plus)
  96. {
  97. unsigned char buf[5];
  98. int i, byte_order;
  99. dig_rewind(fp);
  100. /* bytes 1 - 5 */
  101. if (0 >= dig__fread_port_C((char *)buf, 5, fp))
  102. return (-1);
  103. plus->cidx_Version_Major = buf[0];
  104. plus->cidx_Version_Minor = buf[1];
  105. plus->cidx_Back_Major = buf[2];
  106. plus->cidx_Back_Minor = buf[3];
  107. byte_order = buf[4];
  108. G_debug(3,
  109. "Cidx header: file version %d.%d , supported from GRASS version %d.%d",
  110. plus->cidx_Version_Major, plus->cidx_Version_Minor,
  111. plus->cidx_Back_Major, plus->cidx_Back_Minor);
  112. G_debug(3, " byte order %d", byte_order);
  113. /* check version numbers */
  114. if (plus->cidx_Version_Major > GV_CIDX_VER_MAJOR ||
  115. plus->cidx_Version_Minor > GV_CIDX_VER_MINOR) {
  116. /* The file was created by GRASS library with higher version than this one */
  117. if (plus->cidx_Back_Major > GV_CIDX_VER_MAJOR ||
  118. plus->cidx_Back_Minor > GV_CIDX_VER_MINOR) {
  119. /* This version of GRASS lib is lower than the oldest which can read this format */
  120. G_fatal_error
  121. ("Category index format version %d.%d is not supported by this release."
  122. " Try to rebuild topology or upgrade GRASS.",
  123. plus->cidx_Version_Major, plus->cidx_Version_Minor);
  124. return (-1);
  125. }
  126. G_warning
  127. ("Your GRASS version does not fully support category index format %d.%d of the vector."
  128. " Consider to rebuild topology or upgrade GRASS.",
  129. plus->cidx_Version_Major, plus->cidx_Version_Minor);
  130. }
  131. dig_init_portable(&(plus->cidx_port), byte_order);
  132. dig_set_cur_port(&(plus->cidx_port));
  133. /* bytes 6 - 9 : header size */
  134. if (0 >= dig__fread_port_L(&(plus->cidx_head_size), 1, fp))
  135. return (-1);
  136. G_debug(3, " header size %ld", plus->cidx_head_size);
  137. /* get required offset size */
  138. if (plus->off_t_size == 0) {
  139. /* should not happen, topo is opened first */
  140. if (plus->coor_size > (off_t)PORT_LONG_MAX)
  141. plus->off_t_size = 8;
  142. else
  143. plus->off_t_size = 4;
  144. }
  145. /* Body of header - info about all fields */
  146. /* Number of fields */
  147. if (0 >= dig__fread_port_I(&(plus->n_cidx), 1, fp))
  148. return (-1);
  149. /* alloc space */
  150. plus->a_cidx = plus->n_cidx;
  151. plus->cidx =
  152. (struct Cat_index *)G_malloc(plus->a_cidx * sizeof(struct Cat_index));
  153. for (i = 0; i < plus->n_cidx; i++) {
  154. int t;
  155. struct Cat_index *ci;
  156. ci = &(plus->cidx[i]);
  157. ci->cat = NULL;
  158. ci->a_cats = 0;
  159. /* Field number */
  160. if (0 >= dig__fread_port_I(&(ci->field), 1, fp))
  161. return (-1);
  162. /* Number of categories */
  163. if (0 >= dig__fread_port_I(&(ci->n_cats), 1, fp))
  164. return (-1);
  165. /* Number of unique categories */
  166. if (0 >= dig__fread_port_I(&(ci->n_ucats), 1, fp))
  167. return (-1);
  168. /* Number of types */
  169. if (0 >= dig__fread_port_I(&(ci->n_types), 1, fp))
  170. return (-1);
  171. /* Types */
  172. for (t = 0; t < ci->n_types; t++) {
  173. int rtype;
  174. /* type */
  175. if (0 >= dig__fread_port_I(&rtype, 1, fp))
  176. return (-1);
  177. ci->type[t][0] = dig_type_from_store(rtype);
  178. /* number of items */
  179. if (0 >= dig__fread_port_I(&(ci->type[t][1]), 1, fp))
  180. return (-1);
  181. }
  182. /* Offset */
  183. if (0 >= dig__fread_port_O(&(ci->offset), 1, fp, plus->off_t_size))
  184. return (0);
  185. }
  186. if (dig_fseek(fp, plus->cidx_head_size, SEEK_SET) == -1)
  187. return (-1);
  188. return (0);
  189. }
  190. /* Write spatial index */
  191. int dig_write_cidx(struct gvfile * fp, struct Plus_head *plus)
  192. {
  193. int i;
  194. dig_set_cur_port(&(plus->cidx_port));
  195. dig_rewind(fp);
  196. dig_write_cidx_head(fp, plus);
  197. /* Write category-type-id for each field */
  198. for (i = 0; i < plus->n_cidx; i++) {
  199. int j;
  200. struct Cat_index *ci;
  201. ci = &(plus->cidx[i]);
  202. ci->offset = dig_ftell(fp);
  203. /* convert type */
  204. for (j = 0; j < ci->n_cats; j++)
  205. ci->cat[j][1] = dig_type_to_store(ci->cat[j][1]);
  206. if (0 >= dig__fwrite_port_I((int *)ci->cat, 3 * ci->n_cats, fp))
  207. return (-1);
  208. /* Return back */
  209. for (j = 0; j < ci->n_cats; j++)
  210. ci->cat[j][1] = dig_type_from_store(ci->cat[j][1]);
  211. }
  212. dig_write_cidx_head(fp, plus); /* rewrite with offsets */
  213. return 0;
  214. }
  215. /*!
  216. \brief Read spatial index file
  217. \param fp pointer to gvfile structure
  218. \param[in,out] plus pointer to Plus_head structure
  219. \param head_only non-zero to read only head
  220. \return 0 OK
  221. \return 1 error
  222. */
  223. int dig_read_cidx(struct gvfile * fp, struct Plus_head *plus, int head_only)
  224. {
  225. int i;
  226. G_debug(3, "dig_read_cidx()");
  227. dig_cidx_init(plus);
  228. dig_rewind(fp);
  229. if (dig_read_cidx_head(fp, plus) == -1) {
  230. G_debug(3, "Cannot read cidx head");
  231. return 1;
  232. }
  233. if (head_only) {
  234. plus->cidx_up_to_date = 1; /* OK ? */
  235. return 0;
  236. }
  237. dig_set_cur_port(&(plus->cidx_port));
  238. /* Read category-type-id for each field */
  239. for (i = 0; i < plus->n_cidx; i++) {
  240. int j;
  241. struct Cat_index *ci;
  242. ci = &(plus->cidx[i]);
  243. ci->a_cats = ci->n_cats;
  244. ci->cat = G_malloc(ci->a_cats * 3 * sizeof(int));
  245. if (dig_fseek(fp, ci->offset, 0) == -1)
  246. return 1;
  247. if (0 >= dig__fread_port_I((int *)ci->cat, 3 * ci->n_cats, fp))
  248. return 1;
  249. /* convert type */
  250. for (j = 0; j < ci->n_cats; j++)
  251. ci->cat[j][1] = dig_type_from_store(ci->cat[j][1]);
  252. }
  253. plus->cidx_up_to_date = 1;
  254. return 0;
  255. }