portable.c 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027
  1. /*!
  2. \file diglib/file.c
  3. \brief Vector library - portability (lower level functions)
  4. Lower level functions for reading/writing/manipulating vectors.
  5. (C) 2001-2009 by the GRASS Development Team
  6. This program is free software under the GNU General Public License
  7. (>=v2). Read the file COPYING that comes with GRASS for details.
  8. \author Original author CERL, probably Dave Gerdes
  9. \author Update to GRASS 5.7 Radim Blazek
  10. */
  11. #include <sys/types.h>
  12. #include <string.h>
  13. #include <grass/vector.h>
  14. #include <grass/glocale.h>
  15. extern void port_init(void);
  16. extern int nat_dbl;
  17. extern int nat_flt;
  18. extern int nat_lng;
  19. extern int nat_off_t;
  20. extern int nat_int;
  21. extern int nat_shrt;
  22. extern int dbl_order;
  23. extern int flt_order;
  24. extern int off_t_order;
  25. extern int lng_order;
  26. extern int int_order;
  27. extern int shrt_order;
  28. extern unsigned char dbl_cnvrt[sizeof(double)];
  29. extern unsigned char flt_cnvrt[sizeof(float)];
  30. extern unsigned char off_t_cnvrt[sizeof(off_t)];
  31. extern unsigned char lng_cnvrt[sizeof(long)];
  32. extern unsigned char int_cnvrt[sizeof(int)];
  33. extern unsigned char shrt_cnvrt[sizeof(short)];
  34. struct Port_info *Cur_Head;
  35. static char *buffer = NULL;
  36. static int buf_alloced = 0;
  37. static int buf_alloc(int needed)
  38. {
  39. char *p;
  40. int cnt;
  41. if (needed <= buf_alloced)
  42. return (0);
  43. cnt = buf_alloced;
  44. p = dig__alloc_space(needed, &cnt, 100, buffer, 1);
  45. if (p == NULL)
  46. return (dig_out_of_memory());
  47. buffer = p;
  48. buf_alloced = cnt;
  49. return (0);
  50. }
  51. /*!
  52. \brief Read doubles from the Portable Vector Format
  53. These routines must handle any type size conversions between the
  54. portable format and the native machine.
  55. \param[out] buf data buffer
  56. \param cnt number of members
  57. \param fp pointer to struct gvfile
  58. \return 0 error
  59. \return 1 OK
  60. */
  61. int dig__fread_port_D(double *buf, size_t cnt, struct gvfile * fp)
  62. {
  63. unsigned int i, j;
  64. int ret;
  65. unsigned char *c1, *c2;
  66. if (Cur_Head->dbl_quick) {
  67. ret = dig_fread(buf, PORT_DOUBLE, cnt, fp);
  68. if (ret != (int) cnt)
  69. return 0;
  70. }
  71. else {
  72. /* read into buffer */
  73. buf_alloc(cnt * PORT_DOUBLE);
  74. ret = dig_fread(buffer, PORT_DOUBLE, cnt, fp);
  75. if (ret != (int) cnt)
  76. return 0;
  77. /* read from buffer in changed order */
  78. c1 = (unsigned char *)buffer;
  79. c2 = (unsigned char *)buf;
  80. for (i = 0; i < cnt; i++) {
  81. for (j = 0; j < PORT_DOUBLE; j++) {
  82. c2[Cur_Head->dbl_cnvrt[j]] = c1[j];
  83. }
  84. c1 += PORT_DOUBLE;
  85. c2 += sizeof(double);
  86. }
  87. }
  88. return 1;
  89. }
  90. /*!
  91. \brief Read floats from the Portable Vector Format
  92. These routines must handle any type size conversions between the
  93. portable format and the native machine.
  94. \param[out] buf data buffer
  95. \param cnt number of members
  96. \param fp pointer to struct gvfile
  97. \return 0 error
  98. \return 1 OK
  99. */
  100. int dig__fread_port_F(float *buf, size_t cnt, struct gvfile * fp)
  101. {
  102. unsigned int i, j;
  103. int ret;
  104. unsigned char *c1, *c2;
  105. if (Cur_Head->flt_quick) {
  106. ret = dig_fread(buf, PORT_FLOAT, cnt, fp);
  107. if (ret != (int) cnt)
  108. return 0;
  109. }
  110. else {
  111. /* read into buffer */
  112. buf_alloc(cnt * PORT_FLOAT);
  113. ret = dig_fread(buffer, PORT_FLOAT, cnt, fp);
  114. if (ret != (int) cnt)
  115. return 0;
  116. /* read from buffer in changed order */
  117. c1 = (unsigned char *)buffer;
  118. c2 = (unsigned char *)buf;
  119. for (i = 0; i < cnt; i++) {
  120. for (j = 0; j < PORT_FLOAT; j++) {
  121. c2[Cur_Head->flt_cnvrt[j]] = c1[j];
  122. }
  123. c1 += PORT_FLOAT;
  124. c2 += sizeof(float);
  125. }
  126. }
  127. return 1;
  128. }
  129. /*!
  130. \brief Read off_ts from the Portable Vector Format
  131. These routines must handle any type size conversions between the
  132. portable format and the native machine.
  133. \param[out] buf data buffer
  134. \param cnt number of members
  135. \param fp pointer to struct gvfile
  136. \param port_off_t_size offset
  137. \return 0 error
  138. \return 1 OK
  139. */
  140. int dig__fread_port_O(off_t *buf, size_t cnt, struct gvfile * fp, size_t port_off_t_size)
  141. {
  142. unsigned int i, j;
  143. int ret;
  144. unsigned char *c1, *c2;
  145. if (Cur_Head->off_t_quick) {
  146. if (nat_off_t == port_off_t_size) {
  147. ret = dig_fread(buf, port_off_t_size, cnt, fp);
  148. if (ret != (int) cnt)
  149. return 0;
  150. }
  151. else if (nat_off_t > port_off_t_size) {
  152. /* read into buffer */
  153. buf_alloc(cnt * port_off_t_size);
  154. ret = dig_fread(buffer, port_off_t_size, cnt, fp);
  155. if (ret != (int) cnt)
  156. return 0;
  157. /* set buffer to zero (positive numbers) */
  158. memset(buf, 0, cnt * sizeof(off_t));
  159. /* read from buffer in changed order */
  160. c1 = (unsigned char *)buffer;
  161. c2 = (unsigned char *)buf;
  162. for (i = 0; i < cnt; i++) {
  163. /* set to FF if the value is negative */
  164. if (off_t_order == ENDIAN_LITTLE) {
  165. if (c1[port_off_t_size - 1] & 0x80)
  166. memset(c2, 0xff, sizeof(off_t));
  167. }
  168. else {
  169. if (c1[0] & 0x80)
  170. memset(c2, 0xff, sizeof(off_t));
  171. }
  172. if (off_t_order == ENDIAN_LITTLE)
  173. memcpy(c2, c1, port_off_t_size);
  174. else
  175. memcpy(c2 + nat_off_t - port_off_t_size, c1, port_off_t_size);
  176. c1 += port_off_t_size;
  177. c2 += sizeof(off_t);
  178. }
  179. }
  180. else if (nat_off_t < port_off_t_size) {
  181. /* should never happen */
  182. G_fatal_error(_("Vector exceeds supported file size limit"));
  183. }
  184. }
  185. else {
  186. if (nat_off_t >= port_off_t_size) {
  187. /* read into buffer */
  188. buf_alloc(cnt * port_off_t_size);
  189. ret = dig_fread(buffer, port_off_t_size, cnt, fp);
  190. if (ret != (int) cnt)
  191. return 0;
  192. /* set buffer to zero (positive numbers) */
  193. memset(buf, 0, cnt * sizeof(off_t));
  194. /* read from buffer in changed order */
  195. c1 = (unsigned char *)buffer;
  196. c2 = (unsigned char *)buf;
  197. for (i = 0; i < cnt; i++) {
  198. /* set to FF if the value is negative */
  199. if (Cur_Head->byte_order == ENDIAN_LITTLE) {
  200. if (c1[port_off_t_size - 1] & 0x80)
  201. memset(c2, 0xff, sizeof(off_t));
  202. }
  203. else {
  204. if (c1[0] & 0x80)
  205. memset(c2, 0xff, sizeof(off_t));
  206. }
  207. for (j = 0; j < port_off_t_size; j++)
  208. c2[Cur_Head->off_t_cnvrt[j]] = c1[j];
  209. c1 += port_off_t_size;
  210. c2 += sizeof(off_t);
  211. }
  212. }
  213. else if (nat_off_t < port_off_t_size) {
  214. /* should never happen */
  215. G_fatal_error(_("Vector exceeds supported file size limit"));
  216. }
  217. }
  218. return 1;
  219. }
  220. /*!
  221. \brief Read longs from the Portable Vector Format
  222. These routines must handle any type size conversions between the
  223. portable format and the native machine.
  224. \param[out] buf data buffer
  225. \param cnt number of members
  226. \param fp pointer to struct gvfile
  227. \return 0 error
  228. \return 1 OK
  229. */
  230. int dig__fread_port_L(long *buf, size_t cnt, struct gvfile * fp)
  231. {
  232. unsigned int i, j;
  233. int ret;
  234. unsigned char *c1, *c2;
  235. if (Cur_Head->lng_quick) {
  236. if (nat_lng == PORT_LONG) {
  237. ret = dig_fread(buf, PORT_LONG, cnt, fp);
  238. if (ret != (int) cnt)
  239. return 0;
  240. }
  241. else {
  242. /* read into buffer */
  243. buf_alloc(cnt * PORT_LONG);
  244. ret = dig_fread(buffer, PORT_LONG, cnt, fp);
  245. if (ret != (int) cnt)
  246. return 0;
  247. /* set buffer to zero (positive numbers) */
  248. memset(buf, 0, cnt * sizeof(long));
  249. /* read from buffer in changed order */
  250. c1 = (unsigned char *)buffer;
  251. c2 = (unsigned char *)buf;
  252. for (i = 0; i < cnt; i++) {
  253. /* set to FF if the value is negative */
  254. if (lng_order == ENDIAN_LITTLE) {
  255. if (c1[PORT_LONG - 1] & 0x80)
  256. memset(c2, 0xff, sizeof(long));
  257. }
  258. else {
  259. if (c1[0] & 0x80)
  260. memset(c2, 0xff, sizeof(long));
  261. }
  262. if (lng_order == ENDIAN_LITTLE)
  263. memcpy(c2, c1, PORT_LONG);
  264. else
  265. memcpy(c2 + nat_lng - PORT_LONG, c1, PORT_LONG);
  266. c1 += PORT_LONG;
  267. c2 += sizeof(long);
  268. }
  269. }
  270. }
  271. else {
  272. /* read into buffer */
  273. buf_alloc(cnt * PORT_LONG);
  274. ret = dig_fread(buffer, PORT_LONG, cnt, fp);
  275. if (ret != (int) cnt)
  276. return 0;
  277. /* set buffer to zero (positive numbers) */
  278. memset(buf, 0, cnt * sizeof(long));
  279. /* read from buffer in changed order */
  280. c1 = (unsigned char *)buffer;
  281. c2 = (unsigned char *)buf;
  282. for (i = 0; i < cnt; i++) {
  283. /* set to FF if the value is negative */
  284. if (Cur_Head->byte_order == ENDIAN_LITTLE) {
  285. if (c1[PORT_LONG - 1] & 0x80)
  286. memset(c2, 0xff, sizeof(long));
  287. }
  288. else {
  289. if (c1[0] & 0x80)
  290. memset(c2, 0xff, sizeof(long));
  291. }
  292. for (j = 0; j < PORT_LONG; j++)
  293. c2[Cur_Head->lng_cnvrt[j]] = c1[j];
  294. c1 += PORT_LONG;
  295. c2 += sizeof(long);
  296. }
  297. }
  298. return 1;
  299. }
  300. /*!
  301. \brief Read integers from the Portable Vector Format
  302. These routines must handle any type size conversions between the
  303. portable format and the native machine.
  304. \param[out] buf data buffer
  305. \param cnt number of members
  306. \param fp pointer to struct gvfile
  307. \return 0 error
  308. \return 1 OK
  309. */
  310. int dig__fread_port_I(int *buf, size_t cnt, struct gvfile * fp)
  311. {
  312. unsigned int i, j;
  313. int ret;
  314. unsigned char *c1, *c2;
  315. if (Cur_Head->int_quick) {
  316. if (nat_int == PORT_INT) {
  317. ret = dig_fread(buf, PORT_INT, cnt, fp);
  318. if (ret != (int) cnt)
  319. return 0;
  320. }
  321. else {
  322. /* read into buffer */
  323. buf_alloc(cnt * PORT_INT);
  324. ret = dig_fread(buffer, PORT_INT, cnt, fp);
  325. if (ret != (int) cnt)
  326. return 0;
  327. /* set buffer to zero (positive numbers) */
  328. memset(buf, 0, cnt * sizeof(int));
  329. /* read from buffer in changed order */
  330. c1 = (unsigned char *)buffer;
  331. c2 = (unsigned char *)buf;
  332. for (i = 0; i < cnt; i++) {
  333. /* set to FF if the value is negative */
  334. if (int_order == ENDIAN_LITTLE) {
  335. if (c1[PORT_INT - 1] & 0x80)
  336. memset(c2, 0xff, sizeof(int));
  337. }
  338. else {
  339. if (c1[0] & 0x80)
  340. memset(c2, 0xff, sizeof(int));
  341. }
  342. if (int_order == ENDIAN_LITTLE)
  343. memcpy(c2, c1, PORT_INT);
  344. else
  345. memcpy(c2 + nat_int - PORT_INT, c1, PORT_INT);
  346. c1 += PORT_INT;
  347. c2 += sizeof(int);
  348. }
  349. }
  350. }
  351. else {
  352. /* read into buffer */
  353. buf_alloc(cnt * PORT_INT);
  354. ret = dig_fread(buffer, PORT_INT, cnt, fp);
  355. if (ret != (int) cnt)
  356. return 0;
  357. /* set buffer to zero (positive numbers) */
  358. memset(buf, 0, cnt * sizeof(int));
  359. /* read from buffer in changed order */
  360. c1 = (unsigned char *)buffer;
  361. c2 = (unsigned char *)buf;
  362. for (i = 0; i < cnt; i++) {
  363. /* set to FF if the value is negative */
  364. if (Cur_Head->byte_order == ENDIAN_LITTLE) {
  365. if (c1[PORT_INT - 1] & 0x80)
  366. memset(c2, 0xff, sizeof(int));
  367. }
  368. else {
  369. if (c1[0] & 0x80)
  370. memset(c2, 0xff, sizeof(int));
  371. }
  372. for (j = 0; j < PORT_INT; j++)
  373. c2[Cur_Head->int_cnvrt[j]] = c1[j];
  374. c1 += PORT_INT;
  375. c2 += sizeof(int);
  376. }
  377. }
  378. return 1;
  379. }
  380. /*!
  381. \brief Read shorts from the Portable Vector Format
  382. These routines must handle any type size conversions between the
  383. portable format and the native machine.
  384. \param[out] buf data buffer
  385. \param cnt number of members
  386. \param fp pointer to struct gvfile
  387. \return 0 error
  388. \return 1 OK
  389. */
  390. int dig__fread_port_S(short *buf, size_t cnt, struct gvfile * fp)
  391. {
  392. unsigned int i, j;
  393. int ret;
  394. unsigned char *c1, *c2;
  395. if (Cur_Head->shrt_quick) {
  396. if (nat_shrt == PORT_SHORT) {
  397. ret = dig_fread(buf, PORT_SHORT, cnt, fp);
  398. if (ret != (int) cnt)
  399. return 0;
  400. }
  401. else {
  402. /* read into buffer */
  403. buf_alloc(cnt * PORT_SHORT);
  404. if (0 >= (ret = dig_fread(buffer, PORT_SHORT, cnt, fp)))
  405. if (ret != (int) cnt)
  406. return 0;
  407. /* set buffer to zero (positive numbers) */
  408. memset(buf, 0, cnt * sizeof(short));
  409. /* read from buffer in changed order */
  410. c1 = (unsigned char *)buffer;
  411. c2 = (unsigned char *)buf;
  412. for (i = 0; i < cnt; i++) {
  413. /* set to FF if the value is negative */
  414. if (shrt_order == ENDIAN_LITTLE) {
  415. if (c1[PORT_SHORT - 1] & 0x80)
  416. memset(c2, 0xff, sizeof(short));
  417. }
  418. else {
  419. if (c1[0] & 0x80)
  420. memset(c2, 0xff, sizeof(short));
  421. }
  422. if (shrt_order == ENDIAN_LITTLE)
  423. memcpy(c2, c1, PORT_SHORT);
  424. else
  425. memcpy(c2 + nat_shrt - PORT_SHORT, c1, PORT_SHORT);
  426. c1 += PORT_SHORT;
  427. c2 += sizeof(short);
  428. }
  429. }
  430. }
  431. else {
  432. /* read into buffer */
  433. buf_alloc(cnt * PORT_SHORT);
  434. ret = dig_fread(buffer, PORT_SHORT, cnt, fp);
  435. if (ret != (int) cnt)
  436. return 0;
  437. /* set buffer to zero (positive numbers) */
  438. memset(buf, 0, cnt * sizeof(short));
  439. /* read from buffer in changed order */
  440. c1 = (unsigned char *)buffer;
  441. c2 = (unsigned char *)buf;
  442. for (i = 0; i < cnt; i++) {
  443. /* set to FF if the value is negative */
  444. if (Cur_Head->byte_order == ENDIAN_LITTLE) {
  445. if (c1[PORT_SHORT - 1] & 0x80)
  446. memset(c2, 0xff, sizeof(short));
  447. }
  448. else {
  449. if (c1[0] & 0x80)
  450. memset(c2, 0xff, sizeof(short));
  451. }
  452. for (j = 0; j < PORT_SHORT; j++)
  453. c2[Cur_Head->shrt_cnvrt[j]] = c1[j];
  454. c1 += PORT_SHORT;
  455. c2 += sizeof(short);
  456. }
  457. }
  458. return 1;
  459. }
  460. /*!
  461. \brief Read chars from the Portable Vector Format
  462. These routines must handle any type size conversions between the
  463. portable format and the native machine.
  464. \param[out] buf data buffer
  465. \param cnt number of members
  466. \param fp pointer to gvfile structure
  467. \return 0 error
  468. \return 1 OK
  469. */
  470. int dig__fread_port_C(char *buf, size_t cnt, struct gvfile * fp)
  471. {
  472. int ret;
  473. ret = dig_fread(buf, PORT_CHAR, cnt, fp);
  474. if (ret != (int) cnt)
  475. return 0;
  476. return 1;
  477. }
  478. /*!
  479. \brief Read plus_t from the Portable Vector Format
  480. These routines must handle any type size conversions between the
  481. portable format and the native machine.
  482. plus_t is defined as int so we only retype pointer and use int
  483. function.
  484. \param[out] buf data buffer
  485. \param cnt number of members
  486. \param fp pointer to struct gvfile
  487. \return 0 error
  488. \return 1 OK
  489. */
  490. int dig__fread_port_P(plus_t * buf, size_t cnt, struct gvfile * fp)
  491. {
  492. int *ibuf;
  493. ibuf = (int *)buf;
  494. return (dig__fread_port_I(ibuf, cnt, fp));
  495. }
  496. /*!
  497. \brief Write doubles to the Portable Vector Format
  498. These routines must handle any type size conversions between the
  499. portable format and the native machine.
  500. \param buf data buffer
  501. \param cnt number of members
  502. \param[in,out] fp pointer to struct gvfile
  503. \return 0 error
  504. \return 1 OK
  505. */
  506. int dig__fwrite_port_D(const double *buf,
  507. size_t cnt, struct gvfile * fp)
  508. {
  509. unsigned int i, j;
  510. unsigned char *c1, *c2;
  511. if (Cur_Head->dbl_quick) {
  512. if (dig_fwrite(buf, PORT_DOUBLE, cnt, fp) == cnt)
  513. return 1;
  514. }
  515. else {
  516. buf_alloc(cnt * PORT_DOUBLE);
  517. c1 = (unsigned char *)buf;
  518. c2 = (unsigned char *)buffer;
  519. for (i = 0; i < cnt; i++) {
  520. for (j = 0; j < PORT_DOUBLE; j++)
  521. c2[j] = c1[Cur_Head->dbl_cnvrt[j]];
  522. c1 += sizeof(double);
  523. c2 += PORT_DOUBLE;
  524. }
  525. if (dig_fwrite(buffer, PORT_DOUBLE, cnt, fp) == cnt)
  526. return 1;
  527. }
  528. return 0;
  529. }
  530. /*!
  531. \brief Write floats to the Portable Vector Format
  532. These routines must handle any type size conversions between the
  533. portable format and the native machine.
  534. \param buf data buffer
  535. \param cnt number of members
  536. \param[in,out] fp pointer to struct gvfile
  537. \return 0 error
  538. \return 1 OK
  539. */
  540. int dig__fwrite_port_F(const float *buf,
  541. size_t cnt, struct gvfile * fp)
  542. {
  543. unsigned int i, j;
  544. unsigned char *c1, *c2;
  545. if (Cur_Head->flt_quick) {
  546. if (dig_fwrite(buf, PORT_FLOAT, cnt, fp) == cnt)
  547. return 1;
  548. }
  549. else {
  550. buf_alloc(cnt * PORT_FLOAT);
  551. c1 = (unsigned char *)buf;
  552. c2 = (unsigned char *)buffer;
  553. for (i = 0; i < cnt; i++) {
  554. for (j = 0; j < PORT_FLOAT; j++)
  555. c2[j] = c1[Cur_Head->flt_cnvrt[j]];
  556. c1 += sizeof(float);
  557. c2 += PORT_FLOAT;
  558. }
  559. if (dig_fwrite(buffer, PORT_FLOAT, cnt, fp) == cnt)
  560. return 1;
  561. }
  562. return 0;
  563. }
  564. /*!
  565. \brief Write off_ts to the Portable Vector Format
  566. These routines must handle any type size conversions between the
  567. portable format and the native machine.
  568. \param buf data buffer
  569. \param cnt number of members
  570. \param[in,out] fp pointer to struct gvfile
  571. \return 0 error
  572. \return 1 OK
  573. */
  574. int dig__fwrite_port_O(const off_t *buf,
  575. size_t cnt, struct gvfile * fp, size_t port_off_t_size)
  576. {
  577. unsigned int i, j;
  578. unsigned char *c1, *c2;
  579. if (Cur_Head->off_t_quick) {
  580. if (nat_off_t == port_off_t_size) {
  581. if (dig_fwrite(buf, port_off_t_size, cnt, fp) == cnt)
  582. return 1;
  583. }
  584. else if (nat_off_t > port_off_t_size) {
  585. buf_alloc(cnt * port_off_t_size);
  586. c1 = (unsigned char *)buf;
  587. c2 = (unsigned char *)buffer;
  588. for (i = 0; i < cnt; i++) {
  589. if (off_t_order == ENDIAN_LITTLE)
  590. memcpy(c2, c1, port_off_t_size);
  591. else
  592. memcpy(c2, c1 + nat_off_t - port_off_t_size, port_off_t_size);
  593. c1 += sizeof(off_t);
  594. c2 += port_off_t_size;
  595. }
  596. if (dig_fwrite(buffer, port_off_t_size, cnt, fp) == cnt)
  597. return 1;
  598. }
  599. else if (nat_off_t < port_off_t_size) {
  600. /* should never happen */
  601. G_fatal_error("Vector exceeds supported file size limit");
  602. }
  603. }
  604. else {
  605. if (nat_off_t >= port_off_t_size) {
  606. buf_alloc(cnt * port_off_t_size);
  607. c1 = (unsigned char *)buf;
  608. c2 = (unsigned char *)buffer;
  609. for (i = 0; i < cnt; i++) {
  610. for (j = 0; j < port_off_t_size; j++)
  611. c2[j] = c1[Cur_Head->off_t_cnvrt[j]];
  612. c1 += sizeof(off_t);
  613. c2 += port_off_t_size;
  614. }
  615. if (dig_fwrite(buffer, port_off_t_size, cnt, fp) == cnt)
  616. return 1;
  617. }
  618. else if (nat_off_t < port_off_t_size) {
  619. /* should never happen */
  620. G_fatal_error(_("Vector exceeds supported file size limit"));
  621. }
  622. }
  623. return 0;
  624. }
  625. /*!
  626. \brief Write longs to the Portable Vector Format
  627. These routines must handle any type size conversions between the
  628. portable format and the native machine.
  629. \param buf data buffer
  630. \param cnt number of members
  631. \param[in,out] fp pointer to struct gvfile
  632. \return 0 error
  633. \return 1 OK
  634. */
  635. int dig__fwrite_port_L(const long *buf,
  636. size_t cnt, struct gvfile * fp)
  637. {
  638. unsigned int i, j;
  639. unsigned char *c1, *c2;
  640. if (Cur_Head->lng_quick) {
  641. if (nat_lng == PORT_LONG) {
  642. if (dig_fwrite(buf, PORT_LONG, cnt, fp) == cnt)
  643. return 1;
  644. }
  645. else {
  646. buf_alloc(cnt * PORT_LONG);
  647. c1 = (unsigned char *)buf;
  648. c2 = (unsigned char *)buffer;
  649. for (i = 0; i < cnt; i++) {
  650. if (lng_order == ENDIAN_LITTLE)
  651. memcpy(c2, c1, PORT_LONG);
  652. else
  653. memcpy(c2, c1 + nat_lng - PORT_LONG, PORT_LONG);
  654. c1 += sizeof(long);
  655. c2 += PORT_LONG;
  656. }
  657. if (dig_fwrite(buffer, PORT_LONG, cnt, fp) == cnt)
  658. return 1;
  659. }
  660. }
  661. else {
  662. buf_alloc(cnt * PORT_LONG);
  663. c1 = (unsigned char *)buf;
  664. c2 = (unsigned char *)buffer;
  665. for (i = 0; i < cnt; i++) {
  666. for (j = 0; j < PORT_LONG; j++)
  667. c2[j] = c1[Cur_Head->lng_cnvrt[j]];
  668. c1 += sizeof(long);
  669. c2 += PORT_LONG;
  670. }
  671. if (dig_fwrite(buffer, PORT_LONG, cnt, fp) == cnt)
  672. return 1;
  673. }
  674. return 0;
  675. }
  676. /*!
  677. \brief Write integers to the Portable Vector Format
  678. These routines must handle any type size conversions between the
  679. portable format and the native machine.
  680. \param buf data buffer
  681. \param cnt number of members
  682. \param[in,out] fp pointer to struct gvfile
  683. \return 0 error
  684. \return 1 OK
  685. */
  686. int dig__fwrite_port_I(const int *buf,
  687. size_t cnt, struct gvfile * fp)
  688. {
  689. unsigned int i, j;
  690. unsigned char *c1, *c2;
  691. if (Cur_Head->int_quick) {
  692. if (nat_int == PORT_INT) {
  693. if (dig_fwrite(buf, PORT_INT, cnt, fp) == cnt)
  694. return 1;
  695. }
  696. else {
  697. buf_alloc(cnt * PORT_INT);
  698. c1 = (unsigned char *)buf;
  699. c2 = (unsigned char *)buffer;
  700. for (i = 0; i < cnt; i++) {
  701. if (int_order == ENDIAN_LITTLE)
  702. memcpy(c2, c1, PORT_INT);
  703. else
  704. memcpy(c2, c1 + nat_int - PORT_INT, PORT_INT);
  705. c1 += sizeof(int);
  706. c2 += PORT_INT;
  707. }
  708. if (dig_fwrite(buffer, PORT_INT, cnt, fp) == cnt)
  709. return 1;
  710. }
  711. }
  712. else {
  713. buf_alloc(cnt * PORT_INT);
  714. c1 = (unsigned char *)buf;
  715. c2 = (unsigned char *)buffer;
  716. for (i = 0; i < cnt; i++) {
  717. for (j = 0; j < PORT_INT; j++)
  718. c2[j] = c1[Cur_Head->int_cnvrt[j]];
  719. c1 += sizeof(int);
  720. c2 += PORT_INT;
  721. }
  722. if (dig_fwrite(buffer, PORT_INT, cnt, fp) == cnt)
  723. return 1;
  724. }
  725. return 0;
  726. }
  727. /*!
  728. \brief Write shorts to the Portable Vector Format
  729. These routines must handle any type size conversions between the
  730. portable format and the native machine.
  731. \param buf data buffer
  732. \param cnt number of members
  733. \param[in,out] fp pointer to struct gvfile
  734. \return 0 error
  735. \return 1 OK
  736. */
  737. int dig__fwrite_port_S(const short *buf,
  738. size_t cnt, struct gvfile * fp)
  739. {
  740. unsigned int i, j;
  741. unsigned char *c1, *c2;
  742. if (Cur_Head->shrt_quick) {
  743. if (nat_shrt == PORT_SHORT) {
  744. if (dig_fwrite(buf, PORT_SHORT, cnt, fp) == cnt)
  745. return 1;
  746. }
  747. else {
  748. buf_alloc(cnt * PORT_SHORT);
  749. c1 = (unsigned char *)buf;
  750. c2 = (unsigned char *)buffer;
  751. for (i = 0; i < cnt; i++) {
  752. if (shrt_order == ENDIAN_LITTLE)
  753. memcpy(c2, c1, PORT_SHORT);
  754. else
  755. memcpy(c2, c1 + nat_shrt - PORT_SHORT, PORT_SHORT);
  756. c1 += sizeof(short);
  757. c2 += PORT_SHORT;
  758. }
  759. if (dig_fwrite(buffer, PORT_SHORT, cnt, fp) == cnt)
  760. return 1;
  761. }
  762. }
  763. else {
  764. buf_alloc(cnt * PORT_SHORT);
  765. c1 = (unsigned char *)buf;
  766. c2 = (unsigned char *)buffer;
  767. for (i = 0; i < cnt; i++) {
  768. for (j = 0; j < PORT_SHORT; j++)
  769. c2[j] = c1[Cur_Head->shrt_cnvrt[j]];
  770. c1 += sizeof(short);
  771. c2 += PORT_SHORT;
  772. }
  773. if (dig_fwrite(buffer, PORT_SHORT, cnt, fp) == cnt)
  774. return 1;
  775. }
  776. return 0;
  777. }
  778. /*!
  779. \brief Write plus_t to the Portable Vector Format
  780. These routines must handle any type size conversions between the
  781. portable format and the native machine.
  782. \param buf data buffer
  783. \param cnt number of members
  784. \param[in,out] fp pointer to struct gvfile
  785. \return 0 error
  786. \return 1 OK
  787. */
  788. int dig__fwrite_port_P(const plus_t * buf,
  789. size_t cnt, struct gvfile * fp)
  790. {
  791. return (dig__fwrite_port_I((int *)buf, cnt, fp));
  792. }
  793. /*!
  794. \brief Write chars to the Portable Vector Format
  795. These routines must handle any type size conversions between the
  796. portable format and the native machine.
  797. \param buf data buffer
  798. \param cnt number of members
  799. \param[in,out] fp pointer to struct gvfile
  800. \return 0 error
  801. \return 1 OK
  802. */
  803. int dig__fwrite_port_C(const char *buf,
  804. size_t cnt, struct gvfile * fp)
  805. {
  806. if (dig_fwrite(buf, PORT_CHAR, cnt, fp) == cnt)
  807. return 1;
  808. return 0;
  809. }
  810. /*!
  811. \brief Set Port_info structure to byte order of file
  812. \param port pointer to Port_info structure
  813. \param byte_order ENDIAN_BIG or ENDIAN_LITTLE
  814. */
  815. void dig_init_portable(struct Port_info *port, int byte_order)
  816. {
  817. unsigned int i;
  818. port_init();
  819. port->byte_order = byte_order;
  820. /* double */
  821. if (port->byte_order == dbl_order)
  822. port->dbl_quick = TRUE;
  823. else
  824. port->dbl_quick = FALSE;
  825. for (i = 0; i < PORT_DOUBLE; i++) {
  826. if (port->byte_order == ENDIAN_BIG)
  827. port->dbl_cnvrt[i] = dbl_cnvrt[i];
  828. else
  829. port->dbl_cnvrt[i] = dbl_cnvrt[PORT_DOUBLE - i - 1];
  830. }
  831. /* float */
  832. if (port->byte_order == flt_order)
  833. port->flt_quick = TRUE;
  834. else
  835. port->flt_quick = FALSE;
  836. for (i = 0; i < PORT_FLOAT; i++) {
  837. if (port->byte_order == ENDIAN_BIG)
  838. port->flt_cnvrt[i] = flt_cnvrt[i];
  839. else
  840. port->flt_cnvrt[i] = flt_cnvrt[PORT_FLOAT - i - 1];
  841. }
  842. /* long */
  843. if (port->byte_order == lng_order)
  844. port->lng_quick = TRUE;
  845. else
  846. port->lng_quick = FALSE;
  847. for (i = 0; i < PORT_LONG; i++) {
  848. if (port->byte_order == ENDIAN_BIG)
  849. port->lng_cnvrt[i] = lng_cnvrt[i];
  850. else
  851. port->lng_cnvrt[i] = lng_cnvrt[PORT_LONG - i - 1];
  852. }
  853. /* int */
  854. if (port->byte_order == int_order)
  855. port->int_quick = TRUE;
  856. else
  857. port->int_quick = FALSE;
  858. for (i = 0; i < PORT_INT; i++) {
  859. if (port->byte_order == ENDIAN_BIG)
  860. port->int_cnvrt[i] = int_cnvrt[i];
  861. else
  862. port->int_cnvrt[i] = int_cnvrt[PORT_INT - i - 1];
  863. }
  864. /* short */
  865. if (port->byte_order == shrt_order)
  866. port->shrt_quick = TRUE;
  867. else
  868. port->shrt_quick = FALSE;
  869. for (i = 0; i < PORT_SHORT; i++) {
  870. if (port->byte_order == ENDIAN_BIG)
  871. port->shrt_cnvrt[i] = shrt_cnvrt[i];
  872. else
  873. port->shrt_cnvrt[i] = shrt_cnvrt[PORT_SHORT - i - 1];
  874. }
  875. /* off_t */
  876. if (port->byte_order == off_t_order)
  877. port->off_t_quick = TRUE;
  878. else
  879. port->off_t_quick = FALSE;
  880. for (i = 0; i < nat_off_t; i++) {
  881. if (port->byte_order == ENDIAN_BIG)
  882. port->off_t_cnvrt[i] = off_t_cnvrt[i];
  883. else
  884. port->off_t_cnvrt[i] = off_t_cnvrt[nat_off_t - i - 1];
  885. }
  886. return;
  887. }
  888. /*!
  889. \brief Set current Port_info structure
  890. \param port pointer to Port_info structure
  891. \return 0
  892. */
  893. int dig_set_cur_port(struct Port_info *port)
  894. {
  895. Cur_Head = port;
  896. return 0;
  897. }
  898. /*!
  899. \brief Get byte order
  900. \return ENDIAN_LITTLE
  901. \return ENDIAN_BIG
  902. */
  903. int dig__byte_order_out()
  904. {
  905. if (dbl_order == ENDIAN_LITTLE)
  906. return (ENDIAN_LITTLE);
  907. else
  908. return (ENDIAN_BIG);
  909. }