portable.c 24 KB

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