PageRenderTime 56ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/wrfv2_fire/external/io_grib2/bacio-1.3/bacio.v1.3.c

http://github.com/jbeezley/wrf-fire
C | 545 lines | 429 code | 30 blank | 86 comment | 118 complexity | 3ed8915f57764da11b36266ee4159f76 MD5 | raw file
Possible License(s): AGPL-1.0
  1. /* Fortran-callable routines to read and write characther (bacio) and */
  2. /* numeric (banio) data byte addressably */
  3. /* Robert Grumbine 16 March 1998 */
  4. /* v1.1: Put diagnostic output under control of define VERBOSE or QUIET */
  5. /* Add option of non-seeking read/write */
  6. /* Return code for fewer data read/written than requested */
  7. /* v1.2: Add cray compatibility 20 April 1998 */
  8. #include <stdio.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <fcntl.h>
  12. #include <unistd.h>
  13. #ifdef MACOS
  14. #include <sys/malloc.h>
  15. #else
  16. #include <malloc.h>
  17. #endif
  18. #include <ctype.h>
  19. #include <string.h>
  20. /* Include the C library file for definition/control */
  21. /* Things that might be changed for new systems are there. */
  22. /* This source file should not (need to) be edited, merely recompiled */
  23. #include "clib.h"
  24. /* Return Codes: */
  25. /* 0 All was well */
  26. /* -1 Tried to open read only _and_ write only */
  27. /* -2 Tried to read and write in the same call */
  28. /* -3 Internal failure in name processing */
  29. /* -4 Failure in opening file */
  30. /* -5 Tried to read on a write-only file */
  31. /* -6 Failed in read to find the 'start' location */
  32. /* -7 Tried to write to a read only file */
  33. /* -8 Failed in write to find the 'start' location */
  34. /* -9 Error in close */
  35. /* -10 Read or wrote fewer data than requested */
  36. /* Note: In your Fortran code, call bacio, not bacio_. */
  37. /*int bacio_(int * mode, int * start, int * size, int * no, int * nactual, */
  38. /* int * fdes, const char *fname, char *data, int namelen, */
  39. /* int datanamelen) */
  40. /* Arguments: */
  41. /* Mode is the integer specifying operations to be performed */
  42. /* see the clib.inc file for the values. Mode is obtained */
  43. /* by adding together the values corresponding to the operations */
  44. /* The best method is to include the clib.inc file and refer to the */
  45. /* names for the operations rather than rely on hard-coded values */
  46. /* Start is the byte number to start your operation from. 0 is the first */
  47. /* byte in the file, not 1. */
  48. /* Newpos is the position in the file after a read or write has been */
  49. /* performed. You'll need this if you're doing 'seeking' read/write */
  50. /* Size is the size of the objects you are trying to read. Rely on the */
  51. /* values in the locale.inc file. Types are CHARACTER, INTEGER, REAL, */
  52. /* COMPLEX. Specify the correct value by using SIZEOF_type, where type */
  53. /* is one of these. (After having included the locale.inc file) */
  54. /* no is the number of things to read or write (characters, integers, */
  55. /* whatever) */
  56. /* nactual is the number of things actually read or written. Check that */
  57. /* you got what you wanted. */
  58. /* fdes is an integer 'file descriptor'. This is not a Fortran Unit Number */
  59. /* You can use it, however, to refer to files you've previously opened. */
  60. /* fname is the name of the file. This only needs to be defined when you */
  61. /* are opening a file. It must be (on the Fortran side) declared as */
  62. /* CHARACTER*N, where N is a length greater than or equal to the length */
  63. /* of the file name. CHARACTER*1 fname[80] (for example) will fail. */
  64. /* data is the name of the entity (variable, vector, array) that you want */
  65. /* to write data out from or read it in to. The fact that C is declaring */
  66. /* it to be a char * does not affect your fortran. */
  67. /* namelen - Do NOT specify this. It is created automagically by the */
  68. /* Fortran compiler */
  69. /* datanamelen - Ditto */
  70. int BACIO
  71. (int * mode, int * start, int *newpos, int * size, int * no,
  72. int * nactual, int * fdes, const char *fname, char *datary,
  73. int namelen, int datanamelen)
  74. {
  75. int i, j, jret, seekret;
  76. char *realname, *tempchar;
  77. int tcharval;
  78. size_t count;
  79. /* Initialization(s) */
  80. *nactual = 0;
  81. /* Check for illegal combinations of options */
  82. if (( BAOPEN_RONLY & *mode) &&
  83. ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
  84. #ifdef VERBOSE
  85. printf("illegal -- trying to open both read only and write only\n");
  86. #endif
  87. return -1;
  88. }
  89. if ( (BAREAD & *mode ) && (BAWRITE & *mode) ) {
  90. #ifdef VERBOSE
  91. printf("illegal -- trying to both read and write in the same call\n");
  92. #endif
  93. return -2;
  94. }
  95. /* This section handles Fortran to C translation of strings so as to */
  96. /* be able to open the files Fortran is expecting to be opened. */
  97. #ifdef CRAY90
  98. namelen = _fcdlen(fcd_fname);
  99. fname = _fcdtocp(fcd_fname);
  100. #endif
  101. realname = (char *) malloc( (namelen+1) * sizeof(char) ) ;
  102. if (realname == NULL) {
  103. #ifdef VERBOSE
  104. printf("failed to mallocate realname %d = namelen\n", namelen);
  105. fflush(stdout);
  106. #endif
  107. return -3;
  108. }
  109. if ( (BAOPEN_RONLY & *mode) || (BAOPEN_WONLY & *mode) ||
  110. (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ||
  111. (BAOPEN_RW & *mode) ) {
  112. #ifdef VERBOSE
  113. printf("Will be opening a file %s %d\n", fname, namelen); fflush(stdout);
  114. printf("Strlen %d namelen %d\n", strlen(fname), namelen); fflush(stdout);
  115. #endif
  116. tempchar = (char *) malloc(sizeof(char) * 1 ) ;
  117. i = 0;
  118. j = 0;
  119. *tempchar = fname[i];
  120. tcharval = *tempchar;
  121. while (i == j && i < namelen ) {
  122. fflush(stdout);
  123. if ( isgraph(tcharval) ) {
  124. realname[j] = fname[i];
  125. j += 1;
  126. }
  127. i += 1;
  128. *tempchar = fname[i];
  129. tcharval = *tempchar;
  130. }
  131. #ifdef VERBOSE
  132. printf("i,j = %d %d\n",i,j); fflush(stdout);
  133. #endif
  134. realname[j] = '\0';
  135. free(tempchar);
  136. }
  137. /* Open files with correct read/write and file permission. */
  138. if (BAOPEN_RONLY & *mode) {
  139. #ifdef VERBOSE
  140. printf("open read only %s\n", realname);
  141. #endif
  142. *fdes = open(realname, O_RDONLY , S_IRWXU | S_IRWXG | S_IRWXO );
  143. }
  144. else if (BAOPEN_WONLY & *mode ) {
  145. #ifdef VERBOSE
  146. printf("open write only %s\n", realname);
  147. #endif
  148. *fdes = open(realname, O_WRONLY | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
  149. }
  150. else if (BAOPEN_WONLY_TRUNC & *mode ) {
  151. #ifdef VERBOSE
  152. printf("open write only with truncation %s\n", realname);
  153. #endif
  154. *fdes = open(realname, O_WRONLY | O_CREAT | O_TRUNC , S_IRWXU | S_IRWXG | S_IRWXO );
  155. }
  156. else if (BAOPEN_WONLY_APPEND & *mode ) {
  157. #ifdef VERBOSE
  158. printf("open write only with append %s\n", realname);
  159. #endif
  160. *fdes = open(realname, O_WRONLY | O_CREAT | O_APPEND , S_IRWXU | S_IRWXG | S_IRWXO );
  161. }
  162. else if (BAOPEN_RW & *mode) {
  163. #ifdef VERBOSE
  164. printf("open read-write %s\n", realname);
  165. #endif
  166. *fdes = open(realname, O_RDWR | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
  167. }
  168. else {
  169. #ifdef VERBOSE
  170. printf("no openings\n");
  171. #endif
  172. }
  173. if (*fdes < 0) {
  174. #ifdef VERBOSE
  175. printf("error in file descriptor! *fdes %d\n", *fdes);
  176. #endif
  177. return -4;
  178. }
  179. else {
  180. #ifdef VERBOSE
  181. printf("file descriptor = %d\n",*fdes );
  182. #endif
  183. }
  184. /* Read data as requested */
  185. if (BAREAD & *mode &&
  186. ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
  187. #ifdef VERBOSE
  188. printf("Error, trying to read while in write only mode!\n");
  189. #endif
  190. return -5;
  191. }
  192. else if (BAREAD & *mode ) {
  193. /* Read in some data */
  194. if (! (*mode & NOSEEK) ) {
  195. seekret = lseek(*fdes, *start, SEEK_SET);
  196. if (seekret == -1) {
  197. #ifdef VERBOSE
  198. printf("error in seeking to %d\n",*start);
  199. #endif
  200. return -6;
  201. }
  202. #ifdef VERBOSE
  203. else {
  204. printf("Seek successful, seek ret %d, start %d\n", seekret, *start);
  205. }
  206. #endif
  207. }
  208. #ifdef CRAY90
  209. datary = _fcdtocp(fcd_datary);
  210. #endif
  211. if (datary == NULL) {
  212. printf("Massive catastrophe -- datary pointer is NULL\n");
  213. return -666;
  214. }
  215. #ifdef VERBOSE
  216. printf("file descriptor, datary = %d %d\n", *fdes, (int) datary);
  217. #endif
  218. count = (size_t) *no;
  219. jret = read(*fdes, (void *) datary, count);
  220. if (jret != *no) {
  221. #ifdef VERBOSE
  222. printf("did not read in the requested number of bytes\n");
  223. printf("read in %d bytes instead of %d \n",jret, *no);
  224. #endif
  225. }
  226. else {
  227. #ifdef VERBOSE
  228. printf("read in %d bytes requested \n", *no);
  229. #endif
  230. }
  231. *nactual = jret;
  232. *newpos = *start + jret;
  233. }
  234. /* Done with reading */
  235. /* See if we should be writing */
  236. if ( BAWRITE & *mode && BAOPEN_RONLY & *mode ) {
  237. #ifdef VERBOSE
  238. printf("Trying to write on a read only file \n");
  239. #endif
  240. return -7;
  241. }
  242. else if ( BAWRITE & *mode ) {
  243. if (! (*mode & NOSEEK) ) {
  244. seekret = lseek(*fdes, *start, SEEK_SET);
  245. if (seekret == -1) {
  246. #ifdef VERBOSE
  247. printf("error in seeking to %d\n",*start);
  248. #endif
  249. return -8;
  250. }
  251. }
  252. #ifdef CRAY90
  253. datary = _fcdtocp(fcd_datary);
  254. #endif
  255. if (datary == NULL) {
  256. printf("Massive catastrophe -- datary pointer is NULL\n");
  257. return -666;
  258. }
  259. #ifdef VERBOSE
  260. printf("write file descriptor, datary = %d %d\n", *fdes, (int) datary);
  261. #endif
  262. count = (size_t) *no;
  263. jret = write(*fdes, (void *) datary, count);
  264. if (jret != *no) {
  265. #ifdef VERBOSE
  266. printf("did not write out the requested number of bytes\n");
  267. printf("wrote %d bytes instead\n", jret);
  268. #endif
  269. *nactual = jret;
  270. *newpos = *start + jret;
  271. }
  272. else {
  273. #ifdef VERBOSE
  274. printf("wrote %d bytes \n", jret);
  275. #endif
  276. *nactual = jret;
  277. *newpos = *start + jret;
  278. }
  279. }
  280. /* Done with writing */
  281. /* Close file if requested */
  282. if (BACLOSE & *mode ) {
  283. jret = close(*fdes);
  284. if (jret != 0) {
  285. #ifdef VERBOSE
  286. printf("close failed! jret = %d\n",jret);
  287. #endif
  288. return -9;
  289. }
  290. }
  291. /* Done closing */
  292. free(realname);
  293. /* Check that if we were reading or writing, that we actually got what */
  294. /* we expected, else return a -10. Return 0 (success) if we're here */
  295. /* and weren't reading or writing */
  296. if ( (*mode & BAREAD || *mode & BAWRITE) && (*nactual != *no) ) {
  297. return -10;
  298. }
  299. else {
  300. return 0;
  301. }
  302. }
  303. int BANIO
  304. (int * mode, int * start, int *newpos, int * size, int * no,
  305. int * nactual, int * fdes, const char *fname, char *datary,
  306. int namelen )
  307. {
  308. int i, j, jret, seekret;
  309. char *realname, *tempchar;
  310. int tcharval;
  311. /* Initialization(s) */
  312. *nactual = 0;
  313. /* Check for illegal combinations of options */
  314. if (( BAOPEN_RONLY & *mode) &&
  315. ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
  316. #ifdef VERBOSE
  317. printf("illegal -- trying to open both read only and write only\n");
  318. #endif
  319. return -1;
  320. }
  321. if ( (BAREAD & *mode ) && (BAWRITE & *mode) ) {
  322. #ifdef VERBOSE
  323. printf("illegal -- trying to both read and write in the same call\n");
  324. #endif
  325. return -2;
  326. }
  327. /* This section handles Fortran to C translation of strings so as to */
  328. /* be able to open the files Fortran is expecting to be opened. */
  329. #ifdef CRAY90
  330. namelen = _fcdlen(fcd_fname);
  331. fname = _fcdtocp(fcd_fname);
  332. #endif
  333. if ( (BAOPEN_RONLY & *mode) || (BAOPEN_WONLY & *mode) ||
  334. (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ||
  335. (BAOPEN_RW & *mode) ) {
  336. #ifdef VERBOSE
  337. printf("Will be opening a file %s %d\n", fname, namelen); fflush(stdout);
  338. printf("Strlen %d namelen %d\n", strlen(fname), namelen); fflush(stdout);
  339. #endif
  340. realname = (char *) malloc( (namelen+1) * sizeof(char) ) ;
  341. if (realname == NULL) {
  342. #ifdef VERBOSE
  343. printf("failed to mallocate realname %d = namelen\n", namelen);
  344. fflush(stdout);
  345. #endif
  346. return -3;
  347. }
  348. tempchar = (char *) malloc(sizeof(char) * 1 ) ;
  349. i = 0;
  350. j = 0;
  351. *tempchar = fname[i];
  352. tcharval = *tempchar;
  353. while (i == j && i < namelen ) {
  354. fflush(stdout);
  355. if ( isgraph(tcharval) ) {
  356. realname[j] = fname[i];
  357. j += 1;
  358. }
  359. i += 1;
  360. *tempchar = fname[i];
  361. tcharval = *tempchar;
  362. }
  363. #ifdef VERBOSE
  364. printf("i,j = %d %d\n",i,j); fflush(stdout);
  365. #endif
  366. realname[j] = '\0';
  367. }
  368. /* Open files with correct read/write and file permission. */
  369. if (BAOPEN_RONLY & *mode) {
  370. #ifdef VERBOSE
  371. printf("open read only %s\n", realname);
  372. #endif
  373. *fdes = open(realname, O_RDONLY , S_IRWXU | S_IRWXG | S_IRWXO );
  374. }
  375. else if (BAOPEN_WONLY & *mode ) {
  376. #ifdef VERBOSE
  377. printf("open write only %s\n", realname);
  378. #endif
  379. *fdes = open(realname, O_WRONLY | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
  380. }
  381. else if (BAOPEN_WONLY_TRUNC & *mode ) {
  382. #ifdef VERBOSE
  383. printf("open write only with truncation %s\n", realname);
  384. #endif
  385. *fdes = open(realname, O_WRONLY | O_CREAT | O_TRUNC , S_IRWXU | S_IRWXG | S_IRWXO );
  386. }
  387. else if (BAOPEN_WONLY_APPEND & *mode ) {
  388. #ifdef VERBOSE
  389. printf("open write only with append %s\n", realname);
  390. #endif
  391. *fdes = open(realname, O_WRONLY | O_CREAT | O_APPEND , S_IRWXU | S_IRWXG | S_IRWXO );
  392. }
  393. else if (BAOPEN_RW & *mode) {
  394. #ifdef VERBOSE
  395. printf("open read-write %s\n", realname);
  396. #endif
  397. *fdes = open(realname, O_RDWR | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
  398. }
  399. else {
  400. #ifdef VERBOSE
  401. printf("no openings\n");
  402. #endif
  403. }
  404. if (*fdes < 0) {
  405. #ifdef VERBOSE
  406. printf("error in file descriptor! *fdes %d\n", *fdes);
  407. #endif
  408. return -4;
  409. }
  410. else {
  411. #ifdef VERBOSE
  412. printf("file descriptor = %d\n",*fdes );
  413. #endif
  414. }
  415. /* Read data as requested */
  416. if (BAREAD & *mode &&
  417. ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
  418. #ifdef VERBOSE
  419. printf("Error, trying to read while in write only mode!\n");
  420. #endif
  421. return -5;
  422. }
  423. else if (BAREAD & *mode ) {
  424. /* Read in some data */
  425. if (! (*mode & NOSEEK) ) {
  426. seekret = lseek(*fdes, *start, SEEK_SET);
  427. if (seekret == -1) {
  428. #ifdef VERBOSE
  429. printf("error in seeking to %d\n",*start);
  430. #endif
  431. return -6;
  432. }
  433. #ifdef VERBOSE
  434. else {
  435. printf("Seek successful, seek ret %d, start %d\n", seekret, *start);
  436. }
  437. #endif
  438. }
  439. jret = read(*fdes, datary, *no*(*size) );
  440. if (jret != *no*(*size) ) {
  441. #ifdef VERBOSE
  442. printf("did not read in the requested number of items\n");
  443. printf("read in %d items of %d \n",jret/(*size), *no);
  444. #endif
  445. *nactual = jret/(*size);
  446. *newpos = *start + jret;
  447. }
  448. #ifdef VERBOSE
  449. printf("read in %d items \n", jret/(*size));
  450. #endif
  451. *nactual = jret/(*size);
  452. *newpos = *start + jret;
  453. }
  454. /* Done with reading */
  455. /* See if we should be writing */
  456. if ( BAWRITE & *mode && BAOPEN_RONLY & *mode ) {
  457. #ifdef VERBOSE
  458. printf("Trying to write on a read only file \n");
  459. #endif
  460. return -7;
  461. }
  462. else if ( BAWRITE & *mode ) {
  463. if (! (*mode & NOSEEK) ) {
  464. seekret = lseek(*fdes, *start, SEEK_SET);
  465. if (seekret == -1) {
  466. #ifdef VERBOSE
  467. printf("error in seeking to %d\n",*start);
  468. #endif
  469. return -8;
  470. }
  471. #ifdef VERBOSE
  472. else {
  473. printf("Seek successful, seek ret %d, start %d\n", seekret, *start);
  474. }
  475. #endif
  476. }
  477. jret = write(*fdes, datary, *no*(*size));
  478. if (jret != *no*(*size)) {
  479. #ifdef VERBOSE
  480. printf("did not write out the requested number of items\n");
  481. printf("wrote %d items instead\n", jret/(*size) );
  482. #endif
  483. *nactual = jret/(*size) ;
  484. *newpos = *start + jret;
  485. }
  486. else {
  487. #ifdef VERBOSE
  488. printf("wrote %d items \n", jret/(*size) );
  489. #endif
  490. *nactual = jret/(*size) ;
  491. *newpos = *start + jret;
  492. }
  493. }
  494. /* Done with writing */
  495. /* Close file if requested */
  496. if (BACLOSE & *mode ) {
  497. jret = close(*fdes);
  498. if (jret != 0) {
  499. #ifdef VERBOSE
  500. printf("close failed! jret = %d\n",jret);
  501. #endif
  502. return -9;
  503. }
  504. }
  505. /* Done closing */
  506. /* Check that if we were reading or writing, that we actually got what */
  507. /* we expected, else return a -10. Return 0 (success) if we're here */
  508. /* and weren't reading or writing */
  509. if ( (*mode & BAREAD || *mode & BAWRITE) && (*nactual != *no) ) {
  510. return -10;
  511. }
  512. else {
  513. return 0;
  514. }
  515. }