plus_struct.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. /*
  2. ****************************************************************************
  3. *
  4. * MODULE: Vector library
  5. *
  6. * AUTHOR(S): Dave Gerdes, CERL.
  7. * Update to GRASS 5.7 Radim Blazek.
  8. *
  9. * PURPOSE: Lower level functions for reading/writing/manipulating vectors.
  10. *
  11. * COPYRIGHT: (C) 2001 by the GRASS Development Team
  12. *
  13. * This program is free software under the GNU General Public
  14. * License (>=v2). Read the file COPYING that comes with GRASS
  15. * for details.
  16. *
  17. *****************************************************************************/
  18. #include <sys/types.h>
  19. #include <string.h>
  20. #include <grass/vector.h>
  21. #include <grass/glocale.h>
  22. #include <grass/version.h>
  23. /*
  24. * Routines for reading and writing Dig+ structures.
  25. * return 0 on success, -1 on failure of whatever kind
  26. * if you don't want it written out, then don't call these routines
  27. * ie check for deleted status before calling a write routine
  28. * in as much as it would be nice to hide that code in here,
  29. * this is a library routine and we chose to make it dependent on
  30. * as few external files as possible
  31. */
  32. /* These routines assume ptr->alloc_lines is valid
  33. * Make sure it is initialized before calling
  34. */
  35. /*
  36. * Internally, my default variables for lines/areas/nodes/isles are type
  37. * plus_t which is typedefed as short. This limits the current version
  38. * to no more than 32K lines, nodes etc. (excluding points)
  39. * All in the name of future expansion, I have converted these values to
  40. * longs in the dig_plus data file.
  41. *
  42. * NOTE: 3.10 changes plus_t to ints.
  43. * This assumes that any reasonable machine will use 4 bytes to
  44. * store an int. The mapdev code is not guaranteed to work if
  45. * plus_t is changed to a type that is larger than an int.
  46. */
  47. int dig_Rd_P_node(struct Plus_head *Plus, int n, struct gvfile * fp)
  48. {
  49. int cnt, n_edges;
  50. struct P_node *ptr;
  51. G_debug(4, "dig_Rd_P_node()");
  52. if (0 >= dig__fread_port_P(&cnt, 1, fp))
  53. return (-1);
  54. if (cnt == 0) { /* dead */
  55. G_debug(4, " node is dead");
  56. Plus->Node[n] = NULL;
  57. return 0;
  58. }
  59. ptr = dig_alloc_node();
  60. ptr->n_lines = cnt;
  61. if (dig_node_alloc_line(ptr, ptr->n_lines) == -1)
  62. return -1;
  63. if (ptr->n_lines) {
  64. if (0 >= dig__fread_port_P(ptr->lines, ptr->n_lines, fp))
  65. return (-1);
  66. if (0 >= dig__fread_port_F(ptr->angles, ptr->n_lines, fp))
  67. return (-1);
  68. }
  69. if (Plus->with_z)
  70. if (0 >= dig__fread_port_P(&n_edges, 1, fp)) /* reserved for edges */
  71. return (-1);
  72. /* here will be edges */
  73. if (0 >= dig__fread_port_D(&(ptr->x), 1, fp))
  74. return (-1);
  75. if (0 >= dig__fread_port_D(&(ptr->y), 1, fp))
  76. return (-1);
  77. if (Plus->with_z) {
  78. if (0 >= dig__fread_port_D(&(ptr->z), 1, fp))
  79. return (-1);
  80. }
  81. else
  82. ptr->z = 0;
  83. Plus->Node[n] = ptr;
  84. return (0);
  85. }
  86. int dig_Wr_P_node(struct Plus_head *Plus, int n, struct gvfile * fp)
  87. {
  88. int i, n_edges = 0;
  89. struct P_node *ptr;
  90. G_debug(4, "dig_Wr_P_node()");
  91. ptr = Plus->Node[n];
  92. /* If NULL i.e. dead write just 0 instead of number of lines */
  93. if (ptr == NULL) {
  94. G_debug(4, " node is dead -> write 0 only");
  95. i = 0;
  96. if (0 >= dig__fwrite_port_P(&i, 1, fp))
  97. return (-1);
  98. return 0;
  99. }
  100. if (0 >= dig__fwrite_port_P(&(ptr->n_lines), 1, fp))
  101. return (-1);
  102. if (ptr->n_lines) {
  103. if (0 >= dig__fwrite_port_P(ptr->lines, ptr->n_lines, fp))
  104. return (-1);
  105. if (0 >= dig__fwrite_port_F(ptr->angles, ptr->n_lines, fp))
  106. return (-1);
  107. }
  108. if (Plus->with_z)
  109. if (0 >= dig__fwrite_port_P(&n_edges, 1, fp)) /* reserved for edges */
  110. return (-1);
  111. /* here will be edges */
  112. if (0 >= dig__fwrite_port_D(&(ptr->x), 1, fp))
  113. return (-1);
  114. if (0 >= dig__fwrite_port_D(&(ptr->y), 1, fp))
  115. return (-1);
  116. if (Plus->with_z)
  117. if (0 >= dig__fwrite_port_D(&(ptr->z), 1, fp))
  118. return (-1);
  119. return (0);
  120. }
  121. int dig_Rd_P_line(struct Plus_head *Plus, int n, struct gvfile * fp)
  122. {
  123. int n_edges;
  124. char tp;
  125. struct P_line *ptr;
  126. G_debug(4, "dig_Rd_P_line()");
  127. if (0 >= dig__fread_port_C(&tp, 1, fp))
  128. return (-1);
  129. if (tp == 0) { /* dead */
  130. G_debug(4, " line is dead");
  131. Plus->Line[n] = NULL;
  132. return 0;
  133. }
  134. ptr = dig_alloc_line();
  135. /* type */
  136. ptr->type = dig_type_from_store(tp);
  137. G_debug(5, " line type %d -> %d", tp, ptr->type);
  138. /* offset */
  139. if (0 >= dig__fread_port_O(&(ptr->offset), 1, fp, Plus->off_t_size))
  140. return (-1);
  141. if (ptr->type == GV_POINT) {
  142. ptr->topo = NULL;
  143. }
  144. else {
  145. ptr->topo = dig_alloc_topo(ptr->type);
  146. }
  147. /* centroids */
  148. if (ptr->type & GV_CENTROID) {
  149. struct P_topo_c *topo = (struct P_topo_c *)ptr->topo;
  150. if (0 >= dig__fread_port_P(&(topo->area), 1, fp))
  151. return -1;
  152. }
  153. /* lines */
  154. else if (ptr->type & GV_LINE) {
  155. struct P_topo_l *topo = (struct P_topo_l *)ptr->topo;
  156. if (0 >= dig__fread_port_P(&(topo->N1), 1, fp))
  157. return -1;
  158. if (0 >= dig__fread_port_P(&(topo->N2), 1, fp))
  159. return -1;
  160. }
  161. /* boundaries */
  162. else if (ptr->type & GV_BOUNDARY) {
  163. struct P_topo_b *topo = (struct P_topo_b *)ptr->topo;
  164. if (0 >= dig__fread_port_P(&(topo->N1), 1, fp))
  165. return -1;
  166. if (0 >= dig__fread_port_P(&(topo->N2), 1, fp))
  167. return -1;
  168. if (0 >= dig__fread_port_P(&(topo->left), 1, fp))
  169. return -1;
  170. if (0 >= dig__fread_port_P(&(topo->right), 1, fp))
  171. return -1;
  172. }
  173. /* faces */
  174. else if ((ptr->type & GV_FACE) && Plus->with_z) { /* reserved for face edges */
  175. struct P_topo_f *topo = (struct P_topo_f *)ptr->topo;
  176. if (0 >= dig__fread_port_I(&n_edges, 1, fp))
  177. return -1;
  178. /* here will be list of edges */
  179. /* left / right volume */
  180. if (0 >= dig__fread_port_P(&(topo->left), 1, fp))
  181. return -1;
  182. if (0 >= dig__fread_port_P(&(topo->left), 1, fp))
  183. return -1;
  184. }
  185. /* kernels */
  186. else if ((ptr->type & GV_KERNEL) && Plus->with_z) { /* reserved for kernel (volume number) */
  187. struct P_topo_k *topo = (struct P_topo_k *)ptr->topo;
  188. if (0 >= dig__fread_port_P(&(topo->volume), 1, fp))
  189. return -1;
  190. }
  191. Plus->Line[n] = ptr;
  192. return (0);
  193. }
  194. int dig_Wr_P_line(struct Plus_head *Plus, int n, struct gvfile * fp)
  195. {
  196. int n_edges = 0;
  197. char ch;
  198. struct P_line *ptr;
  199. G_debug(4, "dig_Wr_P_line() line = %d", n);
  200. ptr = Plus->Line[n];
  201. /* if NULL i.e. dead write just 0 instead of type */
  202. if (ptr == NULL) {
  203. G_debug(4, " line is dead -> write 0 only");
  204. ch = 0;
  205. if (0 >= dig__fwrite_port_C(&ch, 1, fp))
  206. return (-1);
  207. return 0;
  208. }
  209. /* type */
  210. ch = (char)dig_type_to_store(ptr->type);
  211. G_debug(5, " line type %d -> %d", ptr->type, ch);
  212. if (0 >= dig__fwrite_port_C(&ch, 1, fp))
  213. return (-1);
  214. /* offset */
  215. if (0 >= dig__fwrite_port_O(&(ptr->offset), 1, fp, Plus->off_t_size))
  216. return (-1);
  217. if (!ptr->topo)
  218. return (0);
  219. /* nothing else for points */
  220. /* centroids */
  221. if (ptr->type & GV_CENTROID) {
  222. struct P_topo_c *topo = (struct P_topo_c *)ptr->topo;
  223. if (0 >= dig__fwrite_port_P(&(topo->area), 1, fp))
  224. return (-1);
  225. }
  226. /* lines */
  227. else if (ptr->type & GV_LINE) {
  228. struct P_topo_l *topo = (struct P_topo_l *)ptr->topo;
  229. if (0 >= dig__fwrite_port_P(&(topo->N1), 1, fp))
  230. return (-1);
  231. if (0 >= dig__fwrite_port_P(&(topo->N2), 1, fp))
  232. return (-1);
  233. }
  234. /* boundaries */
  235. else if (ptr->type & GV_BOUNDARY) {
  236. struct P_topo_b *topo = (struct P_topo_b *)ptr->topo;
  237. if (0 >= dig__fwrite_port_P(&(topo->N1), 1, fp))
  238. return (-1);
  239. if (0 >= dig__fwrite_port_P(&(topo->N2), 1, fp))
  240. return (-1);
  241. if (0 >= dig__fwrite_port_P(&(topo->left), 1, fp))
  242. return (-1);
  243. if (0 >= dig__fwrite_port_P(&(topo->right), 1, fp))
  244. return (-1);
  245. }
  246. /* faces */
  247. else if ((ptr->type & GV_FACE) && Plus->with_z) { /* reserved for face */
  248. struct P_topo_f *topo = (struct P_topo_f *)ptr->topo;
  249. if (0 >= dig__fwrite_port_I(&n_edges, 1, fp))
  250. return (-1);
  251. /* here will be list of edges */
  252. /* left / right volume / hole */
  253. if (0 >= dig__fwrite_port_P(&(topo->left), 1, fp))
  254. return (-1);
  255. if (0 >= dig__fwrite_port_P(&(topo->right), 1, fp))
  256. return (-1);
  257. }
  258. /* kernels */
  259. else if ((ptr->type & GV_KERNEL) && Plus->with_z) { /* reserved for kernel (volume number) */
  260. struct P_topo_k *topo = (struct P_topo_k *)ptr->topo;
  261. /* volume */
  262. if (0 >= dig__fwrite_port_P(&(topo->volume), 1, fp))
  263. return (-1);
  264. }
  265. return (0);
  266. }
  267. int dig_Rd_P_area(struct Plus_head *Plus, int n, struct gvfile * fp)
  268. {
  269. int cnt;
  270. struct P_area *ptr;
  271. G_debug(4, "dig_Rd_P_area(): n = %d", n);
  272. if (0 >= dig__fread_port_P(&cnt, 1, fp))
  273. return (-1);
  274. if (cnt == 0) { /* dead */
  275. Plus->Area[n] = NULL;
  276. return 0;
  277. }
  278. ptr = dig_alloc_area();
  279. /* boundaries */
  280. ptr->n_lines = cnt;
  281. if (dig_area_alloc_line(ptr, ptr->n_lines) == -1)
  282. return -1;
  283. if (ptr->n_lines)
  284. if (0 >= dig__fread_port_P(ptr->lines, ptr->n_lines, fp))
  285. return -1;
  286. /* isles */
  287. if (0 >= dig__fread_port_P(&(ptr->n_isles), 1, fp))
  288. return -1;
  289. if (dig_area_alloc_isle(ptr, ptr->n_isles) == -1)
  290. return -1;
  291. if (ptr->n_isles)
  292. if (0 >= dig__fread_port_P(ptr->isles, ptr->n_isles, fp))
  293. return -1;
  294. /* centroid */
  295. if (0 >= dig__fread_port_P(&(ptr->centroid), 1, fp))
  296. return -1;
  297. Plus->Area[n] = ptr;
  298. return (0);
  299. }
  300. int dig_Wr_P_area(struct Plus_head *Plus, int n, struct gvfile * fp)
  301. {
  302. int i;
  303. struct P_area *ptr;
  304. ptr = Plus->Area[n];
  305. /* If NULL i.e. dead write just 0 instead of number of lines */
  306. if (ptr == NULL) {
  307. i = 0;
  308. if (0 >= dig__fwrite_port_P(&i, 1, fp))
  309. return (-1);
  310. return 0;
  311. }
  312. /* boundaries */
  313. if (0 >= dig__fwrite_port_P(&(ptr->n_lines), 1, fp))
  314. return (-1);
  315. if (ptr->n_lines)
  316. if (0 >= dig__fwrite_port_P(ptr->lines, ptr->n_lines, fp))
  317. return -1;
  318. /* isles */
  319. if (0 >= dig__fwrite_port_P(&(ptr->n_isles), 1, fp))
  320. return (-1);
  321. if (ptr->n_isles)
  322. if (0 >= dig__fwrite_port_P(ptr->isles, ptr->n_isles, fp))
  323. return -1;
  324. /* centroid */
  325. if (0 >= dig__fwrite_port_P(&(ptr->centroid), 1, fp))
  326. return (-1);
  327. return (0);
  328. }
  329. int dig_Rd_P_isle(struct Plus_head *Plus, int n, struct gvfile * fp)
  330. {
  331. int cnt;
  332. struct P_isle *ptr;
  333. G_debug(4, "dig_Rd_P_isle()");
  334. if (0 >= dig__fread_port_P(&cnt, 1, fp))
  335. return (-1);
  336. if (cnt == 0) { /* dead */
  337. Plus->Isle[n] = NULL;
  338. return 0;
  339. }
  340. ptr = dig_alloc_isle();
  341. /* boundaries */
  342. ptr->n_lines = cnt;
  343. if (dig_isle_alloc_line(ptr, ptr->n_lines) == -1)
  344. return -1;
  345. if (ptr->n_lines)
  346. if (0 >= dig__fread_port_P(ptr->lines, ptr->n_lines, fp))
  347. return -1;
  348. /* area */
  349. if (0 >= dig__fread_port_P(&(ptr->area), 1, fp))
  350. return -1;
  351. Plus->Isle[n] = ptr;
  352. return (0);
  353. }
  354. int dig_Wr_P_isle(struct Plus_head *Plus, int n, struct gvfile * fp)
  355. {
  356. int i;
  357. struct P_isle *ptr;
  358. ptr = Plus->Isle[n];
  359. /* If NULL i.e. dead write just 0 instead of number of lines */
  360. if (ptr == NULL) {
  361. i = 0;
  362. if (0 >= dig__fwrite_port_P(&i, 1, fp))
  363. return (-1);
  364. return 0;
  365. }
  366. /* lines */
  367. if (0 >= dig__fwrite_port_P(&(ptr->n_lines), 1, fp))
  368. return (-1);
  369. if (ptr->n_lines)
  370. if (0 >= dig__fwrite_port_P(ptr->lines, ptr->n_lines, fp))
  371. return -1;
  372. /* area */
  373. if (0 >= dig__fwrite_port_P(&(ptr->area), 1, fp))
  374. return (-1);
  375. return (0);
  376. }
  377. /*!
  378. \brief Read Plus_head from file
  379. \param fp pointer to gvfile structure
  380. \param[in,out] ptr pointer to Plus_head structure
  381. \return -1 error
  382. \return 0 OK
  383. */
  384. int dig_Rd_Plus_head(struct gvfile * fp, struct Plus_head *ptr)
  385. {
  386. unsigned char buf[5];
  387. int byte_order;
  388. dig_rewind(fp);
  389. /* bytes 1 - 5 */
  390. if (0 >= dig__fread_port_C((char *)buf, 5, fp))
  391. return (-1);
  392. ptr->version.topo.major = buf[0];
  393. ptr->version.topo.minor = buf[1];
  394. ptr->version.topo.back_major = buf[2];
  395. ptr->version.topo.back_minor = buf[3];
  396. byte_order = buf[4];
  397. G_debug(2,
  398. "Topo header: file version %d.%d , supported from GRASS version %d.%d",
  399. ptr->version.topo.major, ptr->version.topo.minor, ptr->version.topo.back_major,
  400. ptr->version.topo.back_minor);
  401. G_debug(2, " byte order %d", byte_order);
  402. /* check version numbers */
  403. if (ptr->version.topo.major > GV_TOPO_VER_MAJOR ||
  404. ptr->version.topo.minor > GV_TOPO_VER_MINOR) {
  405. /* The file was created by GRASS library with higher version than this one */
  406. if (ptr->version.topo.back_major > GV_TOPO_VER_MAJOR ||
  407. ptr->version.topo.back_minor > GV_TOPO_VER_MINOR) {
  408. /* This version of GRASS lib is lower than the oldest which can read this format */
  409. G_debug(1, "Topology format version %d.%d",
  410. ptr->version.topo.major, ptr->version.topo.minor);
  411. G_fatal_error
  412. (_("This version of GRASS (%d.%d) is too old to read this topology format."
  413. " Try to rebuild topology or upgrade GRASS to at least version %d."),
  414. GRASS_VERSION_MAJOR, GRASS_VERSION_MINOR, GRASS_VERSION_MAJOR + 1);
  415. return (-1);
  416. }
  417. G_warning(_("Your GRASS version does not fully support topology format %d.%d of the vector."
  418. " Consider to rebuild topology or upgrade GRASS."),
  419. ptr->version.topo.major, ptr->version.topo.minor);
  420. }
  421. if (ptr->version.topo.major < GV_TOPO_VER_MAJOR ||
  422. (ptr->version.topo.major == GV_TOPO_VER_MAJOR &&
  423. ptr->version.topo.minor < GV_TOPO_VER_MINOR)) {
  424. /* The file was created by GRASS library with lower version than this one */
  425. /* This version of GRASS lib can not read this old format */
  426. G_warning(_("Old topology format version %d.%d is not supported by this release."
  427. " Try to rebuild topology using v.build or v.build.all module."),
  428. ptr->version.topo.major, ptr->version.topo.minor);
  429. return (-1);
  430. }
  431. /* init Port_info structure and set as default */
  432. dig_init_portable(&(ptr->port), byte_order);
  433. dig_set_cur_port(&(ptr->port));
  434. /* bytes 6 - 9 : header size */
  435. if (0 >= dig__fread_port_L(&(ptr->head_size), 1, fp))
  436. return (-1);
  437. G_debug(2, " header size %ld", ptr->head_size);
  438. /* determine required offset size from header size */
  439. /* this is not safe in case new fields get added in later versions */
  440. /* better: add a new field with off_t_size after byte_order? */
  441. if (ptr->head_size >= 142 + 32) /* keep in sync with dig_Wr_Plus_head() */
  442. ptr->off_t_size = 8;
  443. else
  444. ptr->off_t_size = 4;
  445. if (sizeof(off_t) < ptr->off_t_size) {
  446. G_warning(_("Vector exceeds supported file size limit"));
  447. return (-1);
  448. }
  449. G_debug(2, "topo off_t size = %d", ptr->off_t_size);
  450. /* byte 10 : dimension 2D or 3D */
  451. if (0 >= dig__fread_port_C((char *)buf, 1, fp))
  452. return (-1);
  453. ptr->with_z = buf[0];
  454. G_debug(2, " with_z %d", ptr->with_z);
  455. /* bytes 11 - 58 : bound box */
  456. if (0 >= dig__fread_port_D(&(ptr->box.N), 1, fp))
  457. return (-1);
  458. if (0 >= dig__fread_port_D(&(ptr->box.S), 1, fp))
  459. return (-1);
  460. if (0 >= dig__fread_port_D(&(ptr->box.E), 1, fp))
  461. return (-1);
  462. if (0 >= dig__fread_port_D(&(ptr->box.W), 1, fp))
  463. return (-1);
  464. if (0 >= dig__fread_port_D(&(ptr->box.T), 1, fp))
  465. return (-1);
  466. if (0 >= dig__fread_port_D(&(ptr->box.B), 1, fp))
  467. return (-1);
  468. /* bytes 59 - 86 : number of structures */
  469. if (0 >= dig__fread_port_P(&(ptr->n_nodes), 1, fp))
  470. return (-1);
  471. if (0 >= dig__fread_port_P(&(ptr->n_edges), 1, fp))
  472. return (-1);
  473. if (0 >= dig__fread_port_P(&(ptr->n_lines), 1, fp))
  474. return (-1);
  475. if (0 >= dig__fread_port_P(&(ptr->n_areas), 1, fp))
  476. return (-1);
  477. if (0 >= dig__fread_port_P(&(ptr->n_isles), 1, fp))
  478. return (-1);
  479. if (0 >= dig__fread_port_P(&(ptr->n_volumes), 1, fp))
  480. return (-1);
  481. if (0 >= dig__fread_port_P(&(ptr->n_holes), 1, fp))
  482. return (-1);
  483. /* bytes 87 - 110 : number of line types */
  484. if (0 >= dig__fread_port_P(&(ptr->n_plines), 1, fp))
  485. return (-1);
  486. if (0 >= dig__fread_port_P(&(ptr->n_llines), 1, fp))
  487. return (-1);
  488. if (0 >= dig__fread_port_P(&(ptr->n_blines), 1, fp))
  489. return (-1);
  490. if (0 >= dig__fread_port_P(&(ptr->n_clines), 1, fp))
  491. return (-1);
  492. if (0 >= dig__fread_port_P(&(ptr->n_flines), 1, fp))
  493. return (-1);
  494. if (0 >= dig__fread_port_P(&(ptr->n_klines), 1, fp))
  495. return (-1);
  496. /* bytes 111 - 138 : Offset */
  497. if (0 >= dig__fread_port_O(&(ptr->Node_offset), 1, fp, ptr->off_t_size))
  498. return (-1);
  499. if (0 >= dig__fread_port_O(&(ptr->Edge_offset), 1, fp, ptr->off_t_size))
  500. return (-1);
  501. if (0 >= dig__fread_port_O(&(ptr->Line_offset), 1, fp, ptr->off_t_size))
  502. return (-1);
  503. if (0 >= dig__fread_port_O(&(ptr->Area_offset), 1, fp, ptr->off_t_size))
  504. return (-1);
  505. if (0 >= dig__fread_port_O(&(ptr->Isle_offset), 1, fp, ptr->off_t_size))
  506. return (-1);
  507. if (0 >= dig__fread_port_O(&(ptr->Volume_offset), 1, fp, ptr->off_t_size))
  508. return (-1);
  509. if (0 >= dig__fread_port_O(&(ptr->Hole_offset), 1, fp, ptr->off_t_size))
  510. return (-1);
  511. /* bytes 139 - 142 : Coor size and time */
  512. if (0 >= dig__fread_port_O(&(ptr->coor_size), 1, fp, ptr->off_t_size))
  513. return (-1);
  514. G_debug(2, " coor size %"PRI_OFF_T, ptr->coor_size);
  515. dig_fseek(fp, ptr->head_size, SEEK_SET);
  516. return (0);
  517. }
  518. int dig_Wr_Plus_head(struct gvfile * fp, struct Plus_head *ptr)
  519. {
  520. unsigned char buf[10];
  521. long length = 142;
  522. dig_rewind(fp);
  523. dig_set_cur_port(&(ptr->port));
  524. /* bytes 1 - 5 */
  525. buf[0] = GV_TOPO_VER_MAJOR;
  526. buf[1] = GV_TOPO_VER_MINOR;
  527. buf[2] = GV_TOPO_EARLIEST_MAJOR;
  528. buf[3] = GV_TOPO_EARLIEST_MINOR;
  529. buf[4] = ptr->port.byte_order;
  530. if (0 >= dig__fwrite_port_C((char *)buf, 5, fp))
  531. return (-1);
  532. /* determine required offset size from coor file size */
  533. if (ptr->coor_size > (off_t)PORT_LONG_MAX) {
  534. /* can only happen when sizeof(off_t) == 8 */
  535. ptr->off_t_size = 8;
  536. }
  537. else
  538. ptr->off_t_size = 4;
  539. /* add a new field with off_t_size after byte_order? */
  540. /* adjust header size for large files */
  541. if (ptr->off_t_size == 8) {
  542. /* 7 offset values and coor file size: add 8 * 4 */
  543. length += 32;
  544. }
  545. /* bytes 6 - 9 : header size */
  546. if (0 >= dig__fwrite_port_L(&length, 1, fp))
  547. return (0);
  548. /* byte 10 : dimension 2D or 3D */
  549. buf[0] = ptr->with_z;
  550. if (0 >= dig__fwrite_port_C((char *)buf, 1, fp))
  551. return (0);
  552. /* bytes 11 - 58 : bound box */
  553. if (0 >= dig__fwrite_port_D(&(ptr->box.N), 1, fp))
  554. return (-1);
  555. if (0 >= dig__fwrite_port_D(&(ptr->box.S), 1, fp))
  556. return (-1);
  557. if (0 >= dig__fwrite_port_D(&(ptr->box.E), 1, fp))
  558. return (-1);
  559. if (0 >= dig__fwrite_port_D(&(ptr->box.W), 1, fp))
  560. return (-1);
  561. if (0 >= dig__fwrite_port_D(&(ptr->box.T), 1, fp))
  562. return (-1);
  563. if (0 >= dig__fwrite_port_D(&(ptr->box.B), 1, fp))
  564. return (-1);
  565. /* bytes 59 - 86 : number of structures */
  566. if (0 >= dig__fwrite_port_P(&(ptr->n_nodes), 1, fp))
  567. return (-1);
  568. if (0 >= dig__fwrite_port_P(&(ptr->n_edges), 1, fp))
  569. return (-1);
  570. if (0 >= dig__fwrite_port_P(&(ptr->n_lines), 1, fp))
  571. return (-1);
  572. if (0 >= dig__fwrite_port_P(&(ptr->n_areas), 1, fp))
  573. return (-1);
  574. if (0 >= dig__fwrite_port_P(&(ptr->n_isles), 1, fp))
  575. return (-1);
  576. if (0 >= dig__fwrite_port_P(&(ptr->n_volumes), 1, fp))
  577. return (-1);
  578. if (0 >= dig__fwrite_port_P(&(ptr->n_holes), 1, fp))
  579. return (-1);
  580. /* bytes 87 - 110 : number of line types */
  581. if (0 >= dig__fwrite_port_P(&(ptr->n_plines), 1, fp))
  582. return (-1);
  583. if (0 >= dig__fwrite_port_P(&(ptr->n_llines), 1, fp))
  584. return (-1);
  585. if (0 >= dig__fwrite_port_P(&(ptr->n_blines), 1, fp))
  586. return (-1);
  587. if (0 >= dig__fwrite_port_P(&(ptr->n_clines), 1, fp))
  588. return (-1);
  589. if (0 >= dig__fwrite_port_P(&(ptr->n_flines), 1, fp))
  590. return (-1);
  591. if (0 >= dig__fwrite_port_P(&(ptr->n_klines), 1, fp))
  592. return (-1);
  593. /* bytes 111 - 138 : Offset */
  594. if (0 >= dig__fwrite_port_O(&(ptr->Node_offset), 1, fp, ptr->off_t_size))
  595. return (-1);
  596. if (0 >= dig__fwrite_port_O(&(ptr->Edge_offset), 1, fp, ptr->off_t_size))
  597. return (-1);
  598. if (0 >= dig__fwrite_port_O(&(ptr->Line_offset), 1, fp, ptr->off_t_size))
  599. return (-1);
  600. if (0 >= dig__fwrite_port_O(&(ptr->Area_offset), 1, fp, ptr->off_t_size))
  601. return (-1);
  602. if (0 >= dig__fwrite_port_O(&(ptr->Isle_offset), 1, fp, ptr->off_t_size))
  603. return (-1);
  604. if (0 >= dig__fwrite_port_O(&(ptr->Volume_offset), 1, fp, ptr->off_t_size))
  605. return (-1);
  606. if (0 >= dig__fwrite_port_O(&(ptr->Hole_offset), 1, fp, ptr->off_t_size))
  607. return (-1);
  608. /* bytes 139 - 142 : Coor size and time */
  609. if (0 >= dig__fwrite_port_O(&(ptr->coor_size), 1, fp, ptr->off_t_size))
  610. return (-1);
  611. G_debug(2, "topo body offset %"PRI_OFF_T, dig_ftell(fp));
  612. return (0);
  613. }