portable.c 24 KB

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