OpenCMISS-Iron Internal API Documentation
binary_file_c.c
Go to the documentation of this file.
1 /* \file
2  * \author Chris Bradley
3  * \brief This file provides c utility routines for the binary_file module
4  *.
5  * \section LICENSE
6  *
7  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
8  *
9  * The contents of this file are subject to the Mozilla Public License
10  * Version 1.1 (the "License"); you may not use this file except in
11  * compliance with the License. You may obtain a copy of the License at
12  * http://www.mozilla.org/MPL/
13  *
14  * Software distributed under the License is distributed on an "AS IS"
15  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
16  * License for the specific language governing rights and limitations
17  * under the License.
18  *
19  * The Original Code is OpenCMISS
20  *
21  * The Initial Developer of the Original Code is University of Auckland,
22  * Auckland, New Zealand, the University of Oxford, Oxford, United
23  * Kingdom and King's College, London, United Kingdom. Portions created
24  * by the University of Auckland, the University of Oxford and King's
25  * College, London are Copyright (C) 2007-2010 by the University of
26  * Auckland, the University of Oxford and King's College, London.
27  * All Rights Reserved.
28  *
29  * Contributor(s):
30  *
31  * Alternatively, the contents of this file may be used under the terms of
32  * either the GNU General Public License Version 2 or later (the "GPL"), or
33  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
34  * in which case the provisions of the GPL or the LGPL are applicable instead
35  * of those above. If you wish to allow use of your version of this file only
36  * under the terms of either the GPL or the LGPL, and not to allow others to
37  * use your version of this file under the terms of the MPL, indicate your
38  * decision by deleting the provisions above and replace them with the notice
39  * and other provisions required by the GPL or the LGPL. If you do not delete
40  * the provisions above, a recipient may use your version of this file under
41  * the terms of any one of the MPL, the GPL or the LGPL.
42  *
43  */
44 
45 /*
46 File: binary_file.c
47 ===================
48 
49 This file provides c utility routines for the binary_file module.
50 
51 Functions included:
52 
53 BinaryCloseFile Close a binary file
54 BinaryOpenFile Open a binary file
55 BinaryReadFile Read data from a binary file
56 BinarySetFile Sets the position of a binary file
57 BinarySkipFile Skip bytes in a binary file
58 BinaryWriteFile Write data to a binary file
59 IsBinaryFileOpen Returns whether or not a binary file is open
60 IsEndBinaryFile Returns whether or not at eof of a binary file
61 
62 */
63 
64 /* Included files */
65 
66 #include <stdio.h>
67 #include <stdlib.h>
68 #include <string.h>
69 
70 #ifdef VMS
71 #define BinaryCloseFile BINARYCLOSEFILE
72 #define BinaryOpenFile BINARYOPENFILE
73 #define BinaryReadFile BINARYREADFILE
74 #define BinarySetFile BINARYSETFILE
75 #define BinarySkipFile BINARYSKIPFILE
76 #define BinaryWriteFile BINARYWRITEFILE
77 #define IsBinaryFileOpen ISBINARYFILEOPEN
78 #define IsEndBinaryFile ISENDBINARYFILE
79 #endif
80 #ifdef mips
81 #define BinaryCloseFile binaryclosefile_
82 #define BinaryOpenFile binaryopenfile_
83 #define BinaryReadFile binaryreadfile_
84 #define BinarySetFile binarysetfile_
85 #define BinarySkipFile binaryskipfile_
86 #define BinaryWriteFile binarywritefile_
87 #define IsBinaryFileOpen isbinaryfileopen_
88 #define IsEndBinaryFile isendbinaryfile_
89 #endif
90 #ifdef WIN32
91 #define BinaryCloseFile binaryclosefile
92 #define BinaryOpenFile binaryopenfile
93 #define BinaryReadFile binaryreadfile
94 #define BinarySetFile binarysetfile
95 #define BinarySkipFile binaryskipfile
96 #define BinaryWriteFile binarywritefile
97 #define IsBinaryFileOpen isbinaryfileopen
98 #define IsEndBinaryFile isendbinaryfile
99 #endif
100 #ifdef linux
101 #define BinaryCloseFile binaryclosefile
102 #define BinaryOpenFile binaryopenfile
103 #define BinaryReadFile binaryreadfile_
104 #define BinarySetFile binarysetfile
105 #define BinarySkipFile binaryskipfile
106 #define BinaryWriteFile binarywritefile_
107 #define IsBinaryFileOpen isbinaryfileopen
108 #define IsEndBinaryFile isendbinaryfile_
109 #endif
110 
111 /* Item Type defines */
112 /* These should be the same as those in constants.f90 */
113 #define INTEGERTYPE 1
114 #define SHORTINTTYPE 2
115 #define LONGINTTYPE 3
116 #define FLOATTYPE 4
117 #define DOUBLETYPE 5
118 #define QUADRUPLETYPE 6
119 #define CHARTYPE 7
120 #define LOGICALTYPE 8
121 #define COMPLEXTYPE 9
122 #define DOUBLECOMPLEXTYPE 10
123 #define QUADRUPLECOMPLEXTYPE 11
124 
125 /* Binary file defines */
126 /* These should be the same as those in binary_file.f90 */
127 #define MAXBINFILES 99
128 #define SAMEENDIAN 0
129 #define FLIPENDIAN 1
130 
131 /* Type definitions */
132 
133 typedef int logical;
134 
135 /* Function prototypes */
136 
137 void BinaryCloseFile(int *fileid,
138  int *err,
139  char *error_string);
140 void BinaryOpenFile(int *fileid,
141  char *filename,
142  char* access_code,
143  int *err,
144  char *error_string);
145 void BinaryReadFile(int *fileid,
146  int *endian,
147  int *number_of_items,
148  int *item_type,
149  char *data,
150  int *err,
151  char *error_string);
152 void BinarySetFile(int *fileid,
153  int *set_code,
154  int *err,
155  char *error_string);
156 void BinarySkipFile(int *fileid,
157  int *number_of_bytes,
158  int *err,
159  char *error_string);
160 void BinaryWriteFile(int *fileid,
161  int *endian,
162  int *number_of_items,
163  int *item_type,
164  char *data,
165  int *err,
166  char *error_string);
167 void IsBinaryFileOpen(int *fileid,
168  int *returncode,
169  int *err,
170  char *error_string);
171 void IsEndBinaryFile(int *fileid,
172  int *returncode,
173  int *err,
174  char *error_string);
175 
176 /* Function Definitions */
177 
178 
179 /* Global variables */
180 
182  {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
183  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
184  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
185  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
186  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
187  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
188  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
189  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
190  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
191  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
192  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
193 
194 /* Code */
195 
196 void BinaryCloseFile(int *fileid,
197  int *err,
198  char *error_string)
199 
200 /*
201 Closes the binary file specified by fileid.
202 */
203 
204 {
205  if((*fileid >= 1) && (*fileid <= MAXBINFILES-1))
206  {
207  if(!binaryfiles[*fileid-1])
208  {
209  *err = 0;
210  }
211  else
212  {
213  *err = fclose(binaryfiles[*fileid-1]);
214  binaryfiles[*fileid-1] = (FILE *)NULL;
215  if(*err != 0)
216  {
217  strcpy(error_string,">>ERROR: error closing binary file");
218  }
219  }
220  }
221  else
222  {
223  *err=1;
224  strcpy(error_string,">>ERROR: file ID is out of range");
225  }
226 }
227 
228 void BinaryOpenFile(int *fileid,
229  char *filename,
230  char *access_code,
231  int *err,
232  char *error_string)
233 
234 /*
235 Opens a binary file specified by fileid and name filename.
236 */
237 
238 {
239  if((*fileid >= 1) && (*fileid <= MAXBINFILES-1))
240  {
241  if(binaryfiles[*fileid-1])
242  {
243  *err=1;
244  strcpy(error_string,">>ERROR: binary file is already open");
245  }
246  else
247  {
248  if(binaryfiles[*fileid-1] = fopen(filename,access_code))
249  {
250  *err=0;
251  }
252  else
253  {
254  *err=1;
255  strcpy(error_string,">>ERROR: binary file could not be opened");
256  }
257  }
258  }
259  else
260  {
261  *err=1;
262  strcpy(error_string,">>ERROR: file ID is out of range");
263  }
264 }
265 
266 void BinaryReadFile(int *fileid,
267  int *endian,
268  int *number_of_items,
269  int *item_type,
270  char *data,
271  int *err,
272  char *error_string)
273 
274 /*
275 Reads number_of_items of data of a type given by item_type from
276 a binary file specified by fileid into an array iven by data.
277 
278 The default endian ordering is big endian. This is specified by
279 endian=0. If little endian is required endian must be set to a number
280 other than 0.
281 
282 */
283 
284 {
285  int i,item_size,j,number_of_bytes,start_byte,temp;
286  FILE* binaryfile;
287 
288  if((*fileid >= 1) && (*fileid <= MAXBINFILES-1))
289  {
290  binaryfile=binaryfiles[*fileid-1];
291  if(!binaryfile)
292  {
293  *err = 1;
294  strcpy(error_string,">>ERROR: binary file is not open");
295  }
296  else
297  {
298  if(INTEGERTYPE == *item_type)
299  {
300  /* Integer data */
301  item_size=sizeof(int);
302  }
303  else if(FLOATTYPE == *item_type)
304  {
305  /* Float data */
306  item_size=sizeof(float);
307  }
308  else if(DOUBLETYPE == *item_type)
309  /* Double data */
310  {
311  item_size=sizeof(double);
312  }
313  else if(CHARTYPE == *item_type)
314  /* Character data */
315  {
316  item_size=sizeof(char);
317  }
318  else if(LOGICALTYPE == *item_type)
319  /* Logical data */
320  {
321  item_size=sizeof(logical);
322  }
323  else if(SHORTINTTYPE == *item_type)
324  /* Short integer data */
325  {
326  item_size=sizeof(short int);
327  }
328  else
329  {
330  *err=1;
331  strcpy(error_string,">>ERROR: Invalid item type");
332  }
333 
334  if(SAMEENDIAN == *endian || CHARTYPE == *item_type)
335  {
336  /* Default big endian format */
337  number_of_bytes=*number_of_items * item_size;
338  for(i = 0; i < number_of_bytes ; i++)
339  {
340  temp = getc(binaryfile);
341  data[i] = (char)temp;
342  }
343  if(CHARTYPE == *item_type)
344  {
345  data[number_of_bytes]='\0';
346  }
347  }
348  else
349  {
350  /* Little endian format - must reverse byte ordering */
351  for(i = 0; i < *number_of_items; i++)
352  {
353  start_byte=i*item_size;
354  for(j = 0; j < item_size; j++)
355  {
356  temp = getc(binaryfile);
357  data[start_byte+item_size-j-1] = (char)temp;
358  }
359  }
360  }
361 
362  *err=ferror(binaryfile);
363  if(*err != 0)
364  {
365  strcpy(error_string,">>ERROR: error reading binary file");
366  }
367  }
368  }
369  else
370  {
371  *err=1;
372  strcpy(error_string,">>ERROR: file ID is out of range");
373  }
374 }
375 
376 void BinarySetFile(int *fileid,
377  int *set_code,
378  int *err,
379  char *error_string)
380 
381 /*
382 Sets the position of the file pointer of the binary file (given
383 by fileid) to either the beginning (set_code=0), current
384 position (set_code=1) or end (set_code=2) of the file.
385 */
386 
387 {
388  FILE* binaryfile;
389 
390  if((*fileid >= 1) && (*fileid <= MAXBINFILES-1))
391  {
392  binaryfile=binaryfiles[*fileid-1];
393  if(!binaryfile)
394  {
395  *err = 1;
396  strcpy(error_string,">>ERROR: binary file is not open");
397  }
398  else
399  {
400  switch(*set_code)
401  {
402  case 0: /* Beginning of a file */
403  {
404  *err=fseek(binaryfile,(long)0,SEEK_SET);
405  if(*err != 0)
406  {
407  strcpy(error_string,">>ERROR: Could not set to beginning of file");
408  }
409  } break;
410  case 1: /* Current file position */
411  {
412  *err=fseek(binaryfile,(long)0,SEEK_CUR);
413  if(*err != 0)
414  {
415  strcpy(error_string,">>ERROR: Could not set to current file position");
416  }
417  } break;
418  case 2: /* End of file */
419  {
420  *err=fseek(binaryfile,(long)0,SEEK_END);
421  if(*err != 0)
422  {
423  strcpy(error_string,">>ERROR: Could not set to end of file position");
424  }
425  } break;
426  default:
427  {
428  *err=1;
429  strcpy(error_string,">>ERROR: Invalid set_code");
430  } break;
431  }
432  }
433  }
434  else
435  {
436  *err=1;
437  strcpy(error_string,">>ERROR: file ID is out of range");
438  }
439 }
440 
441 void BinarySkipFile(int *fileid,
442  int *number_of_bytes,
443  int *err,
444  char *error_string)
445 
446 /*
447 Skips number_of_bytes bytes of data in a binary file specified
448 by fileid.
449 */
450 
451 {
452  int i,temp;
453  FILE* binaryfile;
454 
455  if((*fileid >= 1) && (*fileid <= MAXBINFILES-1))
456  {
457  binaryfile=binaryfiles[*fileid-1];
458  if(!binaryfile)
459  {
460  *err = 1;
461  strcpy(error_string,">>ERROR: binary file is not open");
462  }
463  else
464  {
465  for(i = 0; i < *number_of_bytes ; i++)
466  {
467  temp = getc(binaryfile);
468  }
469 
470  *err=ferror(binaryfile);
471  if(*err != 0)
472  {
473  strcpy(error_string,">>ERROR: error skipping binary file");
474  }
475  }
476  }
477  else
478  {
479  *err=1;
480  strcpy(error_string,">>ERROR: file ID is out of range");
481  }
482 }
483 
484 void BinaryWriteFile(int *fileid,
485  int *endian,
486  int *number_of_items,
487  int *item_type,
488  char *data,
489  int *err,
490  char *error_string)
491 
492 /*
493 Writes number_of_items of data of a type given byitem_type to a
494 binary file specified by fileid from an array given by data.
495 
496 The default endian ordering is big endian. This is specified by
497 endian=0. If little endian is required endian must be set to a number
498 other than 0.
499 
500 */
501 
502 {
503  int i,item_size,j,number_of_bytes,start_byte;
504  FILE* binaryfile;
505 
506  if((*fileid >= 1) && (*fileid <= MAXBINFILES-1))
507  {
508  binaryfile=binaryfiles[*fileid-1];
509  if(!binaryfile)
510  {
511  *err = 1;
512  strcpy(error_string,">>ERROR: binary file is not open");
513  }
514  else
515  {
516  if(INTEGERTYPE == *item_type)
517  {
518  /* Integer data */
519  item_size=sizeof(int);
520  }
521  else if(FLOATTYPE == *item_type)
522  {
523  /* Float data */
524  item_size=sizeof(float);
525  }
526  else if(DOUBLETYPE == *item_type)
527  /* Double data */
528  {
529  item_size=sizeof(double);
530  }
531  else if(CHARTYPE == *item_type)
532  /* Character data */
533  {
534  item_size=sizeof(char);
535  }
536  else if(LOGICALTYPE == *item_type)
537  /* Logical data */
538  {
539  item_size=sizeof(logical);
540  }
541  else if(SHORTINTTYPE == *item_type)
542  /* Short integer data */
543  {
544  item_size=sizeof(short int);
545  }
546  else
547  {
548  *err=1;
549  strcpy(error_string,">>ERROR: Invalid item type");
550  }
551 
552  if(SAMEENDIAN == *endian || CHARTYPE == *item_type)
553  {
554  /* Default big endian format */
555  number_of_bytes=*number_of_items * item_size;
556  for(i = 0; i < number_of_bytes ; i++)
557  {
558  putc(data[i],binaryfile);
559  }
560  }
561  else
562  {
563  /* Little endian format - must reverse byte ordering */
564  for(i = 0; i < *number_of_items; i++)
565  {
566  start_byte=i*item_size;
567  for(j = 0; j < item_size; j++)
568  {
569  putc(data[start_byte+item_size-j-1],binaryfile);
570  }
571  }
572  }
573 
574  *err=ferror(binaryfile);
575  if(*err != 0)
576  {
577  strcpy(error_string,">>ERROR: error writing binary file");
578  }
579  }
580  }
581  else
582  {
583  *err=1;
584  strcpy(error_string,">>ERROR: file ID is out of range");
585  }
586 }
587 
588 void IsBinaryFileOpen(int *fileid,
589  int *returncode,
590  int *err,
591  char *error_string)
592 
593 /*
594 Returns 1 in returncode if a binary file specified by fileid
595 is open, 0 if not.
596 */
597 
598 {
599  FILE* binaryfile;
600 
601  if((*fileid >= 1) && (*fileid <= MAXBINFILES-1))
602  {
603  binaryfile=binaryfiles[*fileid-1];
604  if(!binaryfile)
605  {
606  *returncode = 0;
607  }
608  else
609  {
610  *returncode = 1;
611  }
612  *err=0;
613  }
614  else
615  {
616  *err=1;
617  strcpy(error_string,">>ERROR: file ID is out of range");
618  }
619 }
620 
621 
622 void IsEndBinaryFile(int *fileid,
623  int *returncode,
624  int *err,
625  char *error_string)
626 
627 /*
628 Returns 1 in returncode if a binary file specified by fileid
629 is at end of file (eof), 0 if not.
630 */
631 
632 {
633  FILE* binaryfile;
634 
635  if((*fileid >= 1) && (*fileid <= MAXBINFILES-1))
636  {
637  binaryfile=binaryfiles[*fileid-1];
638  if(feof(binaryfile))
639  {
640  *returncode = 1;
641  }
642  else
643  {
644  *returncode = 0;
645  }
646  *err=0;
647  }
648  else
649  {
650  *err=1;
651  strcpy(error_string,">>ERROR: file ID is out of range");
652  }
653 }
654 
void IsEndBinaryFile(int *fileid, int *returncode, int *err, char *error_string)
#define SAMEENDIAN
void IsBinaryFileOpen(int *fileid, int *returncode, int *err, char *error_string)
#define SHORTINTTYPE
FILE * binaryfiles[MAXBINFILES]
int logical
#define DOUBLETYPE
#define FLOATTYPE
void BinaryOpenFile(int *fileid, char *filename, char *access_code, int *err, char *error_string)
void BinarySkipFile(int *fileid, int *number_of_bytes, int *err, char *error_string)
#define LOGICALTYPE
void BinaryReadFile(int *fileid, int *endian, int *number_of_items, int *item_type, char *data, int *err, char *error_string)
#define MAXBINFILES
void BinarySetFile(int *fileid, int *set_code, int *err, char *error_string)
#define INTEGERTYPE
#define CHARTYPE
void BinaryCloseFile(int *fileid, int *err, char *error_string)
void BinaryWriteFile(int *fileid, int *endian, int *number_of_items, int *item_type, char *data, int *err, char *error_string)