portable.c 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028
  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. \param port_off_t_size
  572. \return 0 error
  573. \return 1 OK
  574. */
  575. int dig__fwrite_port_O(const off_t *buf,
  576. size_t cnt, struct gvfile * fp, size_t port_off_t_size)
  577. {
  578. unsigned int i, j;
  579. unsigned char *c1, *c2;
  580. if (Cur_Head->off_t_quick) {
  581. if (nat_off_t == port_off_t_size) {
  582. if (dig_fwrite(buf, port_off_t_size, cnt, fp) == cnt)
  583. return 1;
  584. }
  585. else if (nat_off_t > port_off_t_size) {
  586. buf_alloc(cnt * port_off_t_size);
  587. c1 = (unsigned char *)buf;
  588. c2 = (unsigned char *)buffer;
  589. for (i = 0; i < cnt; i++) {
  590. if (off_t_order == ENDIAN_LITTLE)
  591. memcpy(c2, c1, port_off_t_size);
  592. else
  593. memcpy(c2, c1 + nat_off_t - port_off_t_size, port_off_t_size);
  594. c1 += sizeof(off_t);
  595. c2 += port_off_t_size;
  596. }
  597. if (dig_fwrite(buffer, port_off_t_size, cnt, fp) == cnt)
  598. return 1;
  599. }
  600. else if (nat_off_t < port_off_t_size) {
  601. /* should never happen */
  602. G_fatal_error("Vector exceeds supported file size limit");
  603. }
  604. }
  605. else {
  606. if (nat_off_t >= port_off_t_size) {
  607. buf_alloc(cnt * port_off_t_size);
  608. c1 = (unsigned char *)buf;
  609. c2 = (unsigned char *)buffer;
  610. for (i = 0; i < cnt; i++) {
  611. for (j = 0; j < port_off_t_size; j++)
  612. c2[j] = c1[Cur_Head->off_t_cnvrt[j]];
  613. c1 += sizeof(off_t);
  614. c2 += port_off_t_size;
  615. }
  616. if (dig_fwrite(buffer, port_off_t_size, cnt, fp) == cnt)
  617. return 1;
  618. }
  619. else if (nat_off_t < port_off_t_size) {
  620. /* should never happen */
  621. G_fatal_error(_("Vector exceeds supported file size limit"));
  622. }
  623. }
  624. return 0;
  625. }
  626. /*!
  627. \brief Write longs to the Portable Vector Format
  628. These routines must handle any type size conversions between the
  629. portable format and the native machine.
  630. \param buf data buffer
  631. \param cnt number of members
  632. \param[in,out] fp pointer to struct gvfile
  633. \return 0 error
  634. \return 1 OK
  635. */
  636. int dig__fwrite_port_L(const long *buf,
  637. size_t cnt, struct gvfile * fp)
  638. {
  639. unsigned int i, j;
  640. unsigned char *c1, *c2;
  641. if (Cur_Head->lng_quick) {
  642. if (nat_lng == PORT_LONG) {
  643. if (dig_fwrite(buf, PORT_LONG, cnt, fp) == cnt)
  644. return 1;
  645. }
  646. else {
  647. buf_alloc(cnt * PORT_LONG);
  648. c1 = (unsigned char *)buf;
  649. c2 = (unsigned char *)buffer;
  650. for (i = 0; i < cnt; i++) {
  651. if (lng_order == ENDIAN_LITTLE)
  652. memcpy(c2, c1, PORT_LONG);
  653. else
  654. memcpy(c2, c1 + nat_lng - PORT_LONG, PORT_LONG);
  655. c1 += sizeof(long);
  656. c2 += PORT_LONG;
  657. }
  658. if (dig_fwrite(buffer, PORT_LONG, cnt, fp) == cnt)
  659. return 1;
  660. }
  661. }
  662. else {
  663. buf_alloc(cnt * PORT_LONG);
  664. c1 = (unsigned char *)buf;
  665. c2 = (unsigned char *)buffer;
  666. for (i = 0; i < cnt; i++) {
  667. for (j = 0; j < PORT_LONG; j++)
  668. c2[j] = c1[Cur_Head->lng_cnvrt[j]];
  669. c1 += sizeof(long);
  670. c2 += PORT_LONG;
  671. }
  672. if (dig_fwrite(buffer, PORT_LONG, cnt, fp) == cnt)
  673. return 1;
  674. }
  675. return 0;
  676. }
  677. /*!
  678. \brief Write integers to the Portable Vector Format
  679. These routines must handle any type size conversions between the
  680. portable format and the native machine.
  681. \param buf data buffer
  682. \param cnt number of members
  683. \param[in,out] fp pointer to struct gvfile
  684. \return 0 error
  685. \return 1 OK
  686. */
  687. int dig__fwrite_port_I(const int *buf,
  688. size_t cnt, struct gvfile * fp)
  689. {
  690. unsigned int i, j;
  691. unsigned char *c1, *c2;
  692. if (Cur_Head->int_quick) {
  693. if (nat_int == PORT_INT) {
  694. if (dig_fwrite(buf, PORT_INT, cnt, fp) == cnt)
  695. return 1;
  696. }
  697. else {
  698. buf_alloc(cnt * PORT_INT);
  699. c1 = (unsigned char *)buf;
  700. c2 = (unsigned char *)buffer;
  701. for (i = 0; i < cnt; i++) {
  702. if (int_order == ENDIAN_LITTLE)
  703. memcpy(c2, c1, PORT_INT);
  704. else
  705. memcpy(c2, c1 + nat_int - PORT_INT, PORT_INT);
  706. c1 += sizeof(int);
  707. c2 += PORT_INT;
  708. }
  709. if (dig_fwrite(buffer, PORT_INT, cnt, fp) == cnt)
  710. return 1;
  711. }
  712. }
  713. else {
  714. buf_alloc(cnt * PORT_INT);
  715. c1 = (unsigned char *)buf;
  716. c2 = (unsigned char *)buffer;
  717. for (i = 0; i < cnt; i++) {
  718. for (j = 0; j < PORT_INT; j++)
  719. c2[j] = c1[Cur_Head->int_cnvrt[j]];
  720. c1 += sizeof(int);
  721. c2 += PORT_INT;
  722. }
  723. if (dig_fwrite(buffer, PORT_INT, cnt, fp) == cnt)
  724. return 1;
  725. }
  726. return 0;
  727. }
  728. /*!
  729. \brief Write shorts to the Portable Vector Format
  730. These routines must handle any type size conversions between the
  731. portable format and the native machine.
  732. \param buf data buffer
  733. \param cnt number of members
  734. \param[in,out] fp pointer to struct gvfile
  735. \return 0 error
  736. \return 1 OK
  737. */
  738. int dig__fwrite_port_S(const short *buf,
  739. size_t cnt, struct gvfile * fp)
  740. {
  741. unsigned int i, j;
  742. unsigned char *c1, *c2;
  743. if (Cur_Head->shrt_quick) {
  744. if (nat_shrt == PORT_SHORT) {
  745. if (dig_fwrite(buf, PORT_SHORT, cnt, fp) == cnt)
  746. return 1;
  747. }
  748. else {
  749. buf_alloc(cnt * PORT_SHORT);
  750. c1 = (unsigned char *)buf;
  751. c2 = (unsigned char *)buffer;
  752. for (i = 0; i < cnt; i++) {
  753. if (shrt_order == ENDIAN_LITTLE)
  754. memcpy(c2, c1, PORT_SHORT);
  755. else
  756. memcpy(c2, c1 + nat_shrt - PORT_SHORT, PORT_SHORT);
  757. c1 += sizeof(short);
  758. c2 += PORT_SHORT;
  759. }
  760. if (dig_fwrite(buffer, PORT_SHORT, cnt, fp) == cnt)
  761. return 1;
  762. }
  763. }
  764. else {
  765. buf_alloc(cnt * PORT_SHORT);
  766. c1 = (unsigned char *)buf;
  767. c2 = (unsigned char *)buffer;
  768. for (i = 0; i < cnt; i++) {
  769. for (j = 0; j < PORT_SHORT; j++)
  770. c2[j] = c1[Cur_Head->shrt_cnvrt[j]];
  771. c1 += sizeof(short);
  772. c2 += PORT_SHORT;
  773. }
  774. if (dig_fwrite(buffer, PORT_SHORT, cnt, fp) == cnt)
  775. return 1;
  776. }
  777. return 0;
  778. }
  779. /*!
  780. \brief Write plus_t to the Portable Vector Format
  781. These routines must handle any type size conversions between the
  782. portable format and the native machine.
  783. \param buf data buffer
  784. \param cnt number of members
  785. \param[in,out] fp pointer to struct gvfile
  786. \return 0 error
  787. \return 1 OK
  788. */
  789. int dig__fwrite_port_P(const plus_t * buf,
  790. size_t cnt, struct gvfile * fp)
  791. {
  792. return (dig__fwrite_port_I((int *)buf, cnt, fp));
  793. }
  794. /*!
  795. \brief Write chars to the Portable Vector Format
  796. These routines must handle any type size conversions between the
  797. portable format and the native machine.
  798. \param buf data buffer
  799. \param cnt number of members
  800. \param[in,out] fp pointer to struct gvfile
  801. \return 0 error
  802. \return 1 OK
  803. */
  804. int dig__fwrite_port_C(const char *buf,
  805. size_t cnt, struct gvfile * fp)
  806. {
  807. if (dig_fwrite(buf, PORT_CHAR, cnt, fp) == cnt)
  808. return 1;
  809. return 0;
  810. }
  811. /*!
  812. \brief Set Port_info structure to byte order of file
  813. \param port pointer to Port_info structure
  814. \param byte_order ENDIAN_BIG or ENDIAN_LITTLE
  815. */
  816. void dig_init_portable(struct Port_info *port, int byte_order)
  817. {
  818. unsigned int i;
  819. port_init();
  820. port->byte_order = byte_order;
  821. /* double */
  822. if (port->byte_order == dbl_order)
  823. port->dbl_quick = TRUE;
  824. else
  825. port->dbl_quick = FALSE;
  826. for (i = 0; i < PORT_DOUBLE; i++) {
  827. if (port->byte_order == ENDIAN_BIG)
  828. port->dbl_cnvrt[i] = dbl_cnvrt[i];
  829. else
  830. port->dbl_cnvrt[i] = dbl_cnvrt[PORT_DOUBLE - i - 1];
  831. }
  832. /* float */
  833. if (port->byte_order == flt_order)
  834. port->flt_quick = TRUE;
  835. else
  836. port->flt_quick = FALSE;
  837. for (i = 0; i < PORT_FLOAT; i++) {
  838. if (port->byte_order == ENDIAN_BIG)
  839. port->flt_cnvrt[i] = flt_cnvrt[i];
  840. else
  841. port->flt_cnvrt[i] = flt_cnvrt[PORT_FLOAT - i - 1];
  842. }
  843. /* long */
  844. if (port->byte_order == lng_order)
  845. port->lng_quick = TRUE;
  846. else
  847. port->lng_quick = FALSE;
  848. for (i = 0; i < PORT_LONG; i++) {
  849. if (port->byte_order == ENDIAN_BIG)
  850. port->lng_cnvrt[i] = lng_cnvrt[i];
  851. else
  852. port->lng_cnvrt[i] = lng_cnvrt[PORT_LONG - i - 1];
  853. }
  854. /* int */
  855. if (port->byte_order == int_order)
  856. port->int_quick = TRUE;
  857. else
  858. port->int_quick = FALSE;
  859. for (i = 0; i < PORT_INT; i++) {
  860. if (port->byte_order == ENDIAN_BIG)
  861. port->int_cnvrt[i] = int_cnvrt[i];
  862. else
  863. port->int_cnvrt[i] = int_cnvrt[PORT_INT - i - 1];
  864. }
  865. /* short */
  866. if (port->byte_order == shrt_order)
  867. port->shrt_quick = TRUE;
  868. else
  869. port->shrt_quick = FALSE;
  870. for (i = 0; i < PORT_SHORT; i++) {
  871. if (port->byte_order == ENDIAN_BIG)
  872. port->shrt_cnvrt[i] = shrt_cnvrt[i];
  873. else
  874. port->shrt_cnvrt[i] = shrt_cnvrt[PORT_SHORT - i - 1];
  875. }
  876. /* off_t */
  877. if (port->byte_order == off_t_order)
  878. port->off_t_quick = TRUE;
  879. else
  880. port->off_t_quick = FALSE;
  881. for (i = 0; i < nat_off_t; i++) {
  882. if (port->byte_order == ENDIAN_BIG)
  883. port->off_t_cnvrt[i] = off_t_cnvrt[i];
  884. else
  885. port->off_t_cnvrt[i] = off_t_cnvrt[nat_off_t - i - 1];
  886. }
  887. return;
  888. }
  889. /*!
  890. \brief Set current Port_info structure
  891. \param port pointer to Port_info structure
  892. \return 0
  893. */
  894. int dig_set_cur_port(struct Port_info *port)
  895. {
  896. Cur_Head = port;
  897. return 0;
  898. }
  899. /*!
  900. \brief Get byte order
  901. \return ENDIAN_LITTLE
  902. \return ENDIAN_BIG
  903. */
  904. int dig__byte_order_out()
  905. {
  906. if (dbl_order == ENDIAN_LITTLE)
  907. return (ENDIAN_LITTLE);
  908. else
  909. return (ENDIAN_BIG);
  910. }