PageRenderTime 62ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/src/xdrfile/xdrfile.c

http://mdanalysis.googlecode.com/
C | 2596 lines | 2014 code | 301 blank | 281 comment | 365 complexity | fcdc0b20a600bf12fb169403705dfd7a MD5 | raw file
Possible License(s): LGPL-3.0, CC-BY-3.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
  2. *
  3. * $Id$
  4. *
  5. * Copyright (c) Erik Lindahl, David van der Spoel 2003,2004.
  6. * Coordinate compression (c) by Frans van Hoesel.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public License
  10. * as published by the Free Software Foundation; either version 3
  11. * of the License, or (at your option) any later version.
  12. */
  13. /* Get HAVE_RPC_XDR_H, F77_FUNC from config.h if available */
  14. #ifdef HAVE_CONFIG_H
  15. #include <config.h>
  16. #endif
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <math.h>
  21. #include <limits.h>
  22. /* get fixed-width types if we are using ANSI C99 */
  23. #ifdef HAVE_STDINT_H
  24. # include <stdint.h>
  25. #elif (defined HAVE_INTTYPES_H)
  26. # include <inttypes.h>
  27. #endif
  28. #ifdef HAVE_RPC_XDR_H
  29. # include <rpc/rpc.h>
  30. # include <rpc/xdr.h>
  31. #endif
  32. #include "xdrfile.h"
  33. /* Default FORTRAN name mangling is: lower case name, append underscore */
  34. #ifndef F77_FUNC
  35. #define F77_FUNC(name,NAME) name ## _
  36. #endif
  37. char *exdr_message[exdrNR] = {
  38. "OK",
  39. "Header",
  40. "String",
  41. "Double",
  42. "Integer",
  43. "Float",
  44. "Unsigned integer",
  45. "Compressed 3D coordinate",
  46. "Closing file",
  47. "Magic number",
  48. "Not enough memory",
  49. "End of file",
  50. "File not found"
  51. };
  52. /*
  53. * Declare our own XDR routines statically if no libraries are present.
  54. * Actual implementation is at the end of this file.
  55. *
  56. * We don't want the low-level XDR implementation as part of the Gromacs
  57. * documentation, so skip it for doxygen too...
  58. */
  59. #if (!defined HAVE_RPC_XDR_H && !defined DOXYGEN)
  60. enum xdr_op
  61. {
  62. XDR_ENCODE = 0,
  63. XDR_DECODE = 1,
  64. XDR_FREE = 2
  65. };
  66. /* We need integer types that are guaranteed to be 4 bytes wide.
  67. * If ANSI C99 headers were included they are already defined
  68. * as int32_t and uint32_t. Check, and if not define them ourselves.
  69. * Since it is just our workaround for missing ANSI C99 types, avoid adding
  70. * it to the doxygen documentation.
  71. */
  72. #if !(defined INT32_MAX || defined DOXYGEN)
  73. # if (INT_MAX == 2147483647)
  74. # define int32_t int
  75. # define uint32_t unsigned int
  76. # define INT32_MAX 2147483647
  77. # elif (LONG_MAX == 2147483647)
  78. # define int32_t long
  79. # define uint32_t unsigned long
  80. # define INT32_MAX 2147483647L
  81. # else
  82. # error ERROR: No 32 bit wide integer type found!
  83. # error Use system XDR libraries instead, or update xdrfile.c
  84. # endif
  85. #endif
  86. typedef struct XDR XDR;
  87. struct XDR
  88. {
  89. enum xdr_op x_op;
  90. struct xdr_ops
  91. {
  92. int (*x_getlong) (XDR *__xdrs, int32_t *__lp);
  93. int (*x_putlong) (XDR *__xdrs, int32_t *__lp);
  94. int (*x_getbytes) (XDR *__xdrs, char *__addr, unsigned int __len);
  95. int (*x_putbytes) (XDR *__xdrs, char *__addr, unsigned int __len);
  96. /* two next routines are not 64-bit IO safe - don't use! */
  97. unsigned int (*x_getpostn) (XDR *__xdrs);
  98. int (*x_setpostn) (XDR *__xdrs, unsigned int __pos);
  99. void (*x_destroy) (XDR *__xdrs);
  100. }
  101. *x_ops;
  102. char *x_private;
  103. };
  104. static int xdr_char (XDR *xdrs, char *ip);
  105. static int xdr_u_char (XDR *xdrs, unsigned char *ip);
  106. static int xdr_short (XDR *xdrs, short *ip);
  107. static int xdr_u_short (XDR *xdrs, unsigned short *ip);
  108. static int xdr_int (XDR *xdrs, int *ip);
  109. static int xdr_u_int (XDR *xdrs, unsigned int *ip);
  110. static int xdr_float (XDR *xdrs, float *ip);
  111. static int xdr_double (XDR *xdrs, double *ip);
  112. static int xdr_string (XDR *xdrs, char **ip, unsigned int maxsize);
  113. static int xdr_opaque (XDR *xdrs, char *cp, unsigned int cnt);
  114. static void xdrstdio_create (XDR *xdrs, FILE *fp, enum xdr_op xop);
  115. #define xdr_getpos(xdrs) \
  116. (*(xdrs)->x_ops->x_getpostn)(xdrs)
  117. #define xdr_setpos(xdrs, pos) \
  118. (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
  119. #define xdr_destroy(xdrs) \
  120. do { \
  121. if ((xdrs)->x_ops->x_destroy) \
  122. (*(xdrs)->x_ops->x_destroy)(xdrs); \
  123. } while (0)
  124. #endif /* end of our own XDR declarations */
  125. /** Contents of the abstract XDRFILE data structure.
  126. *
  127. * @internal
  128. *
  129. * This structure is used to provide an XDR file interface that is
  130. * virtual identical to the standard UNIX fopen/fread/fwrite/fclose.
  131. */
  132. struct XDRFILE
  133. {
  134. FILE * fp; /**< pointer to standard C library file handle */
  135. XDR * xdr; /**< pointer to corresponding XDR handle */
  136. char mode; /**< r=read, w=write, a=append */
  137. int * buf1; /**< Buffer for internal use */
  138. int buf1size; /**< Current allocated length of buf1 */
  139. int * buf2; /**< Buffer for internal use */
  140. int buf2size; /**< Current allocated length of buf2 */
  141. };
  142. /*************************************************************
  143. * Implementation of higher-level routines to read/write *
  144. * portable data based on the XDR standard. These should be *
  145. * called from C - see further down for Fortran77 wrappers. *
  146. *************************************************************/
  147. XDRFILE *
  148. xdrfile_open(const char *path, const char *mode)
  149. {
  150. char newmode[5];
  151. enum xdr_op xdrmode;
  152. XDRFILE *xfp;
  153. /* make sure XDR files are opened in binary mode... */
  154. if(*mode=='w' || *mode=='W')
  155. {
  156. sprintf(newmode,"wb+");
  157. xdrmode=XDR_ENCODE;
  158. } else if(*mode == 'a' || *mode == 'A')
  159. {
  160. sprintf(newmode,"ab+");
  161. xdrmode = XDR_ENCODE;
  162. } else if(*mode == 'r' || *mode == 'R')
  163. {
  164. sprintf(newmode,"rb");
  165. xdrmode = XDR_DECODE;
  166. } else /* cannot determine mode */
  167. return NULL;
  168. if((xfp=(XDRFILE *)malloc(sizeof(XDRFILE)))==NULL)
  169. return NULL;
  170. if((xfp->fp=fopen(path,newmode))==NULL)
  171. {
  172. free(xfp);
  173. return NULL;
  174. }
  175. if((xfp->xdr=(XDR *)malloc(sizeof(XDR)))==NULL)
  176. {
  177. fclose(xfp->fp);
  178. free(xfp);
  179. return NULL;
  180. }
  181. xfp->mode=*mode;
  182. xdrstdio_create((XDR *)(xfp->xdr),xfp->fp,xdrmode);
  183. xfp->buf1 = xfp->buf2 = NULL;
  184. xfp->buf1size = xfp->buf2size = 0;
  185. return xfp;
  186. }
  187. int
  188. xdrfile_close(XDRFILE *xfp)
  189. {
  190. int ret=exdrCLOSE;
  191. if(xfp)
  192. {
  193. /* flush and destroy XDR stream */
  194. if(xfp->xdr)
  195. xdr_destroy((XDR *)(xfp->xdr));
  196. free(xfp->xdr);
  197. /* close the file */
  198. ret=fclose(xfp->fp);
  199. if(xfp->buf1size)
  200. free(xfp->buf1);
  201. if(xfp->buf2size)
  202. free(xfp->buf2);
  203. free(xfp);
  204. }
  205. return ret; /* return 0 if ok */
  206. }
  207. int
  208. xdrfile_read_int(int *ptr, int ndata, XDRFILE* xfp)
  209. {
  210. int i=0;
  211. /* read write is encoded in the XDR struct */
  212. while(i<ndata && xdr_int((XDR *)(xfp->xdr),ptr+i))
  213. i++;
  214. return i;
  215. }
  216. int
  217. xdrfile_write_int(int *ptr, int ndata, XDRFILE* xfp)
  218. {
  219. int i=0;
  220. /* read write is encoded in the XDR struct */
  221. while(i<ndata && xdr_int((XDR *)(xfp->xdr),ptr+i))
  222. i++;
  223. return i;
  224. }
  225. int
  226. xdrfile_read_uint(unsigned int *ptr, int ndata, XDRFILE* xfp)
  227. {
  228. int i=0;
  229. /* read write is encoded in the XDR struct */
  230. while(i<ndata && xdr_u_int((XDR *)(xfp->xdr),ptr+i))
  231. i++;
  232. return i;
  233. }
  234. int
  235. xdrfile_write_uint(unsigned int *ptr, int ndata, XDRFILE* xfp)
  236. {
  237. int i=0;
  238. /* read write is encoded in the XDR struct */
  239. while(i<ndata && xdr_u_int((XDR *)(xfp->xdr),ptr+i))
  240. i++;
  241. return i;
  242. }
  243. int
  244. xdrfile_read_char(char *ptr, int ndata, XDRFILE* xfp)
  245. {
  246. int i=0;
  247. /* read write is encoded in the XDR struct */
  248. while(i<ndata && xdr_char((XDR *)(xfp->xdr),ptr+i))
  249. i++;
  250. return i;
  251. }
  252. int
  253. xdrfile_write_char(char *ptr, int ndata, XDRFILE* xfp)
  254. {
  255. int i=0;
  256. /* read write is encoded in the XDR struct */
  257. while(i<ndata && xdr_char((XDR *)(xfp->xdr),ptr+i))
  258. i++;
  259. return i;
  260. }
  261. int
  262. xdrfile_read_uchar(unsigned char *ptr, int ndata, XDRFILE* xfp)
  263. {
  264. int i=0;
  265. /* read write is encoded in the XDR struct */
  266. while(i<ndata && xdr_u_char((XDR *)(xfp->xdr),ptr+i))
  267. i++;
  268. return i;
  269. }
  270. int
  271. xdrfile_write_uchar(unsigned char *ptr, int ndata, XDRFILE* xfp)
  272. {
  273. int i=0;
  274. /* read write is encoded in the XDR struct */
  275. while(i<ndata && xdr_u_char((XDR *)(xfp->xdr),ptr+i))
  276. i++;
  277. return i;
  278. }
  279. int
  280. xdrfile_read_short(short *ptr, int ndata, XDRFILE* xfp)
  281. {
  282. int i=0;
  283. /* read write is encoded in the XDR struct */
  284. while(i<ndata && xdr_short((XDR *)(xfp->xdr),ptr+i))
  285. i++;
  286. return i;
  287. }
  288. int
  289. xdrfile_write_short(short *ptr, int ndata, XDRFILE* xfp)
  290. {
  291. int i=0;
  292. /* read write is encoded in the XDR struct */
  293. while(i<ndata && xdr_short((XDR *)(xfp->xdr),ptr+i))
  294. i++;
  295. return i;
  296. }
  297. int
  298. xdrfile_read_ushort(unsigned short *ptr, int ndata, XDRFILE* xfp)
  299. {
  300. int i=0;
  301. /* read write is encoded in the XDR struct */
  302. while(i<ndata && xdr_u_short((XDR *)(xfp->xdr),ptr+i))
  303. i++;
  304. return i;
  305. }
  306. int
  307. xdrfile_write_ushort(unsigned short *ptr, int ndata, XDRFILE* xfp)
  308. {
  309. int i=0;
  310. /* read write is encoded in the XDR struct */
  311. while(i<ndata && xdr_u_short((XDR *)(xfp->xdr),ptr+i))
  312. i++;
  313. return i;
  314. }
  315. int
  316. xdrfile_read_float(float *ptr, int ndata, XDRFILE* xfp)
  317. {
  318. int i=0;
  319. /* read write is encoded in the XDR struct */
  320. while(i<ndata && xdr_float((XDR *)(xfp->xdr),ptr+i))
  321. i++;
  322. return i;
  323. }
  324. int
  325. xdrfile_write_float(float *ptr, int ndata, XDRFILE* xfp)
  326. {
  327. int i=0;
  328. /* read write is encoded in the XDR struct */
  329. while(i<ndata && xdr_float((XDR *)(xfp->xdr),ptr+i))
  330. i++;
  331. return i;
  332. }
  333. int
  334. xdrfile_read_double(double *ptr, int ndata, XDRFILE* xfp)
  335. {
  336. int i=0;
  337. /* read write is encoded in the XDR struct */
  338. while(i<ndata && xdr_double((XDR *)(xfp->xdr),ptr+i))
  339. i++;
  340. return i;
  341. }
  342. int
  343. xdrfile_write_double(double *ptr, int ndata, XDRFILE* xfp)
  344. {
  345. int i=0;
  346. /* read write is encoded in the XDR struct */
  347. while(i<ndata && xdr_double((XDR *)(xfp->xdr),ptr+i))
  348. i++;
  349. return i;
  350. }
  351. int
  352. xdrfile_read_string(char *ptr, int maxlen, XDRFILE* xfp)
  353. {
  354. int i;
  355. if(xdr_string((XDR *)(xfp->xdr),&ptr,maxlen)) {
  356. i=0;
  357. while(i<maxlen && ptr[i]!=0)
  358. i++;
  359. if(i==maxlen)
  360. return maxlen;
  361. else
  362. return i+1;
  363. } else
  364. return 0;
  365. }
  366. int
  367. xdrfile_write_string(char *ptr, XDRFILE* xfp)
  368. {
  369. int len=strlen(ptr)+1;
  370. if(xdr_string((XDR *)(xfp->xdr),&ptr,len))
  371. return len;
  372. else
  373. return 0;
  374. }
  375. int
  376. xdrfile_read_opaque(char *ptr, int cnt, XDRFILE* xfp)
  377. {
  378. if(xdr_opaque((XDR *)(xfp->xdr),ptr,cnt))
  379. return cnt;
  380. else
  381. return 0;
  382. }
  383. int
  384. xdrfile_write_opaque(char *ptr, int cnt, XDRFILE* xfp)
  385. {
  386. if(xdr_opaque((XDR *)(xfp->xdr),ptr,cnt))
  387. return cnt;
  388. else
  389. return 0;
  390. }
  391. /* Internal support routines for reading/writing compressed coordinates
  392. * sizeofint - calculate smallest number of bits necessary
  393. * to represent a certain integer.
  394. */
  395. static int
  396. sizeofint(int size) {
  397. unsigned int num = 1;
  398. int num_of_bits = 0;
  399. while (size >= num && num_of_bits < 32)
  400. {
  401. num_of_bits++;
  402. num <<= 1;
  403. }
  404. return num_of_bits;
  405. }
  406. /*
  407. * sizeofints - calculate 'bitsize' of compressed ints
  408. *
  409. * given a number of small unsigned integers and the maximum value
  410. * return the number of bits needed to read or write them with the
  411. * routines encodeints/decodeints. You need this parameter when
  412. * calling those routines.
  413. * (However, in some cases we can just use the variable 'smallidx'
  414. * which is the exact number of bits, and them we dont need to call
  415. * this routine).
  416. */
  417. static int
  418. sizeofints(int num_of_ints, unsigned int sizes[])
  419. {
  420. int i, num;
  421. unsigned int num_of_bytes, num_of_bits, bytes[32], bytecnt, tmp;
  422. num_of_bytes = 1;
  423. bytes[0] = 1;
  424. num_of_bits = 0;
  425. for (i=0; i < num_of_ints; i++)
  426. {
  427. tmp = 0;
  428. for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++)
  429. {
  430. tmp = bytes[bytecnt] * sizes[i] + tmp;
  431. bytes[bytecnt] = tmp & 0xff;
  432. tmp >>= 8;
  433. }
  434. while (tmp != 0)
  435. {
  436. bytes[bytecnt++] = tmp & 0xff;
  437. tmp >>= 8;
  438. }
  439. num_of_bytes = bytecnt;
  440. }
  441. num = 1;
  442. num_of_bytes--;
  443. while (bytes[num_of_bytes] >= num)
  444. {
  445. num_of_bits++;
  446. num *= 2;
  447. }
  448. return num_of_bits + num_of_bytes * 8;
  449. }
  450. /*
  451. * encodebits - encode num into buf using the specified number of bits
  452. *
  453. * This routines appends the value of num to the bits already present in
  454. * the array buf. You need to give it the number of bits to use and you had
  455. * better make sure that this number of bits is enough to hold the value.
  456. * Num must also be positive.
  457. */
  458. static void
  459. encodebits(int buf[], int num_of_bits, int num)
  460. {
  461. unsigned int cnt, lastbyte;
  462. int lastbits;
  463. unsigned char * cbuf;
  464. cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
  465. cnt = (unsigned int) buf[0];
  466. lastbits = buf[1];
  467. lastbyte =(unsigned int) buf[2];
  468. while (num_of_bits >= 8)
  469. {
  470. lastbyte = (lastbyte << 8) | ((num >> (num_of_bits -8)) /* & 0xff*/);
  471. cbuf[cnt++] = lastbyte >> lastbits;
  472. num_of_bits -= 8;
  473. }
  474. if (num_of_bits > 0)
  475. {
  476. lastbyte = (lastbyte << num_of_bits) | num;
  477. lastbits += num_of_bits;
  478. if (lastbits >= 8)
  479. {
  480. lastbits -= 8;
  481. cbuf[cnt++] = lastbyte >> lastbits;
  482. }
  483. }
  484. buf[0] = cnt;
  485. buf[1] = lastbits;
  486. buf[2] = lastbyte;
  487. if (lastbits>0)
  488. {
  489. cbuf[cnt] = lastbyte << (8 - lastbits);
  490. }
  491. }
  492. /*
  493. * encodeints - encode a small set of small integers in compressed format
  494. *
  495. * this routine is used internally by xdr3dfcoord, to encode a set of
  496. * small integers to the buffer for writing to a file.
  497. * Multiplication with fixed (specified maximum) sizes is used to get
  498. * to one big, multibyte integer. Allthough the routine could be
  499. * modified to handle sizes bigger than 16777216, or more than just
  500. * a few integers, this is not done because the gain in compression
  501. * isn't worth the effort. Note that overflowing the multiplication
  502. * or the byte buffer (32 bytes) is unchecked and whould cause bad results.
  503. * THese things are checked in the calling routines, so make sure not
  504. * to remove those checks...
  505. */
  506. static void
  507. encodeints(int buf[], int num_of_ints, int num_of_bits,
  508. unsigned int sizes[], unsigned int nums[])
  509. {
  510. int i;
  511. unsigned int bytes[32], num_of_bytes, bytecnt, tmp;
  512. tmp = nums[0];
  513. num_of_bytes = 0;
  514. do
  515. {
  516. bytes[num_of_bytes++] = tmp & 0xff;
  517. tmp >>= 8;
  518. } while (tmp != 0);
  519. for (i = 1; i < num_of_ints; i++)
  520. {
  521. if (nums[i] >= sizes[i])
  522. {
  523. fprintf(stderr,"major breakdown in encodeints - num %u doesn't "
  524. "match size %u\n", nums[i], sizes[i]);
  525. abort();
  526. }
  527. /* use one step multiply */
  528. tmp = nums[i];
  529. for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++)
  530. {
  531. tmp = bytes[bytecnt] * sizes[i] + tmp;
  532. bytes[bytecnt] = tmp & 0xff;
  533. tmp >>= 8;
  534. }
  535. while (tmp != 0)
  536. {
  537. bytes[bytecnt++] = tmp & 0xff;
  538. tmp >>= 8;
  539. }
  540. num_of_bytes = bytecnt;
  541. }
  542. if (num_of_bits >= num_of_bytes * 8)
  543. {
  544. for (i = 0; i < num_of_bytes; i++)
  545. {
  546. encodebits(buf, 8, bytes[i]);
  547. }
  548. encodebits(buf, num_of_bits - num_of_bytes * 8, 0);
  549. }
  550. else
  551. {
  552. for (i = 0; i < num_of_bytes-1; i++)
  553. {
  554. encodebits(buf, 8, bytes[i]);
  555. }
  556. encodebits(buf, num_of_bits- (num_of_bytes -1) * 8, bytes[i]);
  557. }
  558. }
  559. /*
  560. * decodebits - decode number from buf using specified number of bits
  561. *
  562. * extract the number of bits from the array buf and construct an integer
  563. * from it. Return that value.
  564. *
  565. */
  566. static int
  567. decodebits(int buf[], int num_of_bits)
  568. {
  569. int cnt, num;
  570. unsigned int lastbits, lastbyte;
  571. unsigned char * cbuf;
  572. int mask = (1 << num_of_bits) -1;
  573. cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
  574. cnt = buf[0];
  575. lastbits = (unsigned int) buf[1];
  576. lastbyte = (unsigned int) buf[2];
  577. num = 0;
  578. while (num_of_bits >= 8)
  579. {
  580. lastbyte = ( lastbyte << 8 ) | cbuf[cnt++];
  581. num |= (lastbyte >> lastbits) << (num_of_bits - 8);
  582. num_of_bits -=8;
  583. }
  584. if (num_of_bits > 0)
  585. {
  586. if (lastbits < num_of_bits)
  587. {
  588. lastbits += 8;
  589. lastbyte = (lastbyte << 8) | cbuf[cnt++];
  590. }
  591. lastbits -= num_of_bits;
  592. num |= (lastbyte >> lastbits) & ((1 << num_of_bits) -1);
  593. }
  594. num &= mask;
  595. buf[0] = cnt;
  596. buf[1] = lastbits;
  597. buf[2] = lastbyte;
  598. return num;
  599. }
  600. /*
  601. * decodeints - decode 'small' integers from the buf array
  602. *
  603. * this routine is the inverse from encodeints() and decodes the small integers
  604. * written to buf by calculating the remainder and doing divisions with
  605. * the given sizes[]. You need to specify the total number of bits to be
  606. * used from buf in num_of_bits.
  607. *
  608. */
  609. static void
  610. decodeints(int buf[], int num_of_ints, int num_of_bits,
  611. unsigned int sizes[], int nums[])
  612. {
  613. int bytes[32];
  614. int i, j, num_of_bytes, p, num;
  615. bytes[1] = bytes[2] = bytes[3] = 0;
  616. num_of_bytes = 0;
  617. while (num_of_bits > 8)
  618. {
  619. bytes[num_of_bytes++] = decodebits(buf, 8);
  620. num_of_bits -= 8;
  621. }
  622. if (num_of_bits > 0)
  623. {
  624. bytes[num_of_bytes++] = decodebits(buf, num_of_bits);
  625. }
  626. for (i = num_of_ints-1; i > 0; i--)
  627. {
  628. num = 0;
  629. for (j = num_of_bytes-1; j >=0; j--)
  630. {
  631. num = (num << 8) | bytes[j];
  632. p = num / sizes[i];
  633. bytes[j] = p;
  634. num = num - p * sizes[i];
  635. }
  636. nums[i] = num;
  637. }
  638. nums[0] = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
  639. }
  640. static const int magicints[] =
  641. {
  642. 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
  643. 80, 101, 128, 161, 203, 256, 322, 406, 512, 645, 812, 1024, 1290,
  644. 1625, 2048, 2580, 3250, 4096, 5060, 6501, 8192, 10321, 13003,
  645. 16384, 20642, 26007, 32768, 41285, 52015, 65536,82570, 104031,
  646. 131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561,
  647. 832255, 1048576, 1321122, 1664510, 2097152, 2642245, 3329021,
  648. 4194304, 5284491, 6658042, 8388607, 10568983, 13316085, 16777216
  649. };
  650. #define FIRSTIDX 9
  651. /* note that magicints[FIRSTIDX-1] == 0 */
  652. #define LASTIDX (sizeof(magicints) / sizeof(*magicints))
  653. /* Compressed coordinate routines - modified from the original
  654. * implementation by Frans v. Hoesel to make them threadsafe.
  655. */
  656. int
  657. xdrfile_decompress_coord_float(float *ptr,
  658. int *size,
  659. float *precision,
  660. XDRFILE* xfp)
  661. {
  662. int minint[3], maxint[3], *lip;
  663. int smallidx, minidx, maxidx;
  664. unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3;
  665. int k, *buf1, *buf2, lsize, flag;
  666. int smallnum, smaller, larger, i, is_smaller, run;
  667. float *lfp, inv_precision;
  668. int tmp, *thiscoord, prevcoord[3];
  669. unsigned int bitsize;
  670. bitsizeint[0] = 0;
  671. bitsizeint[1] = 0;
  672. bitsizeint[2] = 0;
  673. if(xfp==NULL || ptr==NULL)
  674. return -1;
  675. tmp=xdrfile_read_int(&lsize,1,xfp);
  676. if(tmp==0)
  677. return -1; /* return if we could not read size */
  678. if (*size < lsize)
  679. {
  680. fprintf(stderr, "Requested to decompress %d coords, file contains %d\n",
  681. *size, lsize);
  682. return -1;
  683. }
  684. *size = lsize;
  685. size3 = *size * 3;
  686. if(size3>xfp->buf1size)
  687. {
  688. if((xfp->buf1=(int *)malloc(sizeof(int)*size3))==NULL)
  689. {
  690. fprintf(stderr,"Cannot allocate memory for decompressing coordinates.\n");
  691. return -1;
  692. }
  693. xfp->buf1size=size3;
  694. xfp->buf2size=size3*1.2;
  695. if((xfp->buf2=(int *)malloc(sizeof(int)*xfp->buf2size))==NULL)
  696. {
  697. fprintf(stderr,"Cannot allocate memory for decompressing coordinates.\n");
  698. return -1;
  699. }
  700. }
  701. /* Dont bother with compression for three atoms or less */
  702. if(*size<=9)
  703. {
  704. return xdrfile_read_float(ptr,size3,xfp)/3;
  705. /* return number of coords, not floats */
  706. }
  707. /* Compression-time if we got here. Read precision first */
  708. xdrfile_read_float(precision,1,xfp);
  709. /* avoid repeated pointer dereferencing. */
  710. buf1=xfp->buf1;
  711. buf2=xfp->buf2;
  712. /* buf2[0-2] are special and do not contain actual data */
  713. buf2[0] = buf2[1] = buf2[2] = 0;
  714. xdrfile_read_int(minint,3,xfp);
  715. xdrfile_read_int(maxint,3,xfp);
  716. sizeint[0] = maxint[0] - minint[0]+1;
  717. sizeint[1] = maxint[1] - minint[1]+1;
  718. sizeint[2] = maxint[2] - minint[2]+1;
  719. /* check if one of the sizes is to big to be multiplied */
  720. if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
  721. {
  722. bitsizeint[0] = sizeofint(sizeint[0]);
  723. bitsizeint[1] = sizeofint(sizeint[1]);
  724. bitsizeint[2] = sizeofint(sizeint[2]);
  725. bitsize = 0; /* flag the use of large sizes */
  726. }
  727. else
  728. {
  729. bitsize = sizeofints(3, sizeint);
  730. }
  731. if (xdrfile_read_int(&smallidx,1,xfp) == 0)
  732. return 0; /* not sure what has happened here or why we return... */
  733. tmp=smallidx+8;
  734. maxidx = (LASTIDX<tmp) ? LASTIDX : tmp;
  735. minidx = maxidx - 8; /* often this equal smallidx */
  736. tmp = smallidx-1;
  737. tmp = (FIRSTIDX>tmp) ? FIRSTIDX : tmp;
  738. smaller = magicints[tmp] / 2;
  739. smallnum = magicints[smallidx] / 2;
  740. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
  741. larger = magicints[maxidx];
  742. /* buf2[0] holds the length in bytes */
  743. if (xdrfile_read_int(buf2,1,xfp) == 0)
  744. return 0;
  745. if (xdrfile_read_opaque((char *)&(buf2[3]),(unsigned int)buf2[0],xfp) == 0)
  746. return 0;
  747. buf2[0] = buf2[1] = buf2[2] = 0;
  748. lfp = ptr;
  749. inv_precision = 1.0 / * precision;
  750. run = 0;
  751. i = 0;
  752. lip = buf1;
  753. while ( i < lsize )
  754. {
  755. thiscoord = (int *)(lip) + i * 3;
  756. if (bitsize == 0)
  757. {
  758. thiscoord[0] = decodebits(buf2, bitsizeint[0]);
  759. thiscoord[1] = decodebits(buf2, bitsizeint[1]);
  760. thiscoord[2] = decodebits(buf2, bitsizeint[2]);
  761. }
  762. else
  763. {
  764. decodeints(buf2, 3, bitsize, sizeint, thiscoord);
  765. }
  766. i++;
  767. thiscoord[0] += minint[0];
  768. thiscoord[1] += minint[1];
  769. thiscoord[2] += minint[2];
  770. prevcoord[0] = thiscoord[0];
  771. prevcoord[1] = thiscoord[1];
  772. prevcoord[2] = thiscoord[2];
  773. flag = decodebits(buf2, 1);
  774. is_smaller = 0;
  775. if (flag == 1)
  776. {
  777. run = decodebits(buf2, 5);
  778. is_smaller = run % 3;
  779. run -= is_smaller;
  780. is_smaller--;
  781. }
  782. if (run > 0)
  783. {
  784. thiscoord += 3;
  785. for (k = 0; k < run; k+=3)
  786. {
  787. decodeints(buf2, 3, smallidx, sizesmall, thiscoord);
  788. i++;
  789. thiscoord[0] += prevcoord[0] - smallnum;
  790. thiscoord[1] += prevcoord[1] - smallnum;
  791. thiscoord[2] += prevcoord[2] - smallnum;
  792. if (k == 0) {
  793. /* interchange first with second atom for better
  794. * compression of water molecules
  795. */
  796. tmp = thiscoord[0]; thiscoord[0] = prevcoord[0];
  797. prevcoord[0] = tmp;
  798. tmp = thiscoord[1]; thiscoord[1] = prevcoord[1];
  799. prevcoord[1] = tmp;
  800. tmp = thiscoord[2]; thiscoord[2] = prevcoord[2];
  801. prevcoord[2] = tmp;
  802. *lfp++ = prevcoord[0] * inv_precision;
  803. *lfp++ = prevcoord[1] * inv_precision;
  804. *lfp++ = prevcoord[2] * inv_precision;
  805. } else {
  806. prevcoord[0] = thiscoord[0];
  807. prevcoord[1] = thiscoord[1];
  808. prevcoord[2] = thiscoord[2];
  809. }
  810. *lfp++ = thiscoord[0] * inv_precision;
  811. *lfp++ = thiscoord[1] * inv_precision;
  812. *lfp++ = thiscoord[2] * inv_precision;
  813. }
  814. }
  815. else
  816. {
  817. *lfp++ = thiscoord[0] * inv_precision;
  818. *lfp++ = thiscoord[1] * inv_precision;
  819. *lfp++ = thiscoord[2] * inv_precision;
  820. }
  821. smallidx += is_smaller;
  822. if (is_smaller < 0)
  823. {
  824. smallnum = smaller;
  825. if (smallidx > FIRSTIDX)
  826. {
  827. smaller = magicints[smallidx - 1] /2;
  828. }
  829. else
  830. {
  831. smaller = 0;
  832. }
  833. }
  834. else if (is_smaller > 0)
  835. {
  836. smaller = smallnum;
  837. smallnum = magicints[smallidx] / 2;
  838. }
  839. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
  840. }
  841. return *size;
  842. }
  843. int
  844. xdrfile_compress_coord_float(float *ptr,
  845. int size,
  846. float precision,
  847. XDRFILE* xfp)
  848. {
  849. int minint[3], maxint[3], mindiff, *lip, diff;
  850. int lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx;
  851. int minidx, maxidx;
  852. unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3, *luip;
  853. int k, *buf1, *buf2;
  854. int smallnum, smaller, larger, i, j, is_small, is_smaller, run, prevrun;
  855. float *lfp, lf;
  856. int tmp, tmpsum, *thiscoord, prevcoord[3];
  857. unsigned int tmpcoord[30];
  858. int errval=1;
  859. unsigned int bitsize;
  860. if(xfp==NULL)
  861. return -1;
  862. size3=3*size;
  863. bitsizeint[0] = 0;
  864. bitsizeint[1] = 0;
  865. bitsizeint[2] = 0;
  866. if(size3>xfp->buf1size)
  867. {
  868. if((xfp->buf1=(int *)malloc(sizeof(int)*size3))==NULL)
  869. {
  870. fprintf(stderr,"Cannot allocate memory for compressing coordinates.\n");
  871. return -1;
  872. }
  873. xfp->buf1size=size3;
  874. xfp->buf2size=size3*1.2;
  875. if((xfp->buf2=(int *)malloc(sizeof(int)*xfp->buf2size))==NULL)
  876. {
  877. fprintf(stderr,"Cannot allocate memory for compressing coordinates.\n");
  878. return -1;
  879. }
  880. }
  881. if(xdrfile_write_int(&size,1,xfp)==0)
  882. return -1; /* return if we could not write size */
  883. /* Dont bother with compression for three atoms or less */
  884. if(size<=9)
  885. {
  886. return xdrfile_write_float(ptr,size3,xfp)/3;
  887. /* return number of coords, not floats */
  888. }
  889. /* Compression-time if we got here. Write precision first */
  890. if (precision <= 0)
  891. precision = 1000;
  892. xdrfile_write_float(&precision,1,xfp);
  893. /* avoid repeated pointer dereferencing. */
  894. buf1=xfp->buf1;
  895. buf2=xfp->buf2;
  896. /* buf2[0-2] are special and do not contain actual data */
  897. buf2[0] = buf2[1] = buf2[2] = 0;
  898. minint[0] = minint[1] = minint[2] = INT_MAX;
  899. maxint[0] = maxint[1] = maxint[2] = INT_MIN;
  900. prevrun = -1;
  901. lfp = ptr;
  902. lip = buf1;
  903. mindiff = INT_MAX;
  904. oldlint1 = oldlint2 = oldlint3 = 0;
  905. while(lfp < ptr + size3 )
  906. {
  907. /* find nearest integer */
  908. if (*lfp >= 0.0)
  909. lf = *lfp * precision + 0.5;
  910. else
  911. lf = *lfp * precision - 0.5;
  912. if (fabs(lf) > INT_MAX-2)
  913. {
  914. /* scaling would cause overflow */
  915. fprintf(stderr,"Internal overflow compressing coordinates.\n");
  916. errval=0;
  917. }
  918. lint1 = lf;
  919. if (lint1 < minint[0]) minint[0] = lint1;
  920. if (lint1 > maxint[0]) maxint[0] = lint1;
  921. *lip++ = lint1;
  922. lfp++;
  923. if (*lfp >= 0.0)
  924. lf = *lfp * precision + 0.5;
  925. else
  926. lf = *lfp * precision - 0.5;
  927. if (fabs(lf) > INT_MAX-2)
  928. {
  929. /* scaling would cause overflow */
  930. fprintf(stderr,"Internal overflow compressing coordinates.\n");
  931. errval=0;
  932. }
  933. lint2 = lf;
  934. if (lint2 < minint[1]) minint[1] = lint2;
  935. if (lint2 > maxint[1]) maxint[1] = lint2;
  936. *lip++ = lint2;
  937. lfp++;
  938. if (*lfp >= 0.0)
  939. lf = *lfp * precision + 0.5;
  940. else
  941. lf = *lfp * precision - 0.5;
  942. if (fabs(lf) > INT_MAX-2)
  943. {
  944. errval=0;
  945. }
  946. lint3 = lf;
  947. if (lint3 < minint[2]) minint[2] = lint3;
  948. if (lint3 > maxint[2]) maxint[2] = lint3;
  949. *lip++ = lint3;
  950. lfp++;
  951. diff = abs(oldlint1-lint1)+abs(oldlint2-lint2)+abs(oldlint3-lint3);
  952. if (diff < mindiff && lfp > ptr + 3)
  953. mindiff = diff;
  954. oldlint1 = lint1;
  955. oldlint2 = lint2;
  956. oldlint3 = lint3;
  957. }
  958. xdrfile_write_int(minint,3,xfp);
  959. xdrfile_write_int(maxint,3,xfp);
  960. if ((float)maxint[0] - (float)minint[0] >= INT_MAX-2 ||
  961. (float)maxint[1] - (float)minint[1] >= INT_MAX-2 ||
  962. (float)maxint[2] - (float)minint[2] >= INT_MAX-2) {
  963. /* turning value in unsigned by subtracting minint
  964. * would cause overflow
  965. */
  966. fprintf(stderr,"Internal overflow compressing coordinates.\n");
  967. errval=0;
  968. }
  969. sizeint[0] = maxint[0] - minint[0]+1;
  970. sizeint[1] = maxint[1] - minint[1]+1;
  971. sizeint[2] = maxint[2] - minint[2]+1;
  972. /* check if one of the sizes is to big to be multiplied */
  973. if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
  974. {
  975. bitsizeint[0] = sizeofint(sizeint[0]);
  976. bitsizeint[1] = sizeofint(sizeint[1]);
  977. bitsizeint[2] = sizeofint(sizeint[2]);
  978. bitsize = 0; /* flag the use of large sizes */
  979. }
  980. else
  981. {
  982. bitsize = sizeofints(3, sizeint);
  983. }
  984. lip = buf1;
  985. luip = (unsigned int *) buf1;
  986. smallidx = FIRSTIDX;
  987. while (smallidx < LASTIDX && magicints[smallidx] < mindiff)
  988. {
  989. smallidx++;
  990. }
  991. xdrfile_write_int(&smallidx,1,xfp);
  992. tmp=smallidx+8;
  993. maxidx = (LASTIDX<tmp) ? LASTIDX : tmp;
  994. minidx = maxidx - 8; /* often this equal smallidx */
  995. tmp=smallidx-1;
  996. tmp= (FIRSTIDX>tmp) ? FIRSTIDX : tmp;
  997. smaller = magicints[tmp] / 2;
  998. smallnum = magicints[smallidx] / 2;
  999. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
  1000. larger = magicints[maxidx] / 2;
  1001. i = 0;
  1002. while (i < size)
  1003. {
  1004. is_small = 0;
  1005. thiscoord = (int *)(luip) + i * 3;
  1006. if (smallidx < maxidx && i >= 1 &&
  1007. abs(thiscoord[0] - prevcoord[0]) < larger &&
  1008. abs(thiscoord[1] - prevcoord[1]) < larger &&
  1009. abs(thiscoord[2] - prevcoord[2]) < larger) {
  1010. is_smaller = 1;
  1011. }
  1012. else if (smallidx > minidx)
  1013. {
  1014. is_smaller = -1;
  1015. }
  1016. else
  1017. {
  1018. is_smaller = 0;
  1019. }
  1020. if (i + 1 < size)
  1021. {
  1022. if (abs(thiscoord[0] - thiscoord[3]) < smallnum &&
  1023. abs(thiscoord[1] - thiscoord[4]) < smallnum &&
  1024. abs(thiscoord[2] - thiscoord[5]) < smallnum)
  1025. {
  1026. /* interchange first with second atom for better
  1027. * compression of water molecules
  1028. */
  1029. tmp = thiscoord[0]; thiscoord[0] = thiscoord[3];
  1030. thiscoord[3] = tmp;
  1031. tmp = thiscoord[1]; thiscoord[1] = thiscoord[4];
  1032. thiscoord[4] = tmp;
  1033. tmp = thiscoord[2]; thiscoord[2] = thiscoord[5];
  1034. thiscoord[5] = tmp;
  1035. is_small = 1;
  1036. }
  1037. }
  1038. tmpcoord[0] = thiscoord[0] - minint[0];
  1039. tmpcoord[1] = thiscoord[1] - minint[1];
  1040. tmpcoord[2] = thiscoord[2] - minint[2];
  1041. if (bitsize == 0)
  1042. {
  1043. encodebits(buf2, bitsizeint[0], tmpcoord[0]);
  1044. encodebits(buf2, bitsizeint[1], tmpcoord[1]);
  1045. encodebits(buf2, bitsizeint[2], tmpcoord[2]);
  1046. }
  1047. else
  1048. {
  1049. encodeints(buf2, 3, bitsize, sizeint, tmpcoord);
  1050. }
  1051. prevcoord[0] = thiscoord[0];
  1052. prevcoord[1] = thiscoord[1];
  1053. prevcoord[2] = thiscoord[2];
  1054. thiscoord = thiscoord + 3;
  1055. i++;
  1056. run = 0;
  1057. if (is_small == 0 && is_smaller == -1)
  1058. is_smaller = 0;
  1059. while (is_small && run < 8*3)
  1060. {
  1061. tmpsum=0;
  1062. for(j=0;j<3;j++)
  1063. {
  1064. tmp=thiscoord[j] - prevcoord[j];
  1065. tmpsum+=tmp*tmp;
  1066. }
  1067. if (is_smaller == -1 && tmpsum >= smaller * smaller)
  1068. {
  1069. is_smaller = 0;
  1070. }
  1071. tmpcoord[run++] = thiscoord[0] - prevcoord[0] + smallnum;
  1072. tmpcoord[run++] = thiscoord[1] - prevcoord[1] + smallnum;
  1073. tmpcoord[run++] = thiscoord[2] - prevcoord[2] + smallnum;
  1074. prevcoord[0] = thiscoord[0];
  1075. prevcoord[1] = thiscoord[1];
  1076. prevcoord[2] = thiscoord[2];
  1077. i++;
  1078. thiscoord = thiscoord + 3;
  1079. is_small = 0;
  1080. if (i < size &&
  1081. abs(thiscoord[0] - prevcoord[0]) < smallnum &&
  1082. abs(thiscoord[1] - prevcoord[1]) < smallnum &&
  1083. abs(thiscoord[2] - prevcoord[2]) < smallnum)
  1084. {
  1085. is_small = 1;
  1086. }
  1087. }
  1088. if (run != prevrun || is_smaller != 0)
  1089. {
  1090. prevrun = run;
  1091. encodebits(buf2, 1, 1); /* flag the change in run-length */
  1092. encodebits(buf2, 5, run+is_smaller+1);
  1093. }
  1094. else
  1095. {
  1096. encodebits(buf2, 1, 0); /* flag the fact that runlength did not change */
  1097. }
  1098. for (k=0; k < run; k+=3)
  1099. {
  1100. encodeints(buf2, 3, smallidx, sizesmall, &tmpcoord[k]);
  1101. }
  1102. if (is_smaller != 0)
  1103. {
  1104. smallidx += is_smaller;
  1105. if (is_smaller < 0)
  1106. {
  1107. smallnum = smaller;
  1108. smaller = magicints[smallidx-1] / 2;
  1109. }
  1110. else
  1111. {
  1112. smaller = smallnum;
  1113. smallnum = magicints[smallidx] / 2;
  1114. }
  1115. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
  1116. }
  1117. }
  1118. if (buf2[1] != 0) buf2[0]++;
  1119. xdrfile_write_int(buf2,1,xfp); /* buf2[0] holds the length in bytes */
  1120. tmp=xdrfile_write_opaque((char *)&(buf2[3]),(unsigned int)buf2[0],xfp);
  1121. if(tmp==(unsigned int)buf2[0])
  1122. return size;
  1123. else
  1124. return -1;
  1125. }
  1126. int
  1127. xdrfile_decompress_coord_double(double *ptr,
  1128. int *size,
  1129. double *precision,
  1130. XDRFILE* xfp)
  1131. {
  1132. int minint[3], maxint[3], *lip;
  1133. int smallidx, minidx, maxidx;
  1134. unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3;
  1135. int k, *buf1, *buf2, lsize, flag;
  1136. int smallnum, smaller, larger, i, is_smaller, run;
  1137. double *lfp, inv_precision;
  1138. float float_prec, tmpdata[30];
  1139. int tmp, *thiscoord, prevcoord[3];
  1140. unsigned int bitsize;
  1141. bitsizeint[0] = 0;
  1142. bitsizeint[1] = 0;
  1143. bitsizeint[2] = 0;
  1144. if(xfp==NULL || ptr==NULL)
  1145. return -1;
  1146. tmp=xdrfile_read_int(&lsize,1,xfp);
  1147. if(tmp==0)
  1148. return -1; /* return if we could not read size */
  1149. if (*size < lsize)
  1150. {
  1151. fprintf(stderr, "Requested to decompress %d coords, file contains %d\n",
  1152. *size, lsize);
  1153. return -1;
  1154. }
  1155. *size = lsize;
  1156. size3 = *size * 3;
  1157. if(size3>xfp->buf1size)
  1158. {
  1159. if((xfp->buf1=(int *)malloc(sizeof(int)*size3))==NULL)
  1160. {
  1161. fprintf(stderr,"Cannot allocate memory for decompression coordinates.\n");
  1162. return -1;
  1163. }
  1164. xfp->buf1size=size3;
  1165. xfp->buf2size=size3*1.2;
  1166. if((xfp->buf2=(int *)malloc(sizeof(int)*xfp->buf2size))==NULL)
  1167. {
  1168. fprintf(stderr,"Cannot allocate memory for decompressing coordinates.\n");
  1169. return -1;
  1170. }
  1171. }
  1172. /* Dont bother with compression for three atoms or less */
  1173. if(*size<=9)
  1174. {
  1175. tmp=xdrfile_read_float(tmpdata,size3,xfp);
  1176. for(i=0;i<9*3;i++)
  1177. ptr[i]=tmpdata[i];
  1178. return tmp/3;
  1179. /* return number of coords, not floats */
  1180. }
  1181. /* Compression-time if we got here. Read precision first */
  1182. xdrfile_read_float(&float_prec,1,xfp);
  1183. *precision=float_prec;
  1184. /* avoid repeated pointer dereferencing. */
  1185. buf1=xfp->buf1;
  1186. buf2=xfp->buf2;
  1187. /* buf2[0-2] are special and do not contain actual data */
  1188. buf2[0] = buf2[1] = buf2[2] = 0;
  1189. xdrfile_read_int(minint,3,xfp);
  1190. xdrfile_read_int(maxint,3,xfp);
  1191. sizeint[0] = maxint[0] - minint[0]+1;
  1192. sizeint[1] = maxint[1] - minint[1]+1;
  1193. sizeint[2] = maxint[2] - minint[2]+1;
  1194. /* check if one of the sizes is to big to be multiplied */
  1195. if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
  1196. {
  1197. bitsizeint[0] = sizeofint(sizeint[0]);
  1198. bitsizeint[1] = sizeofint(sizeint[1]);
  1199. bitsizeint[2] = sizeofint(sizeint[2]);
  1200. bitsize = 0; /* flag the use of large sizes */
  1201. }
  1202. else
  1203. {
  1204. bitsize = sizeofints(3, sizeint);
  1205. }
  1206. if (xdrfile_read_int(&smallidx,1,xfp) == 0)
  1207. return 0;
  1208. tmp=smallidx+8;
  1209. maxidx = (LASTIDX<tmp) ? LASTIDX : tmp;
  1210. minidx = maxidx - 8; /* often this equal smallidx */
  1211. tmp = smallidx-1;
  1212. tmp = (FIRSTIDX>tmp) ? FIRSTIDX : tmp;
  1213. smaller = magicints[tmp] / 2;
  1214. smallnum = magicints[smallidx] / 2;
  1215. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
  1216. larger = magicints[maxidx];
  1217. /* buf2[0] holds the length in bytes */
  1218. if (xdrfile_read_int(buf2,1,xfp) == 0)
  1219. return 0;
  1220. if (xdrfile_read_opaque((char *)&(buf2[3]),(unsigned int)buf2[0],xfp) == 0)
  1221. return 0;
  1222. buf2[0] = buf2[1] = buf2[2] = 0;
  1223. lfp = ptr;
  1224. inv_precision = 1.0 / * precision;
  1225. run = 0;
  1226. i = 0;
  1227. lip = buf1;
  1228. while ( i < lsize )
  1229. {
  1230. thiscoord = (int *)(lip) + i * 3;
  1231. if (bitsize == 0)
  1232. {
  1233. thiscoord[0] = decodebits(buf2, bitsizeint[0]);
  1234. thiscoord[1] = decodebits(buf2, bitsizeint[1]);
  1235. thiscoord[2] = decodebits(buf2, bitsizeint[2]);
  1236. } else {
  1237. decodeints(buf2, 3, bitsize, sizeint, thiscoord);
  1238. }
  1239. i++;
  1240. thiscoord[0] += minint[0];
  1241. thiscoord[1] += minint[1];
  1242. thiscoord[2] += minint[2];
  1243. prevcoord[0] = thiscoord[0];
  1244. prevcoord[1] = thiscoord[1];
  1245. prevcoord[2] = thiscoord[2];
  1246. flag = decodebits(buf2, 1);
  1247. is_smaller = 0;
  1248. if (flag == 1)
  1249. {
  1250. run = decodebits(buf2, 5);
  1251. is_smaller = run % 3;
  1252. run -= is_smaller;
  1253. is_smaller--;
  1254. }
  1255. if (run > 0)
  1256. {
  1257. thiscoord += 3;
  1258. for (k = 0; k < run; k+=3)
  1259. {
  1260. decodeints(buf2, 3, smallidx, sizesmall, thiscoord);
  1261. i++;
  1262. thiscoord[0] += prevcoord[0] - smallnum;
  1263. thiscoord[1] += prevcoord[1] - smallnum;
  1264. thiscoord[2] += prevcoord[2] - smallnum;
  1265. if (k == 0)
  1266. {
  1267. /* interchange first with second atom for better
  1268. * compression of water molecules
  1269. */
  1270. tmp = thiscoord[0]; thiscoord[0] = prevcoord[0];
  1271. prevcoord[0] = tmp;
  1272. tmp = thiscoord[1]; thiscoord[1] = prevcoord[1];
  1273. prevcoord[1] = tmp;
  1274. tmp = thiscoord[2]; thiscoord[2] = prevcoord[2];
  1275. prevcoord[2] = tmp;
  1276. *lfp++ = prevcoord[0] * inv_precision;
  1277. *lfp++ = prevcoord[1] * inv_precision;
  1278. *lfp++ = prevcoord[2] * inv_precision;
  1279. }
  1280. else
  1281. {
  1282. prevcoord[0] = thiscoord[0];
  1283. prevcoord[1] = thiscoord[1];
  1284. prevcoord[2] = thiscoord[2];
  1285. }
  1286. *lfp++ = thiscoord[0] * inv_precision;
  1287. *lfp++ = thiscoord[1] * inv_precision;
  1288. *lfp++ = thiscoord[2] * inv_precision;
  1289. }
  1290. } else {
  1291. *lfp++ = thiscoord[0] * inv_precision;
  1292. *lfp++ = thiscoord[1] * inv_precision;
  1293. *lfp++ = thiscoord[2] * inv_precision;
  1294. }
  1295. smallidx += is_smaller;
  1296. if (is_smaller < 0) {
  1297. smallnum = smaller;
  1298. if (smallidx > FIRSTIDX) {
  1299. smaller = magicints[smallidx - 1] /2;
  1300. } else {
  1301. smaller = 0;
  1302. }
  1303. } else if (is_smaller > 0) {
  1304. smaller = smallnum;
  1305. smallnum = magicints[smallidx] / 2;
  1306. }
  1307. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
  1308. }
  1309. return *size;
  1310. }
  1311. int
  1312. xdrfile_compress_coord_double(double *ptr,
  1313. int size,
  1314. double precision,
  1315. XDRFILE* xfp)
  1316. {
  1317. int minint[3], maxint[3], mindiff, *lip, diff;
  1318. int lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx;
  1319. int minidx, maxidx;
  1320. unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3, *luip;
  1321. int k, *buf1, *buf2;
  1322. int smallnum, smaller, larger, i, j, is_small, is_smaller, run, prevrun;
  1323. double *lfp;
  1324. float float_prec, lf,tmpdata[30];
  1325. int tmp, tmpsum, *thiscoord, prevcoord[3];
  1326. unsigned int tmpcoord[30];
  1327. int errval=1;
  1328. unsigned int bitsize;
  1329. bitsizeint[0] = 0;
  1330. bitsizeint[1] = 0;
  1331. bitsizeint[2] = 0;
  1332. if(xfp==NULL)
  1333. return -1;
  1334. size3=3*size;
  1335. if(size3>xfp->buf1size) {
  1336. if((xfp->buf1=(int *)malloc(sizeof(int)*size3))==NULL) {
  1337. fprintf(stderr,"Cannot allocate memory for compressing coordinates.\n");
  1338. return -1;
  1339. }
  1340. xfp->buf1size=size3;
  1341. xfp->buf2size=size3*1.2;
  1342. if((xfp->buf2=(int *)malloc(sizeof(int)*xfp->buf2size))==NULL) {
  1343. fprintf(stderr,"Cannot allocate memory for compressing coordinates.\n");
  1344. return -1;
  1345. }
  1346. }
  1347. if(xdrfile_write_int(&size,1,xfp)==0)
  1348. return -1; /* return if we could not write size */
  1349. /* Dont bother with compression for three atoms or less */
  1350. if(size<=9) {
  1351. for(i=0;i<9*3;i++)
  1352. tmpdata[i]=ptr[i];
  1353. return xdrfile_write_float(tmpdata,size3,xfp)/3;
  1354. /* return number of coords, not floats */
  1355. }
  1356. /* Compression-time if we got here. Write precision first */
  1357. if (precision <= 0)
  1358. precision = 1000;
  1359. float_prec=precision;
  1360. xdrfile_write_float(&float_prec,1,xfp);
  1361. /* avoid repeated pointer dereferencing. */
  1362. buf1=xfp->buf1;
  1363. buf2=xfp->buf2;
  1364. /* buf2[0-2] are special and do not contain actual data */
  1365. buf2[0] = buf2[1] = buf2[2] = 0;
  1366. minint[0] = minint[1] = minint[2] = INT_MAX;
  1367. maxint[0] = maxint[1] = maxint[2] = INT_MIN;
  1368. prevrun = -1;
  1369. lfp = ptr;
  1370. lip = buf1;
  1371. mindiff = INT_MAX;
  1372. oldlint1 = oldlint2 = oldlint3 = 0;
  1373. while(lfp < ptr + size3 ) {
  1374. /* find nearest integer */
  1375. if (*lfp >= 0.0)
  1376. lf = (float)*lfp * float_prec + 0.5;
  1377. else
  1378. lf = (float)*lfp * float_prec - 0.5;
  1379. if (fabs(lf) > INT_MAX-2) {
  1380. /* scaling would cause overflow */
  1381. fprintf(stderr,"Internal overflow compressing coordinates.\n");
  1382. errval=0;
  1383. }
  1384. lint1 = lf;
  1385. if (lint1 < minint[0]) minint[0] = lint1;
  1386. if (lint1 > maxint[0]) maxint[0] = lint1;
  1387. *lip++ = lint1;
  1388. lfp++;
  1389. if (*lfp >= 0.0)
  1390. lf = (float)*lfp * float_prec + 0.5;
  1391. else
  1392. lf = (float)*lfp * float_prec - 0.5;
  1393. if (fabs(lf) > INT_MAX-2) {
  1394. /* scaling would cause overflow */
  1395. fprintf(stderr,"Internal overflow compressing coordinates.\n");
  1396. errval=0;
  1397. }
  1398. lint2 = lf;
  1399. if (lint2 < minint[1]) minint[1] = lint2;
  1400. if (lint2 > maxint[1]) maxint[1] = lint2;
  1401. *lip++ = lint2;
  1402. lfp++;
  1403. if (*lfp >= 0.0)
  1404. lf = (float)*lfp * float_prec + 0.5;
  1405. else
  1406. lf = (float)*lfp * float_prec - 0.5;
  1407. if (fabs(lf) > INT_MAX-2) {
  1408. errval=0;
  1409. }
  1410. lint3 = lf;
  1411. if (lint3 < minint[2]) minint[2] = lint3;
  1412. if (lint3 > maxint[2]) maxint[2] = lint3;
  1413. *lip++ = lint3;
  1414. lfp++;
  1415. diff = abs(oldlint1-lint1)+abs(oldlint2-lint2)+abs(oldlint3-lint3);
  1416. if (diff < mindiff && lfp > ptr + 3)
  1417. mindiff = diff;
  1418. oldlint1 = lint1;
  1419. oldlint2 = lint2;
  1420. oldlint3 = lint3;
  1421. }
  1422. xdrfile_write_int(minint,3,xfp);
  1423. xdrfile_write_int(maxint,3,xfp);
  1424. if ((float)maxint[0] - (float)minint[0] >= INT_MAX-2 ||
  1425. (float)maxint[1] - (float)minint[1] >= INT_MAX-2 ||
  1426. (float)maxint[2] - (float)minint[2] >= INT_MAX-2) {
  1427. /* turning value in unsigned by subtracting minint
  1428. * would cause overflow
  1429. */
  1430. fprintf(stderr,"Internal overflow compressing coordinates.\n");
  1431. errval=0;
  1432. }
  1433. sizeint[0] = maxint[0] - minint[0]+1;
  1434. sizeint[1] = maxint[1] - minint[1]+1;
  1435. sizeint[2] = maxint[2] - minint[2]+1;
  1436. /* check if one of the sizes is to big to be multiplied */
  1437. if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff) {
  1438. bitsizeint[0] = sizeofint(sizeint[0]);
  1439. bitsizeint[1] = sizeofint(sizeint[1]);
  1440. bitsizeint[2] = sizeofint(sizeint[2]);
  1441. bitsize = 0; /* flag the use of large sizes */
  1442. } else {
  1443. bitsize = sizeofints(3, sizeint);
  1444. }
  1445. lip = buf1;
  1446. luip = (unsigned int *) buf1;
  1447. smallidx = FIRSTIDX;
  1448. while (smallidx < LASTIDX && magicints[smallidx] < mindiff) {
  1449. smallidx++;
  1450. }
  1451. xdrfile_write_int(&smallidx,1,xfp);
  1452. tmp=smallidx+8;
  1453. maxidx = (LASTIDX<tmp) ? LASTIDX : tmp;
  1454. minidx = maxidx - 8; /* often this equal smallidx */
  1455. tmp=smallidx-1;
  1456. tmp= (FIRSTIDX>tmp) ? FIRSTIDX : tmp;
  1457. smaller = magicints[tmp] / 2;
  1458. smallnum = magicints[smallidx] / 2;
  1459. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
  1460. larger = magicints[maxidx] / 2;
  1461. i = 0;
  1462. while (i < size) {
  1463. is_small = 0;
  1464. thiscoord = (int *)(luip) + i * 3;
  1465. if (smallidx < maxidx && i >= 1 &&
  1466. abs(thiscoord[0] - prevcoord[0]) < larger &&
  1467. abs(thiscoord[1] - prevcoord[1]) < larger &&
  1468. abs(thiscoord[2] - prevcoord[2]) < larger) {
  1469. is_smaller = 1;
  1470. } else if (smallidx > minidx) {
  1471. is_smaller = -1;
  1472. } else {
  1473. is_smaller = 0;
  1474. }
  1475. if (i + 1 < size) {
  1476. if (abs(thiscoord[0] - thiscoord[3]) < smallnum &&
  1477. abs(thiscoord[1] - thiscoord[4]) < smallnum &&
  1478. abs(thiscoord[2] - thiscoord[5]) < smallnum) {
  1479. /* interchange first with second atom for better
  1480. * compression of water molecules
  1481. */
  1482. tmp = thiscoord[0]; thiscoord[0] = thiscoord[3];
  1483. thiscoord[3] = tmp;
  1484. tmp = thiscoord[1]; thiscoord[1] = thiscoord[4];
  1485. thiscoord[4] = tmp;
  1486. tmp = thiscoord[2]; thiscoord[2] = thiscoord[5];
  1487. thiscoord[5] = tmp;
  1488. is_small = 1;
  1489. }
  1490. }
  1491. tmpcoord[0] = thiscoord[0] - minint[0];
  1492. tmpcoord[1] = thiscoord[1] - minint[1];
  1493. tmpcoord[2] = thiscoord[2] - minint[2];
  1494. if (bitsize == 0) {
  1495. encodebits(buf2, bitsizeint[0], tmpcoord[0]);
  1496. encodebits(buf2, bitsizeint[1], tmpcoord[1]);
  1497. encodebits(buf2, bitsizeint[2], tmpcoord[2]);
  1498. } else {
  1499. encodeints(buf2, 3, bitsize, sizeint, tmpcoord);
  1500. }
  1501. prevcoord[0] = thiscoord[0];
  1502. prevcoord[1] = thiscoord[1];
  1503. prevcoord[2] = thiscoord[2];
  1504. thiscoord = thiscoord + 3;
  1505. i++;
  1506. run = 0;
  1507. if (is_small == 0 && is_smaller == -1)
  1508. is_smaller = 0;
  1509. while (is_small && run < 8*3) {
  1510. tmpsum=0;
  1511. for(j=0;j<3;j++) {
  1512. tmp=thiscoord[j] - prevcoord[j];
  1513. tmpsum+=tmp*tmp;
  1514. }
  1515. if (is_smaller == -1 && tmpsum >= smaller * smaller) {
  1516. is_smaller = 0;
  1517. }
  1518. tmpcoord[run++] = thiscoord[0] - prevcoord[0] + smallnum;
  1519. tmpcoord[run++] = thiscoord[1] - prevcoord[1] + smallnum;
  1520. tmpcoord[run++] = thiscoord[2] - prevcoord[2] + smallnum;
  1521. prevcoord[0] = thiscoord[0];
  1522. prevcoord[1] = thiscoord[1];
  1523. prevcoord[2] = thiscoord[2];
  1524. i++;
  1525. thiscoord = thiscoord + 3;
  1526. is_small = 0;
  1527. if (i < size &&
  1528. abs(thiscoord[0] - prevcoord[0]) < smallnum &&
  1529. abs(thiscoord[1] - prevcoord[1]) < smallnum &&
  1530. abs(thiscoord[2] - prevcoord[2]) < smallnum) {
  1531. is_small = 1;
  1532. }
  1533. }
  1534. if (run != prevrun || is_smaller != 0) {
  1535. prevrun = run;
  1536. encodebits(buf2, 1, 1); /* flag the change in run-length */
  1537. encodebits(buf2, 5, run+is_smaller+1);
  1538. } else {
  1539. encodebits(buf2, 1, 0); /* flag the fact that runlength did not change */
  1540. }
  1541. for (k=0; k < run; k+=3) {
  1542. encodeints(buf2, 3, smallidx, sizesmall, &tmpcoord[k]);
  1543. }
  1544. if (is_smaller != 0) {
  1545. smallidx += is_smaller;
  1546. if (is_smaller < 0) {
  1547. smallnum = smaller;
  1548. smaller = magicints[smallidx-1] / 2;
  1549. } else {
  1550. smaller = smallnum;
  1551. smallnum = magicints[smallidx] / 2;
  1552. }
  1553. sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
  1554. }
  1555. }
  1556. if (buf2[1] != 0) buf2[0]++;
  1557. xdrfile_write_int(buf2,1,xfp); /* buf2[0] holds the length in bytes */
  1558. tmp=xdrfile_write_opaque((char *)&(buf2[3]),(unsigned int)buf2[0],xfp);
  1559. if(tmp==(unsigned int)buf2[0])
  1560. return size;
  1561. else
  1562. return -1;
  1563. }
  1564. /* Dont try do document Fortran interface, since
  1565. * Doxygen barfs at the F77_FUNC macro
  1566. */
  1567. #ifndef DOXYGEN
  1568. /*************************************************************
  1569. * Fortran77 interface for reading/writing portable data *
  1570. * The routine are not threadsafe when called from Fortran *
  1571. * (as they are when called from C) unless you compile with *
  1572. * this file with posix thread support. *
  1573. * Note that these are not multithread-safe. *
  1574. *************************************************************/
  1575. #define MAX_FORTRAN_XDR 1024
  1576. static XDRFILE *f77xdr[MAX_FORTRAN_XDR]; /* array of file handles */
  1577. static int f77init = 1; /* zero array first time */
  1578. /* internal to this file: C<-->Fortran string conversion */
  1579. static int ftocstr(char *dest, int dest_len, char *src, int src_len);
  1580. static int ctofstr(char *dest, int dest_len, char *src);
  1581. void
  1582. F77_FUNC(xdropen,XDROPEN)(int *fid, char *filename, char *mode,
  1583. int fn_len, int mode_len)
  1584. {
  1585. char cfilename[512];
  1586. char cmode[5];
  1587. int i;
  1588. /* zero array at first invocation */
  1589. if(f77init) {
  1590. for(i=0;i<MAX_FORTRAN_XDR;i++)
  1591. f77xdr[i]=NULL;
  1592. f77init=0;
  1593. }
  1594. i=0;
  1595. /* nf77xdr is always smaller or equal to MAX_FORTRAN_XDR */
  1596. while(i<MAX_FORTRAN_XDR && f77xdr[i]!=NULL)
  1597. i++;
  1598. if(i==MAX_FORTRAN_XDR) {
  1599. *fid = -1;
  1600. } else if (ftocstr(cfilename, sizeof(cfilename), filename, fn_len)) {
  1601. *fid = -1;
  1602. } else if (ftocstr(cmode, sizeof(cmode), mode,mode_len)) {
  1603. *fid = -1;
  1604. } else {
  1605. f77xdr[i]=xdrfile_open(cfilename,cmode);
  1606. /* return the index in the array as a fortran file handle */
  1607. *fid=i;
  1608. }
  1609. }
  1610. void
  1611. F77_FUNC(xdrclose,XDRCLOSE)(int *fid)
  1612. {
  1613. /* first close it */
  1614. xdrfile_close(f77xdr[*fid]);
  1615. /* the remove it from file handle list */
  1616. f77xdr[*fid]=NULL;
  1617. }
  1618. void
  1619. F77_FUNC(xdrrint,XDRRINT)(int *fid, int *data, int *ndata, int *ret)
  1620. {
  1621. *ret = xdrfile_read_int(data,*ndata,f77xdr[*fid]);
  1622. }
  1623. void
  1624. F77_FUNC(xdrwint,XDRWINT)(int *fid, int *data, int *ndata, int *ret)
  1625. {
  1626. *ret = xdrfile_write_int(data,*ndata,f77xdr[*fid]);
  1627. }
  1628. void
  1629. F77_FUNC(xdrruint,XDRRUINT)(int *fid, unsigned int *data, int *ndata, int *ret)
  1630. {
  1631. *ret = xdrfile_read_uint(data,*ndata,f77xdr[*fid]);
  1632. }
  1633. void
  1634. F77_FUNC(xdrwuint,XDRWUINT)(int *fid, unsigned int *data, int *ndata, int *ret)
  1635. {
  1636. *ret = xdrfile_write_uint(data,*ndata,f77xdr[*fid]);
  1637. }
  1638. void
  1639. F77_FUNC(xdrrchar,XDRRCHAR)(int *fid, char *ip, int *ndata, int *ret)
  1640. {
  1641. *ret = xdrfile_read_char(ip,*ndata,f77xdr[*fid]);
  1642. }
  1643. void
  1644. F77_FUNC(xdrwchar,XDRWCHAR)(int *fid, char *ip, int *ndata, int *ret)
  1645. {
  1646. *ret = xdrfile_write_char(ip,*ndata,f77xdr[*fid]);
  1647. }
  1648. void
  1649. F77_FUNC(xdrruchar,XDRRUCHAR)(int *fid, unsigned char *ip, int *ndata, int *ret)
  1650. {
  1651. *ret = xdrfile_read_uchar(ip,*ndata,f77xdr[*fid]);
  1652. }
  1653. void
  1654. F77_FUNC(xdrwuchar,XDRWUCHAR)(int *fid, unsigned char *ip, int *ndata, int *ret)
  1655. {
  1656. *ret = xdrfile_write_uchar(ip,*ndata,f77xdr[*fid]);
  1657. }
  1658. void
  1659. F77_FUNC(xdrrshort,XDRRSHORT)(int *fid, short *ip, int *ndata, int *ret)
  1660. {
  1661. *ret = xdrfile_read_short(ip,*ndata,f77xdr[*fid]);
  1662. }
  1663. void
  1664. F77_FUNC(xdrwshort,XDRWSHORT)(int *fid, short *ip, int *ndata, int *ret)
  1665. {
  1666. *ret = xdrfile_write_short(ip,*ndata,f77xdr[*fid]);
  1667. }
  1668. void
  1669. F77_FUNC(xdrrushort,XDRRUSHORT)(int *fid, unsigned short *ip, int *ndata, int *ret)
  1670. {
  1671. *ret = xdrfile_read_ushort(ip,*ndata,f77xdr[*fid]);
  1672. }
  1673. void
  1674. F77_FUNC(xdrwushort,XDRWUSHORT)(int *fid, unsigned short *ip, int *ndata, int *ret)
  1675. {
  1676. *ret = xdrfile_write_ushort(ip,*ndata,f77xdr[*fid]);
  1677. }
  1678. void
  1679. F77_FUNC(xdrrsingle,XDRRSINGLE)(int *fid, float *data, int *ndata, int *ret)
  1680. {
  1681. *ret = xdrfile_read_float(data,*ndata,f77xdr[*fid]);
  1682. }
  1683. void
  1684. F77_FUNC(xdrwsingle,XDRWSINGLE)(int *fid, float *data, int *ndata, int *ret)
  1685. {
  1686. *ret = xdrfile_write_float(data,*ndata,f77xdr[*fid]);
  1687. }
  1688. void
  1689. F77_FUNC(xdrrdouble,XDRRDOUBLE)(int *fid, double *data, int *ndata, int *ret)
  1690. {
  1691. *ret = xdrfile_read_double(data,*ndata,f77xdr[*fid]);
  1692. }
  1693. void
  1694. F77_FUNC(xdrwdouble,XDRWDOUBLE)(int *fid, double *data, int *ndata, int *ret)
  1695. {
  1696. *ret = xdrfile_write_double(data,*ndata,f77xdr[*fid]);
  1697. }
  1698. static int ftocstr(char *dest, int destlen, char *src, int srclen)
  1699. {
  1700. char *p;
  1701. p = src + srclen;
  1702. while ( --p >= src && *p == ' ' );
  1703. srclen = p - src + 1;
  1704. destlen--;
  1705. dest[0] = 0;
  1706. if (srclen > destlen)
  1707. return 1;
  1708. while (srclen--)
  1709. (*dest++ = *src++);
  1710. *dest = '\0';
  1711. return 0;
  1712. }
  1713. static int ctofstr(char *dest, int destlen, char *src)
  1714. {
  1715. while (destlen && *src) {
  1716. *dest++ = *src++;
  1717. destlen--;
  1718. }
  1719. while (destlen--)
  1720. *dest++ = ' ';
  1721. return 0;
  1722. }
  1723. void
  1724. F77_FUNC(xdrrstring,XDRRSTRING)(int *fid, char *str, int *ret, int len)
  1725. {
  1726. char *cstr;
  1727. if((cstr=(char*)malloc((len+1)*sizeof(char)))==NULL) {
  1728. *ret = 0;
  1729. return;
  1730. }
  1731. if (ftocstr(cstr, len+1, str, len)) {
  1732. *ret = 0;
  1733. free(cstr);
  1734. return;
  1735. }
  1736. *ret = xdrfile_read_string(cstr, len+1,f77xdr[*fid]);
  1737. ctofstr( str, len , cstr);
  1738. free(cstr);
  1739. }
  1740. void
  1741. F77_FUNC(xdrwstring,XDRWSTRING)(int *fid, char *str, int *ret, int len)
  1742. {
  1743. char *cstr;
  1744. if((cstr=(char*)malloc((len+1)*sizeof(char)))==NULL) {
  1745. *ret = 0;
  1746. return;
  1747. }
  1748. if (ftocstr(cstr, len+1, str, len)) {
  1749. *ret = 0;
  1750. free(cstr);
  1751. return;
  1752. }
  1753. *ret = xdrfile_write_string(cstr, f77xdr[*fid]);
  1754. ctofstr( str, len , cstr);
  1755. free(cstr);
  1756. }
  1757. void
  1758. F77_FUNC(xdrropaque,XDRROPAQUE)(int *fid, char *data, int *ndata, int *ret)
  1759. {
  1760. *ret = xdrfile_read_opaque(data,*ndata,f77xdr[*fid]);
  1761. }
  1762. void
  1763. F77_FUNC(xdrwopaque,XDRWOPAQUE)(int *fid, char *data, int *ndata, int *ret)
  1764. {
  1765. *ret = xdrfile_write_opaque(data,*ndata,f77xdr[*fid]);
  1766. }
  1767. /* Write single-precision compressed 3d coordinates */
  1768. void
  1769. F77_FUNC(xdrccs,XDRCCS)(int *fid, float *data, int *ncoord,
  1770. float *prec

Large files files are truncated, but you can click here to view the full file