plus_struct.c 20 KB

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