1 /* created by combine 2.0 */
2 /* file ADFI_AAA_var.c */
3 /***
4 File: ADF_internals.c
5   ----------------------------------------------------------------------
6 			BOEING
7   ----------------------------------------------------------------------
8 	Project: CGNS
9 	Author: Tom Dickens   234-1024    tpd6908@yak.ca.boeing.com
10 	Date: 3/2/1995
11 	Purpose: Provide the underlying support for the ADF-Core.
12   ----------------------------------------------------------------------
13   ----------------------------------------------------------------------
14 Notes:	Integer numbers are stored on disk as ASCII-hex numbers.
15 	2 bytes gives a number from 0 to 255,
16 	4 bytes 0 to 65,535,
17 	8 bytes 0 to 4,294,967,295,
18 	and 12 bytes from 0 to 281,474,976,710,655.
19 
20 Pointers are 12 bytes.
21 	8 bytes pointing to a 4096-byte chunk on disk,
22 	and 4 bytes is an offset into that chunk.
23 This gives a maximum file size of 17,592,186,048,512 bytes (17.5 Tera bytes).
24 
25   ----------------------------------------------------------------------
26 	The tables below detail the format of the information which
27 	makes up the ADF file.
28 
29 	There are 7 different, unique types of data "chunks" used.
30 	Three of these are of fixed length, and the other four are
31 	variable in length.
32 
33 	With the exception of numeric data (user's data), all information
34 	in an ADF file is written in ASCII.
35 
36 	Uniquely-defined boundary-tags are used to surround all "chunks"
37 	of information.  These tags are checked to confirm "chunk" type
38 	and also to ensure data integrity.
39   ----------------------------------------------------------------------
40       186   Physical disk-First block
41 bytes   start   end   description      range / format
42  32    0   31   "what" description      "@(#)ADF Database Version AXXxxx>"
43   4   32   35   "AdF0" boundary tag      Tag
44  28   36   63   Creation date/time       "Wed Apr 19 09:33:25 1995    "
45   4   64   67   "AdF1" boundary tag      Tag
46  28   68   95   Modification date/time   "Wed Apr 19 09:33:29 1995   "
47   4   96   99   "AdF2" boundary tag      Tag
48   1  100  100   Numeric format           ['B', 'L', 'C', 'N']
49   1  101  101   Duplicate of numeric format      ['B', 'L', 'C', 'N']
50   4  102  105   "AdF3" boundary tag      Tag
51   2  106  107   sizeof( char )           0 to 255
52   2  108  109   sizeof( short )          0 to 255
53   2  110  111   sizeof( int )            0 to 255
54   2  112  113   sizeof( long )           0 to 255
55   2  114  115   sizeof( float )          0 to 255
56   2  116  117   sizeof( double )         0 to 255
57   2  118  119   sizeof( char * )         0 to 255
58   2  120  121   sizeof( short * )        0 to 255
59   2  122  123   sizeof( int  *)          0 to 255
60   2  124  125   sizeof( long * )         0 to 255
61   2  126  127   sizeof( float  *)        0 to 255
62   2  128  129   sizeof( double  *)       0 to 255
63   4  130  133   "AdF4" boundary tag      Tag
64  12  134  145   Root-node header pointer Disk chunk, chunk offset.
65  12  146  157   End-of-File pointer      Disk chunk, chunk offset.
66  12  158  169   Free-Chunk table pointer Disk chunk, chunk offset.
67  12  170  181   Extra pointer            Disk chunk, chunk offset.
68   4  182  185   "AdF5" boundary tag      Tag
69 
70 
71        80   Free-Chunk table
72 bytes   start   end   description      range / format
73   4    0    3   "fCbt" boundary tag      Tag
74  12    4   15   First small block pointer  Disk chunk, chunk offset.
75  12   16   27   Last small block pointer   Disk chunk, chunk offset.
76  12   28   39   First medium block pointer Disk chunk, chunk offset.
77  12   40   51   Last medium block pointer  Disk chunk, chunk offset.
78  12   52   63   First large block pointer  Disk chunk, chunk offset.
79  12   64   75   Last large block pointer   Disk chunk, chunk offset.
80   4   76   79   "fcte" boundarg tag      Tag
81 
82 
83    Variable: min   32   Free Chunk
84 bytes   start   end   description      range / format
85   4    0    3   "FreE" boundary tag      Tag
86  12    4   15   Pointer to End-of-Chunk-Tag
87  12   16   27   Pointer to Next-Chunk in list
88   0   28    -   more free space
89   4   28   31   "EndC" boundarg tag      Tag
90 
91 Note:  There can occur other free space "gas" in the file which are smaller
92        than the 32-bytes needed to have tags and pointers.  The convention
93        in these cases is to just fill the entire free space with the letter
94        z, lower-case.
95 
96       246   Node header
97 bytes   start   end   description      range / format
98   4    0    3   "NoDe" boundary tag      Tag
99  32    4   35   Name                     Text:  Blank filled
100  32   36   67   Label                    Text:  Blank filled
101   8   68   75   Number of sub-nodes      0 to 4,294,967,295
102   8   76   83   Entries for sub-nodes    0 to 4,294,967,295
103  12   84   95   Pointer to sub-node table      Disk chunk, chunk offset.
104  32   96  127   Data-type                Text:  Blank filled
105   2  128  129   Number of dimensions      0 to 12
106   8  130  137   Dimension value 0         0 to 4,294,967,295
107   8  138  145   Dimension value 1         0 to 4,294,967,295
108   8  146  153   Dimension value 2         0 to 4,294,967,295
109   8  154  161   Dimension value 3         0 to 4,294,967,295
110   8  162  169   Dimension value 4         0 to 4,294,967,295
111   8  170  177   Dimension value 5         0 to 4,294,967,295
112   8  178  185   Dimension value 6         0 to 4,294,967,295
113   8  186  193   Dimension value 7         0 to 4,294,967,295
114   8  194  201   Dimension value 8         0 to 4,294,967,295
115   8  202  209   Dimension value 9         0 to 4,294,967,295
116   8  210  217   Dimension value 10        0 to 4,294,967,295
117   8  218  225   Dimension value 11        0 to 4,294,967,295
118   4  226  229   Number of data chunks     0 to 65,535
119  12  230  241   Pointer to data chunk (or table)      Disk chunk, chunk offset.
120   4  242  245   "TaiL" boundary tag      Tag
121 
122 
123    Variable: min   64   Sub-node table
124 bytes   start   end   description      range / format
125   4    0    3   "SNTb" boundary tag      Tag
126  12    4   15   Pointer to End-of-Table-Tag
127  32   16   47   Child's name             Text:  Blank filled
128  12   48   59   Pointer to child         Disk chunk, chunk offset.
129  32    -    -   Child's name             Text:  Blank filled
130  12    -    -   Pointer to child         Disk chunk, chunk offset.
131  32    -    -   Child's name             Text:  Blank filled
132  12    -    -   Pointer to child         Disk chunk, chunk offset.
133  32    -    -   Child's name             Text:  Blank filled
134  12    -    -   Pointer to child         Disk chunk, chunk offset.
135  32    -    -   Child's name             Text:  Blank filled
136  12    -    -   Pointer to child         Disk chunk, chunk offset.
137  32    -    -   Child's name             Text:  Blank filled
138  12    -    -   Pointer to child         Disk chunk, chunk offset.
139   4   60   63   "snTE" boundary tag      Tag
140 
141 
142    Variable: min   44   Data-chunk table
143 bytes   start   end   description      range / format
144   4    0    3   "DCtb" boundary tag      Tag
145  12    4   15   Pointer to End-of-Table-Tag
146  12   16   27   Pointer to data start    Disk chunk, chunk offset.
147  12   28   39   Pointer to data end      Disk chunk, chunk offset.
148  12    -    -   Pointer to data start    Disk chunk, chunk offset.
149  12    -    -   Pointer to data end      Disk chunk, chunk offset.
150  12    -    -   Pointer to data start    Disk chunk, chunk offset.
151  12    -    -   Pointer to data end      Disk chunk, chunk offset.
152  12    -    -   Pointer to data start    Disk chunk, chunk offset.
153  12    -    -   Pointer to data end      Disk chunk, chunk offset.
154   4   40   43   "dcTE" boundarg tag      Tag
155 
156 
157    Variable: min   32   Data-chunks
158 (Minimum is 32 bytes, which cooresponds to the size required for a free-chunk)
159 bytes   start   end   description      range / format
160   4    0    3   "DaTa" boundary tag      Tag
161  12    4   15   Pointer to End-of-Data-Tag
162  16   16   27   The data
163   4   28   31   "dEnD" boundarg tag      Tag
164 
165 **/
166 /***********************************************************************
167  	Includes
168 ***********************************************************************/
169 #include <sys/types.h>
170 #include <time.h>
171 #include <stdio.h>
172 #include <errno.h>
173 #include <string.h>
174 #include <stdlib.h>
175 #include <fcntl.h>
176 #include <assert.h>
177 
178 #if defined(_WIN32) && !defined(__NUTC__)
179 # include <io.h>
180 # define ACCESS _access
181 # define OPEN   _open
182 # define CLOSE  _close
183 # define FILENO _fileno
184 # define READ   _read
185 # define WRITE  _write
186 # define LSEEK  _lseek
187 #else
188 # include <unistd.h>
189 # include <sys/param.h>
190 # include <sys/stat.h>
191 # define ACCESS access
192 # define OPEN   open
193 # define CLOSE  close
194 # define FILENO fileno
195 # define READ   read
196 # define WRITE  write
197 # define LSEEK  lseek
198 #endif
199 
200 #include "ADF.h"
201 #include "ADF_internals.h"
202 #ifdef MEM_DEBUG
203 #include "cg_malloc.h"
204 #endif
205 #include "cgns_io.h" /* for cgio_find_file */
206 
207 #if 0
208 #define CHECK_ABORT(E) if(E!=NO_ERROR){int a=0;int b=1/a;}
209 #else
210 #define CHECK_ABORT(E) if(E!=NO_ERROR)return;
211 #endif
212 
213 /***********************************************************************
214    Large File Support - files > 2Gb on 32-bit machines
215  ***********************************************************************/
216 #ifdef HAVE_OPEN64
217 # define file_open open64
218 #else
219 # define file_open OPEN
220 #endif
221 #ifdef HAVE_LSEEK64
222 # ifdef _WIN32
223    typedef __int64 file_offset_t;
224 #  define file_seek _lseeki64
225 # else
226    typedef off64_t file_offset_t;
227 #  define file_seek lseek64
228 # endif
229 #else
230   typedef off_t file_offset_t;
231 # define file_seek LSEEK
232 #endif
233 
234 extern int ADF_sys_err;
235 
236 /* how many file data structures to add when increasing */
237 #define ADF_FILE_INC 5
238 
239 /* open file data structure */
240 ADF_FILE *ADF_file;
241 int maximum_files = 0;
242 
243    /** Track the format of this machine as well as the format
244        of eack of the files.  This is used for reading and
245        writing numeric data associated with the nodes, which may
246        include numeric-format translations.
247    **/
248 static  char   ADF_this_machine_format = UNDEFINED_FORMAT_CHAR ;
249 static  char   ADF_this_machine_os_size = UNDEFINED_FORMAT_CHAR ;
250 
251    /** we need a block of "zz"-bytes for dead-space **/
252 static  char   block_of_ZZ[ SMALLEST_CHUNK_SIZE ] ;
253 static  int    block_of_ZZ_initialized = FALSE ;
254    /** we need a block of "xx"-bytes for free-blocks **/
255 static  char   block_of_XX[ DISK_BLOCK_SIZE ] ;
256 static  int    block_of_XX_initialized = FALSE ;
257    /** we need a block of null-bytes for disk conditioning **/
258 static  char   block_of_00[ DISK_BLOCK_SIZE ] ;
259 static  int    block_of_00_initialized = FALSE ;
260 
261     /** read/write conversion buffer **/
262 #define CONVERSION_BUFF_SIZE 100000
263 static unsigned char from_to_data[ CONVERSION_BUFF_SIZE ] ;
264 
265     /** read/write buffering variables **/
266 static char     rd_block_buffer[DISK_BLOCK_SIZE] ;
267 static cglong_t last_rd_block = -1 ;
268 static int      last_rd_file = -1 ;
269 static int      num_in_rd_block = -1 ;
270 static char     wr_block_buffer[DISK_BLOCK_SIZE] ;
271 static cglong_t last_wr_block = -2 ;
272 static int      last_wr_file = -2 ;
273 static int      flush_wr_block = -2 ;
274 static double   last_link_ID = 0.0;
275 static double   last_link_LID = 0.0;
276 enum { FLUSH, FLUSH_CLOSE };
277 
278     /** Assumed machine variable sizes for the currently supported
279         machines. For ordering of data see the Figure_Machine_Format
280 	function.  Note that when opening a new file not in the machine
281 	format these are the sizes used!! **/
282 enum { TO_FILE_FORMAT, FROM_FILE_FORMAT } ;
283 #define NUMBER_KNOWN_MACHINES 5
284 static	size_t machine_sizes[NUMBER_KNOWN_MACHINES][16] = {
285      /* IEEE BIG 32 */	{ 1, 1, 1, 2, 2, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4 },
286      /* IEEE SML 32 */	{ 1, 1, 1, 2, 2, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4 },
287      /* IEEE BIG 64 */	{ 1, 1, 1, 2, 2, 4, 4, 8, 8, 4, 8, 8, 8, 8, 8, 8 },
288      /* IEEE SML 64 */	{ 1, 1, 1, 2, 2, 4, 4, 8, 8, 4, 8, 8, 8, 8, 8, 8 },
289      /* CRAY     64 */	{ 1, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 } } ;
290 
291 /***********************************************************************
292 	pows: Powers of 16, from 16^0 to 16^7
293 	ASCII_Hex: Hex numbers from 0 to 15.
294 ***********************************************************************/
295 static const unsigned int pows[8] = {	/** Powers of 16 **/
296 		1, 16, 256, 4096, 65536, 1048576, 16777216, 268435456 } ;
297 static const char ASCII_Hex[16] = {
298 		'0', '1', '2', '3', '4', '5', '6', '7',
299 		'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' } ;
300 
301 /***********************************************************************
302     Character string defining the data tags:
303 ***********************************************************************/
304 static char     *file_header_tags[] = {
305         "AdF0", "AdF1", "AdF2", "AdF3", "AdF4", "AdF5" } ;
306 static char     node_start_tag[] = "NoDe" ;
307 static char     node_end_tag[]   = "TaiL" ;
308 static char     free_chunk_table_start_tag[] = "fCbt" ;
309 static char     free_chunk_table_end_tag[]   = "Fcte" ;
310 static char     free_chunk_start_tag[] = "FreE" ;
311 static char     free_chunk_end_tag[]   = "EndC" ;
312 static char     sub_node_start_tag[] = "SNTb" ;
313 static char     sub_node_end_tag[]   = "snTE" ;
314 static char     data_chunk_table_start_tag[] = "DCtb" ;
315 static char     data_chunk_table_end_tag[]   = "dcTE" ;
316 char     data_chunk_start_tag[] = "DaTa" ; /* needed in ADF_interface.c */
317 static char     data_chunk_end_tag[]   = "dEnD" ;
318 
319 /***********************************************************************
320         Priority Stack Buffer is used to buffer some of the overhead of
321 	reading small blocks of file control information like the node
322 	header by saving the data into a memory buffer. The buffer has
323 	a priority value associated with it and is used to determine
324 	which entry to replace when the stack is full!! Each stack entry
325 	could be as large as 274 bytes since the stack data could be for
326 	a node where NODE_HEADER_SIZE = 246.
327 ***********************************************************************/
328 #define MAX_STACK 50
329 static struct {
330   int file_index;
331   cgulong_t file_block;
332   unsigned int block_offset;
333   int stack_type;
334   char *stack_data;
335   int priority_level;
336 } PRISTK[MAX_STACK] ;
337 /* Define stack types */
338 enum { FILE_STK=1, NODE_STK, DISK_PTR_STK, FREE_CHUNK_STK, SUBNODE_STK };
339 /* Define stack control modes */
340 enum { INIT_STK, CLEAR_STK, CLEAR_STK_TYPE, DEL_STK_ENTRY, GET_STK, SET_STK };
341 /***********************************************************************
342 	Defined macros
343 ***********************************************************************/
344 #define	EVAL_2_BYTES( C0, C1 )  (((C0)<<8)+((C1)))
345 #define	EVAL_4_BYTES( C0, C1, C2, C3 ) (((C0)<<24)+((C1)<<16)+((C2)<<8)+((C3)))
346 /* end of file ADFI_AAA_var.c */
347 /* file ADFI_ASCII_Hex_2_unsigned_int.c */
348 /***********************************************************************
349 ADFI ASCII Hex to unsigned int:
350 	Convert a number of ASCII-HEX into an unsigned integer.
351 
352 input:  const unsigned int minimum	Expected minimum number.
353 input:  const unsigned int maximum	Expected maximum number.
354 input:  const unsigned int string_length Length (bytes) of the input string.
355 input:  const char string[]		The input string.
356 output: unsigned int *number		The resulting number.
357 output:	int *error_return		Error return.
358 
359    Possible errors:
360 NO_ERROR
361 NULL_POINTER
362 NULL_STRING_POINTER
363 STRING_LENGTH_ZERO
364 STRING_LENGTH_TOO_BIG
365 STRING_NOT_A_HEX_STRING
366 NUMBER_LESS_THAN_MINIMUM
367 NUMBER_GREATER_THAN_MAXIMUM
368 ***********************************************************************/
ADFI_ASCII_Hex_2_unsigned_int(const unsigned int minimum,const unsigned int maximum,const unsigned int string_length,const char string[],unsigned int * number,int * error_return)369 void	ADFI_ASCII_Hex_2_unsigned_int(
370 		const unsigned int minimum,
371 		const unsigned int maximum,
372 		const unsigned int string_length,
373 		const char string[],
374 		unsigned int *number,
375 		int *error_return )
376 {
377 unsigned int	i,	/** Index from 0 to string_length - 1 **/
378 		ir,	/** Index from string_length - 1 to 0 **/
379 		j,	/** Temoprary integer variable **/
380 		num ;	/** Working value of the number **/
381 
382 if( string == NULL ) {
383    *error_return = NULL_STRING_POINTER ;
384    return ;
385    } /* end if */
386 
387 if( string_length == 0 ) {
388    *error_return = STRING_LENGTH_ZERO ;
389    return ;
390    } /* end if */
391 
392 if( number == NULL ) {
393    *error_return = NULL_POINTER ;
394    return ;
395    } /* end if */
396 
397 if( string_length > 8 ) {
398    *error_return = STRING_LENGTH_TOO_BIG ;
399    return ;
400    } /* end if */
401 
402 if( minimum > maximum ) {
403    *error_return = MINIMUM_GT_MAXIMUM ;
404    return ;
405    } /* end if */
406 
407 *error_return = NO_ERROR ;
408 
409 	/** Convert the ASCII-Hex string into decimal  **/
410 num = 0 ;
411 ir = (string_length - 1) << 2;
412 for( i=0; i<string_length; i++) {
413    if (string[i] >= '0' && string[i] <= '9')
414       j = string[i] - 48;
415    else if (string[i] >= 'A' && string[i] <= 'F')
416       j = string[i] - 55;
417    else if (string[i] >= 'a' && string[i] <= 'f')
418       j = string[i] - 87;
419    else {
420       *error_return = STRING_NOT_A_HEX_STRING ;
421       return ;
422    }
423    num += (j << ir);
424    ir -= 4;
425 }
426 
427 if( num < minimum ) {
428    *error_return = NUMBER_LESS_THAN_MINIMUM ;
429    return ;
430    } /* end if */
431 
432 if( num > maximum ) {
433    *error_return = NUMBER_GREATER_THAN_MAXIMUM ;
434    return ;
435    } /* end if */
436 
437 	/** Return the number **/
438 *number = num ;
439 } /* end of ADFI_ASCII_Hex_2_unsigned_int */
440 /* end of file ADFI_ASCII_Hex_2_unsigned_int.c */
441 /*------------------------------------------------------------------------------------*/
ADFI_convert_integers(const int size,const int count,const char from_format,const char to_format,const char * from_data,char * to_data,int * error_return)442 static void ADFI_convert_integers(
443 		const int size,
444 		const int count,
445 		const char from_format,
446 		const char to_format,
447 		const char *from_data,
448 		char *to_data,
449 		int *error_return)
450 {
451     int do_swap = 0;
452 
453     if (from_format == 'N' || to_format == 'N') {
454         *error_return = CANNOT_CONVERT_NATIVE_FORMAT;
455         return;
456     }
457     if (from_format != to_format) {
458 	switch (EVAL_2_BYTES(from_format, to_format)) {
459 	    case EVAL_2_BYTES('L', 'B'):
460 	    case EVAL_2_BYTES('B', 'L'):
461 	    case EVAL_2_BYTES('L', 'C'):
462 	    case EVAL_2_BYTES('C', 'L'):
463 	        do_swap = 1;
464 		break;
465 	    case EVAL_2_BYTES('B', 'C'):
466 	    case EVAL_2_BYTES('C', 'B'):
467 	        break;
468 	    default:
469 	        *error_return = ADF_FILE_FORMAT_NOT_RECOGNIZED;
470 		return;
471 	}
472     }
473     *error_return = NO_ERROR;
474     if (do_swap) {
475         int n, i;
476 	for (n = 0; n < count; n++) {
477 	    for (i = 0; i < size; i++) {
478 	        to_data[i] = from_data[size-i-1];
479 	    }
480 	    to_data += size;
481 	    from_data += size;
482 	}
483     }
484     else {
485         memcpy(to_data, from_data, size * count);
486     }
487 }
488 /*------------------------------------------------------------------------------------*/
489 /* file ADFI_Abort.c */
490 /***********************************************************************
491 ADFI Abort:
492 	Do any cleanup and then shut the application down.
493 
494 input:  const int error_code	Error which caused the Abort.
495 output: -none-			Hey, we ain't coming back...
496 ***********************************************************************/
ADFI_Abort(const int error_code)497 void    ADFI_Abort(
498 		const int error_code )
499 {
500 fprintf(stderr,"ADF Aborted:  Exiting\n" ) ;
501 exit( error_code ) ;
502 } /* end of ADFI_Abort */
503 /* end of file ADFI_Abort.c */
504 /* file ADFI_ID_2_file_block_offset.c */
505 /***********************************************************************
506 ADFI ID to file block and offset:
507 
508 	The ID is a combination of the file-index, the block within the
509 	file, and an offset within the block.
510 
511    the file index is an unsigned 16-bit int.
512    block pointer is a 32-bit unsigned int.
513    block offset is a 16-bit unsigned int.
514 
515 input:  const double ID			Given ADF ID.
516 output: unsigned int *file_index	File index from the ID.
517 output: unsigned long *file_block	File block from the ID.
518 output: unsigned long *block_offset	Block offset from the ID.
519 output:	int *error_return		Error return.
520 
521    Possible errors:
522 NO_ERROR
523 NULL_POINTER
524 FILE_INDEX_OUT_OF_RANGE
525 BLOCK_OFFSET_OUT_OF_RANGE
526 ***********************************************************************/
ADFI_ID_2_file_block_offset(const double ID,unsigned int * file_index,cgulong_t * file_block,cgulong_t * block_offset,int * error_return)527 void	ADFI_ID_2_file_block_offset(
528 		const double ID,
529 		unsigned int *file_index,
530 		cgulong_t *file_block,
531 		cgulong_t *block_offset,
532 		int *error_return )
533 {
534 unsigned char * cc;
535 
536 if( (file_index == NULL) || (file_block == NULL) || (block_offset == NULL) ) {
537    *error_return = NULL_POINTER ;
538    return ;
539    } /* end if */
540 
541 if( ID == 0.0 ) {
542    *error_return = NODE_ID_ZERO ;
543    return ;
544    } /* end if */
545 
546 *error_return = NO_ERROR ;
547 cc = (unsigned char *) &ID;
548 #ifdef PRINT_STUFF
549 printf("In ADFI_ID_2_file_block_offset: ID=%lf\n",ID);
550 printf("cc[0-7] = %02X %02X %02X %02X %02X %02X %02X %02X \n",
551         cc[0], cc[1], cc[2], cc[3],
552         cc[4], cc[5], cc[6], cc[7] ) ;
553 #endif
554 	/** Unmap the bytes from the character **/
555 #ifdef NEW_ID_MAPPING
556 if (ADF_this_machine_format == IEEE_LITTLE_FORMAT_CHAR) {
557   *file_index =   (((unsigned int)(cc[7] & 0x3F)) << 6) +
558                   (((unsigned int)(cc[6] & 0xFC)) >> 2);
559   *file_block =   (((cgulong_t)(cc[6] & 0x03)) << 36) +
560                   (((cgulong_t)(cc[5] & 0xFF)) << 28) +
561 	          (((cgulong_t)(cc[4] & 0xFF)) << 20) +
562 	          (((cgulong_t)(cc[3] & 0xFF)) << 12) +
563 	          (((cgulong_t)(cc[2] & 0xFF)) <<  4) +
564 	          (((cgulong_t)(cc[1] & 0xF0)) >>  4);
565   *block_offset = (((unsigned int)(cc[1] & 0x0F)) << 8) +
566                   (((unsigned int)(cc[0] & 0xFF)));
567 }
568 else {
569   *file_index =   (((unsigned int)(cc[0] & 0x3F)) << 6) +
570                   (((unsigned int)(cc[1] & 0xFC)) >> 2);
571   *file_block =   (((cgulong_t)(cc[1] & 0x03)) << 36) +
572                   (((cgulong_t)(cc[2] & 0xFF)) << 28) +
573 	          (((cgulong_t)(cc[3] & 0xFF)) << 20) +
574 	          (((cgulong_t)(cc[4] & 0xFF)) << 12) +
575 	          (((cgulong_t)(cc[5] & 0xFF)) <<  4) +
576 	          (((cgulong_t)(cc[6] & 0xF0)) >>  4);
577   *block_offset = (((unsigned int)(cc[6] & 0x0F)) << 8) +
578                   (((unsigned int)(cc[7] & 0xFF)));
579 }
580 #if 0
581 assert(*file_index <= 0xfff);
582 assert(*file_block <= 0x3fffffffff);
583 assert(*block_offset <= 0xfff);
584 #endif
585 #else
586 if ( ADF_this_machine_format == IEEE_BIG_FORMAT_CHAR ) {
587    *file_index = cc[1] + ((cc[0] & 0x3f) << 8) ;
588    *file_block = cc[2] + (cc[3]<<8) +
589                  (cc[4]<<16) + (cc[5]<<24) ;
590    *block_offset = cc[6] + (cc[7]<<8) ;
591    } /* end if */
592 else if ( ADF_this_machine_format == IEEE_LITTLE_FORMAT_CHAR ) {
593    *file_index = cc[6] + ((cc[7] & 0x3f) << 8) ;
594    *file_block = cc[2] + (cc[3]<<8) +
595                  (cc[4]<<16) + (cc[5]<<24) ;
596    *block_offset = cc[0] + (cc[1]<<8) ;
597    } /* end else if */
598 else {
599    *file_index = cc[0] + (cc[1]<<8) ;
600    *file_block = cc[2] + (cc[3]<<8) +
601                  (cc[4]<<16) + (cc[5]<<24) ;
602    *block_offset = cc[6] + (cc[7]<<8) ;
603    } /* end else */
604 #endif
605 
606 #ifdef PRINT_STUFF
607    printf("*file_index=%d, *file_block=%d, *block_offset=%d\n",
608 	   *file_index, *file_block, *block_offset);
609 #endif
610 
611 if( (int)(*file_index) >= maximum_files ) {
612    *error_return = FILE_INDEX_OUT_OF_RANGE ;
613    return ;
614    } /* end if */
615 
616 if( *block_offset >= DISK_BLOCK_SIZE ) {
617    *error_return = BLOCK_OFFSET_OUT_OF_RANGE ;
618    return ;
619    } /* end if */
620 } /* end of ADFI_ID_2_file_block_offset */
621 /* end of file ADFI_ID_2_file_block_offset.c */
622 /* file ADFI_add_2_sub_node_table.c */
623 /***********************************************************************
624 ADFI add 2 sub node table:
625 	Add a child to a parent's sub-node table.
626 
627 input:  const int file_index		Index of ADF file.
628 input:  const struct DISK_POINTER *parent Location of the parent
629 input:  const struct DISK_POINTER *child Location of the child.
630 output:	int *error_return		Error return.
631 
632    Possible errors:
633 NO_ERROR
634 NULL_POINTER
635 ADF_FILE_NOT_OPENED
636 SUB_NODE_TABLE_ENTRIES_BAD
637 MEMORY_ALLOCATION_FAILED
638 ***********************************************************************/
ADFI_add_2_sub_node_table(const int file_index,const struct DISK_POINTER * parent,const struct DISK_POINTER * child,int * error_return)639 void    ADFI_add_2_sub_node_table(
640 		const int file_index,
641 		const struct DISK_POINTER *parent,
642 		const struct DISK_POINTER *child,
643 		int *error_return )
644 {
645 struct	NODE_HEADER	parent_node, child_node ;
646 struct SUB_NODE_TABLE_ENTRY *sub_node_table ;
647 struct DISK_POINTER tmp_disk_ptr ;
648 unsigned int	old_num_entries ;
649 int			i ;
650 
651 if( (parent == NULL) || (child == NULL) ) {
652    *error_return = NULL_POINTER ;
653    return ;
654    } /* end if */
655 
656 if( file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
657    *error_return = ADF_FILE_NOT_OPENED ;
658    return ;
659    } /* end if */
660 
661 *error_return = NO_ERROR ;
662 
663 	/** Get node_header for the node (parent) **/
664 ADFI_read_node_header( file_index, parent, &parent_node, error_return ) ;
665 if( *error_return != NO_ERROR )
666    return ;
667 
668 	/** Get node_header for the node (child) **/
669 ADFI_read_node_header( file_index, child, &child_node, error_return ) ;
670 if( *error_return != NO_ERROR )
671    return ;
672 
673 	/** Check current length of sub-node_table, add space if needed **/
674 if( parent_node.entries_for_sub_nodes <= parent_node.num_sub_nodes ) {
675    old_num_entries = parent_node.entries_for_sub_nodes ;
676 
677 	/** Increase the table space (double it) **/
678    if( parent_node.entries_for_sub_nodes == 0 )
679       parent_node.entries_for_sub_nodes = LIST_CHUNK ;
680    else
681       parent_node.entries_for_sub_nodes = (unsigned int) (
682        (float) parent_node.entries_for_sub_nodes * LIST_CHUNK_GROW_FACTOR ) ;
683 
684    if( parent_node.entries_for_sub_nodes <= parent_node.num_sub_nodes ) {
685       *error_return = SUB_NODE_TABLE_ENTRIES_BAD ;
686       return ;
687       } /* end if */
688 
689 	/** Allocate memory for the required table space in memory **/
690    sub_node_table = (struct SUB_NODE_TABLE_ENTRY *)
691                     malloc( parent_node.entries_for_sub_nodes *
692                     sizeof( *sub_node_table ) ) ;
693    if( sub_node_table == NULL ) {
694       *error_return = MEMORY_ALLOCATION_FAILED ;
695       return ;
696       } /* end if */
697 
698 	/** If sub-node table exists, get it **/
699    if( old_num_entries > 0 ) {
700       ADFI_read_sub_node_table( file_index, &parent_node.sub_node_table,
701 	   sub_node_table, error_return ) ;
702       if( *error_return != NO_ERROR )
703          return ;
704       } /* end if */
705 
706 	/** Blank out the new part of the sub-node_table **/
707    for( i=parent_node.num_sub_nodes; i<(int) parent_node.entries_for_sub_nodes;
708 		i++ ) {
709       strncpy( sub_node_table[i].child_name,
710 	/* "                                   ", ADF_NAME_LENGTH ) ; */
711 	"unused entry in sub-node-table     ", ADF_NAME_LENGTH ) ;
712       sub_node_table[i].child_location.block = 0 ;
713       sub_node_table[i].child_location.offset = DISK_BLOCK_SIZE ;
714       } /* end for */
715 
716 	/** Allocate memory for the required table space on disk **/
717    if( parent_node.num_sub_nodes > 0 ) { /* delete old table from file */
718       ADFI_delete_sub_node_table( file_index, &parent_node.sub_node_table,
719                                   old_num_entries, error_return ) ;
720       if( *error_return != NO_ERROR )
721          return ;
722       } /* end if */
723 
724   ADFI_file_malloc( file_index, TAG_SIZE + DISK_POINTER_SIZE + TAG_SIZE +
725     parent_node.entries_for_sub_nodes * (ADF_NAME_LENGTH + DISK_POINTER_SIZE),
726     &tmp_disk_ptr, error_return ) ;
727    if( *error_return != NO_ERROR )
728       return ;
729 
730    parent_node.sub_node_table.block = tmp_disk_ptr.block ;
731    parent_node.sub_node_table.offset = tmp_disk_ptr.offset ;
732 
733 	/** Write out modified sub_node_table **/
734    ADFI_write_sub_node_table( file_index, &parent_node.sub_node_table,
735         parent_node.entries_for_sub_nodes,
736 	(struct SUB_NODE_TABLE_ENTRY *)sub_node_table, error_return ) ;
737    free( sub_node_table ) ;
738    if( *error_return != NO_ERROR )
739       return ;
740    } /* end if */
741 
742 	/** Insert new entry in sub-node table **/
743 tmp_disk_ptr.block = parent_node.sub_node_table.block ;
744 tmp_disk_ptr.offset = parent_node.sub_node_table.offset +
745 	TAG_SIZE + DISK_POINTER_SIZE +
746 	parent_node.num_sub_nodes * (ADF_NAME_LENGTH + DISK_POINTER_SIZE) ;
747 
748 ADFI_adjust_disk_pointer( &tmp_disk_ptr, error_return ) ;
749 if( *error_return != NO_ERROR )
750    return ;
751 
752 	/** Write the child's name **/
753 ADFI_write_file( file_index, tmp_disk_ptr.block, tmp_disk_ptr.offset,
754 		 ADF_NAME_LENGTH, child_node.name, error_return ) ;
755 if( *error_return != NO_ERROR )
756    return ;
757 
758 	/** Write out new sub_node_table entry **/
759 tmp_disk_ptr.offset += ADF_NAME_LENGTH ;
760 ADFI_adjust_disk_pointer( &tmp_disk_ptr, error_return ) ;
761 if( *error_return != NO_ERROR )
762    return ;
763 
764 ADFI_write_disk_pointer_2_disk( file_index, tmp_disk_ptr.block,
765 				tmp_disk_ptr.offset, child, error_return ) ;
766 if( *error_return != NO_ERROR )
767    return ;
768 
769 	/** Write out modified parent node-header **/
770 parent_node.num_sub_nodes++ ;
771 ADFI_write_node_header( file_index, parent, &parent_node, error_return ) ;
772 if( *error_return != NO_ERROR )
773    return ;
774 
775 } /* end of ADFI_add_2_sub_node_table */
776 /* end of file ADFI_add_2_sub_node_table.c */
777 /* file ADFI_adjust_disk_pointer.c */
778 /***********************************************************************
779 ADFI adjust disk pointer:
780 	Adjust the disk pointer so that the offset is in a legal
781 	range; from 0 and < DISK_BLOCK_SIZE.
782 
783 input:  const struct DISK_POINTER *block_offset
784 output:	int *error_return		Error return.
785 
786    Possible errors:
787 NO_ERROR
788 NULL_POINTER
789 BLOCK_OFFSET_OUT_OF_RANGE
790 ***********************************************************************/
ADFI_adjust_disk_pointer(struct DISK_POINTER * block_offset,int * error_return)791 void    ADFI_adjust_disk_pointer(
792 		struct DISK_POINTER *block_offset,
793 		int *error_return )
794 {
795 cgulong_t oblock ;
796 cgulong_t nblock ;
797 
798 if( block_offset == NULL ) {
799    *error_return = NULL_POINTER ;
800    return ;
801    } /* end if */
802 
803 *error_return = NO_ERROR ;
804 
805 if ( block_offset->offset < DISK_BLOCK_SIZE ) return ;
806 
807         /** Calculate the number of blocks in the current offset **/
808 nblock = (cgulong_t) (block_offset->offset / DISK_BLOCK_SIZE) ;
809 
810 	/** Adjust block/offset checking for block roll-over **/
811 oblock = block_offset->block ;
812 block_offset->block += nblock ;
813 block_offset->offset -= nblock * DISK_BLOCK_SIZE ;
814 if ( block_offset->block < oblock ) {
815    *error_return = BLOCK_OFFSET_OUT_OF_RANGE ;
816    return ;
817    } /* end if */
818 
819 } /* end of ADFI_adjust_disk_pointer */
820 /* end of file ADFI_adjust_disk_pointer.c */
821 /* file ADFI_big_endian_32_swap_64.c */
822 /***********************************************************************
823 ADFI big endian 32 swap 64:
824 
825 input:  const char from_format		Format to convert from. 'B','L','C','N'
826 input:  const char from_os_size		Format to convert from. 'B','L'
827 input:  const char to_format		Format to convert to.
828 input:  const char to_os_size		Format to convert to. 'B','L'
829 input:  const char data_type[2]		The type of data to convert.
830 					   MT I4 I8 U4 U8 R4 R8 X4 X8 C1 B1
831 input:  const unsigned long delta_from_bytes Number of from_bytes used.
832 input:  const unsigned long delta_to_bytes	Number of to_bytes used.
833 input:  const char *from_data		The data to convert from.
834 output: char *to_data			The resulting data.
835 output:	int *error_return		Error return.
836 
837   Recognized data types:
838 					Machine representations
839         Type		  Notation     IEEE_BIG	  IEEE_LITTLE   Cray
840 	                               32    64   32    64
841   No data                   MT
842   Integer 32                I4         I4    I4    I4   I4       I8
843   Integer 64                I8         --    I8    --   I8       I8
844   Unsigned 32               U4         I4    I4    I4   I4       I8
845   Unsigned 64               U8         --    I8    --   I8       I8
846   Real 32                   R4         R4    R4    R4   R4       R8
847   Real 64                   R8         R8    R8    R8   R8       R8
848   Complex 64                X4         R4R4  R4R4  R4R4 R4R4     R8R8
849   Complex 128               X8         R8R8  R8R8  R8R8 R8R8     R8R8
850   Character (unsigned byte) C1         C1    C1    C1   C1       C1
851   Byte (unsigned byte)      B1         C1    C1    C1   C1       C1
852 
853 Machine Numeric Formats:
854 ***IEEE_BIG (SGI-Iris Assembly Language Programmer's Guide, pages 1-2, 6-3)
855 I4:	Byte0	Byte1	Byte2	Byte3
856 	 MSB---------------------LSB
857 R4:	Byte0	Byte1	Byte2	Byte3
858     Bits: sign-bit, 8-bit exponent, 23-bit mantissa
859     The sign of the exponent is:  1=positive, 0=negative (NOT 2's complement)
860     The interpretation of the floating-point number is:
861 	>>> 2.mantissia(fraction) X 2^exponent. <<<
862 
863 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
864     Bits: sign-bit, 11-bit exponent, 52-bit mantissa
865 
866 Machine Numeric Formats:
867 ***IEEE_LITTLE ( The backwards Big Endian )
868 I4:	Byte0	Byte1	Byte2	Byte3
869 	 LSB---------------------MSB
870 R4:	Byte0	Byte1	Byte2	Byte3
871     Bits: 23-bit mantissa, 8-bit exponent, sign-bit
872     The sign of the exponent is:  1=positive, 0=negative (NOT 2's complement)
873     The interpretation of the floating-point number is:
874 	>>> 2.mantissia(fraction) X 2^exponent. <<<
875 
876 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
877     Bits:  52-bit mantissa, 11-bit exponent, sign-bit
878 
879 Note: To convert between these two formats the order of the bytes is reversed
880 since by definition the Big endian starts at the LSB and goes to the MSB where
881 the little goes form the MSB to the LSB of the word.
882 ***
883 
884    Possible errors:
885 NO_ERROR
886 NULL_STRING_POINTER
887 NULL_POINTER
888 ***********************************************************************/
ADFI_big_endian_32_swap_64(const char from_format,const char from_os_size,const char to_format,const char to_os_size,const char data_type[2],const cgulong_t delta_from_bytes,const cgulong_t delta_to_bytes,const unsigned char * from_data,unsigned char * to_data,int * error_return)889 void    ADFI_big_endian_32_swap_64(
890 		const char from_format,
891 		const char from_os_size,
892 		const char to_format,
893 		const char to_os_size,
894 		const char data_type[2],
895 		const cgulong_t delta_from_bytes,
896 		const cgulong_t delta_to_bytes,
897 		const unsigned char *from_data,
898 		unsigned char *to_data,
899 		int *error_return )
900 {
901 
902 if( (from_data == NULL) || (to_data == NULL) ) {
903    *error_return = NULL_STRING_POINTER ;
904    return ;
905    } /* end if */
906 
907 if( (delta_from_bytes == 0) || (delta_to_bytes == 0) ) {
908    *error_return = NULL_POINTER ;
909    return ;
910    } /* end if */
911 
912 if( (from_format == 'N') || (to_format == 'N') ) {
913    *error_return = CANNOT_CONVERT_NATIVE_FORMAT ;
914    return ;
915    } /* end if */
916 
917 *error_return = NO_ERROR ;
918 
919 if ( delta_to_bytes == delta_from_bytes ) {
920   memcpy( to_data, from_data, (size_t)delta_from_bytes ) ;
921   } /* end if */
922 else if ( delta_from_bytes < delta_to_bytes ) {
923   switch( EVAL_2_BYTES( data_type[0], data_type[1] ) ) {
924     case EVAL_2_BYTES( 'I', '8' ):
925       if( (from_data[0] & 0x80) == 0x80 ) { /* Negative number */
926          to_data[0] = 0xff ;
927          to_data[1] = 0xff ;
928          to_data[2] = 0xff ;
929          to_data[3] = 0xff ;
930       } /* end if */
931       else {
932          to_data[0] = 0x00 ;
933          to_data[1] = 0x00 ;
934          to_data[2] = 0x00 ;
935          to_data[3] = 0x00 ;
936       } /* end else */
937       to_data[4] = from_data[0] ;
938       to_data[5] = from_data[1] ;
939       to_data[6] = from_data[2] ;
940       to_data[7] = from_data[3] ;
941       break ;
942     default:
943       *error_return = INVALID_DATA_TYPE ;
944       return ;
945     } /* end switch */
946   } /* end else if */
947 else {
948   switch( EVAL_2_BYTES( data_type[0], data_type[1] ) ) {
949     case EVAL_2_BYTES( 'I', '8' ):
950       to_data[0] = from_data[4] ;
951       to_data[1] = from_data[5] ;
952       to_data[2] = from_data[6] ;
953       to_data[3] = from_data[7] ;
954       break ;
955     default:
956       *error_return = INVALID_DATA_TYPE ;
957       return ;
958     } /* end switch */
959   } /* end else */
960 
961 } /* end of ADFI_big_endian_32_swap_64 */
962 /* end of file ADFI_big_endian_32_swap_64.c */
963 /* file ADFI_big_endian_to_cray.c */
964 /***********************************************************************
965 ADFI big endian to cray:
966 
967 input:  const char from_format		Format to convert from. 'B','L','C','N'
968 input:  const char from_os_size		Format to convert from. 'B','L'
969 input:  const char to_format		Format to convert to.
970 input:  const char to_os_size		Format to convert to. 'B','L'
971 input:  const char data_type[2]		The type of data to convert.
972 					   MT I4 I8 U4 U8 R4 R8 X4 X8 C1 B1
973 input:  const unsigned long delta_from_bytes Number of from_bytes used.
974 input:  const unsigned long delta_to_bytes	Number of to_bytes used.
975 input:  const char *from_data		The data to convert from.
976 output: char *to_data			The resulting data.
977 output:	int *error_return		Error return.
978 
979   Recognized data types:
980 					Machine representations
981         Type		  Notation     IEEE_BIG	  IEEE_LITTLE   Cray
982 	                               32    64   32    64
983   No data                   MT
984   Integer 32                I4         I4    I4    I4   I4       I8
985   Integer 64                I8         --    I8    --   I8       I8
986   Unsigned 32               U4         I4    I4    I4   I4       I8
987   Unsigned 64               U8         --    I8    --   I8       I8
988   Real 32                   R4         R4    R4    R4   R4       R8
989   Real 64                   R8         R8    R8    R8   R8       R8
990   Complex 64                X4         R4R4  R4R4  R4R4 R4R4     R8R8
991   Complex 128               X8         R8R8  R8R8  R8R8 R8R8     R8R8
992   Character (unsigned byte) C1         C1    C1    C1   C1       C1
993   Byte (unsigned byte)      B1         C1    C1    C1   C1       C1
994 
995 Machine Numeric Formats:
996 ***IEEE_BIG (SGI-Iris Assembly Language Programmer's Guide, pages 1-2, 6-3)
997 I4:	Byte0	Byte1	Byte2	Byte3
998 	 MSB---------------------LSB
999 R4:	Byte0	Byte1	Byte2	Byte3
1000     Bits: sign-bit, 8-bit exponent, 23-bit mantissa
1001     The sign of the exponent is:  1=positive, 0=negative (NOT 2's complement)
1002     The interpretation of the floating-point number is:
1003 	>>> 2.mantissia(fraction) X 2^exponent. <<<
1004 
1005 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
1006     Bits: sign-bit, 11-bit exponent, 52-bit mantissa
1007 
1008 ***Cray (Cray CFT77 Reference Manual, pages G-1 G-2)
1009 I8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
1010 	 MSB-----------------------------------------------------LSB
1011 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
1012     Bits: sign-bit, exponent-sign, 14-bit exponent, 48-bit mantissa
1013 Note: Exponent sign:  1 in this bits indicates a positive exponent sign,
1014    thus bit 62 is the inverse of bit 61 (the sign in the exponent).
1015    The exception to this is a zero, in which all 64 bits are zero!
1016     The interpretation of the floating-point number is:
1017 	>>> .mantissia(fraction) X 2^exponent. <<<
1018    The mantissia is left justified (the leftmost bit is a 1).
1019      This MUST be done!
1020 
1021 ***
1022 
1023    Possible errors:
1024 NO_ERROR
1025 NULL_STRING_POINTER
1026 NULL_POINTER
1027 ***********************************************************************/
ADFI_big_endian_to_cray(const char from_format,const char from_os_size,const char to_format,const char to_os_size,const char data_type[2],const cgulong_t delta_from_bytes,const cgulong_t delta_to_bytes,const unsigned char * from_data,unsigned char * to_data,int * error_return)1028 void    ADFI_big_endian_to_cray(
1029 		const char from_format,
1030 		const char from_os_size,
1031 		const char to_format,
1032 		const char to_os_size,
1033 		const char data_type[2],
1034 		const cgulong_t delta_from_bytes,
1035 		const cgulong_t delta_to_bytes,
1036 		const unsigned char *from_data,
1037 		unsigned char *to_data,
1038 		int *error_return )
1039 {
1040 int		i, exp ;
1041 
1042 if( (from_data == NULL) || (to_data == NULL) ) {
1043    *error_return = NULL_STRING_POINTER ;
1044    return ;
1045    } /* end if */
1046 
1047 if( (delta_from_bytes == 0) || (delta_to_bytes == 0) ) {
1048    *error_return = NULL_POINTER ;
1049    return ;
1050    } /* end if */
1051 
1052 if( (from_format == 'N') || (to_format == 'N') ) {
1053    *error_return = CANNOT_CONVERT_NATIVE_FORMAT ;
1054    return ;
1055    } /* end if */
1056 
1057 *error_return = NO_ERROR ;
1058 
1059 switch( EVAL_2_BYTES( data_type[0], data_type[1] ) ) {
1060 
1061    case EVAL_2_BYTES( 'M', 'T' ):
1062       *error_return = NO_DATA ;
1063       return ;
1064 
1065    case EVAL_2_BYTES( 'C', '1' ):
1066    case EVAL_2_BYTES( 'B', '1' ):
1067       to_data[0] = from_data[0] ;
1068       break ;
1069 
1070    case EVAL_2_BYTES( 'I', '4' ):
1071       if( (from_data[0] & 0x80) == 0x80 ) { /* Negative number */
1072          to_data[0] = 0xff ;
1073          to_data[1] = 0xff ;
1074          to_data[2] = 0xff ;
1075          to_data[3] = 0xff ;
1076       } /* end if */
1077       else {
1078          to_data[0] = 0x00 ;
1079          to_data[1] = 0x00 ;
1080          to_data[2] = 0x00 ;
1081          to_data[3] = 0x00 ;
1082       } /* end else */
1083       to_data[4] = from_data[0] ;
1084       to_data[5] = from_data[1] ;
1085       to_data[6] = from_data[2] ;
1086       to_data[7] = from_data[3] ;
1087       break ;
1088 
1089    case EVAL_2_BYTES( 'U', '4' ):
1090       to_data[0] = 0x00 ;
1091       to_data[1] = 0x00 ;
1092       to_data[2] = 0x00 ;
1093       to_data[3] = 0x00 ;
1094       to_data[4] = from_data[0] ;
1095       to_data[5] = from_data[1] ;
1096       to_data[6] = from_data[2] ;
1097       to_data[7] = from_data[3] ;
1098       break ;
1099 
1100    case EVAL_2_BYTES( 'I', '8' ):
1101       if( (from_data[0] & 0x80) == 0x80 ) { /* Negative number */
1102          to_data[0] = 0xff ;
1103          to_data[1] = 0xff ;
1104          to_data[2] = 0xff ;
1105          to_data[3] = 0xff ;
1106       } /* end if */
1107       else {
1108          to_data[0] = 0x00 ;
1109          to_data[1] = 0x00 ;
1110          to_data[2] = 0x00 ;
1111          to_data[3] = 0x00 ;
1112       } /* end else */
1113       for( i=0; i<(int)delta_from_bytes; i++ )
1114          to_data[8-delta_from_bytes+i] = from_data[i] ;
1115       break ;
1116 
1117    case EVAL_2_BYTES( 'U', '8' ):
1118       to_data[0] = 0x00 ;
1119       to_data[1] = 0x00 ;
1120       to_data[2] = 0x00 ;
1121       to_data[3] = 0x00 ;
1122       for( i=0; i<(int)delta_from_bytes; i++ )
1123          to_data[8-delta_from_bytes+i] = from_data[i] ;
1124       break ;
1125 
1126    case EVAL_2_BYTES( 'R', '4' ):
1127       for( i=0; i<8; i++ )
1128          to_data[i] = 0x00 ;
1129 
1130    /** Check for zero: a special case on the Cray (exponent sign) **/
1131       if( (from_data[0] == 0x00) && (from_data[1] == 0x00) &&
1132           (from_data[2] == 0x00) && (from_data[3] == 0x00) )
1133       break ;
1134 
1135    /** Convert the sign **/
1136       to_data[0] = from_data[0] & 0x80 ;
1137 
1138    /** Convert the exponent **/
1139    /** 8 bits to  14 bits.  Sign extent from 8 to 14 **/
1140    /** Cray exponent is 2 greater than the Iris **/
1141       exp = (from_data[0] & 0x3f) << 1 ;
1142       if( (from_data[1] & 0x80) == 0x80 )
1143          exp += 1 ;
1144       if( (from_data[0] & 0x40) == 0x00 ) /* set sign */
1145          exp -= 128 ;
1146       exp += 2 ;
1147 
1148       to_data[1] = exp & 0xff ;
1149       if( exp < 0 )
1150          to_data[0] |= 0x3f ; /* exponent sign 0, sign extend exponent */
1151       else
1152          to_data[0] |= 0x40 ; /* exponent sign 1 */
1153 
1154    /** Convert the mantissia **/
1155    /** 23 bits to 48 bits.  Left shift 25 bits, zero fill **/
1156       to_data[2] = from_data[1] | 0x80 ;
1157       to_data[3] = from_data[2] ;
1158       to_data[4] = from_data[3] ;
1159       break ;
1160 
1161    case EVAL_2_BYTES( 'R', '8' ):
1162       for( i=0; i<8; i++ )
1163          to_data[i] = 0x00 ;
1164 
1165    /** Check for zero: a special case on the Cray (exponent sign) **/
1166       if( (from_data[0] == 0x00) && (from_data[1] == 0x00) &&
1167           (from_data[2] == 0x00) && (from_data[3] == 0x00) )
1168       break ;
1169 
1170    /** Convert the sign **/
1171       to_data[0] = from_data[0] & 0x80 ;
1172 
1173    /** Convert the exponent **/
1174    /** 11 bits to  14 bits.  Sign extent from 11 to 14 **/
1175    /** Cray exponent is 2 greater than the Iris **/
1176       exp = ((from_data[0] & 0x3f) << 4) + ((from_data[1]>>4)&0x0f) ;
1177 
1178       if( (from_data[0] & 0x40) == 0x00 ) /* set sign */
1179          exp -= 1024 ;
1180       exp += 2 ;
1181 
1182       to_data[1] = (unsigned int)(exp & 0xff) ;
1183       to_data[0] |= ((exp>>8) & 0x03) ;
1184       if( exp < 0 )
1185          to_data[0] |= 0x3c ; /* exponent sign 0, sign extend exponent */
1186       else
1187          to_data[0] |= 0x40 ; /* exponent sign 1 */
1188 
1189    /** Convert the mantissia **/
1190    /** 52 bits to 48 bits.  Use 48, drop last 4 bits **/
1191       to_data[2] = 0x80 | ((from_data[1]<<3)&0x78) |
1192                           ((from_data[2]>>5)&0x07) ;
1193       for( i=3; i<8; i++ )
1194          to_data[i] = ((from_data[i-1]<<3)&0xF8) |
1195                       ((from_data[i]>>5)&0x07) ;
1196 #ifdef PRINT_STUFF
1197 printf("from:" ) ;
1198 for( i=0; i<8; i++ )
1199    printf("%02x ", from_data[i] ) ;
1200 printf("to:" ) ;
1201 for( i=0; i<8; i++ )
1202    printf("%02x ", to_data[i] ) ;
1203 printf("\n" ) ;
1204 #endif
1205       break ;
1206 
1207    case EVAL_2_BYTES( 'X', '4' ):
1208       ADFI_big_endian_to_cray( from_format, from_os_size,
1209 	 to_format, to_os_size, "R4", delta_from_bytes,
1210 	 delta_to_bytes, from_data, to_data, error_return ) ;
1211       if( *error_return != NO_ERROR )
1212          return ;
1213 
1214       ADFI_big_endian_to_cray( from_format, from_os_size,
1215 	 to_format, to_os_size, "R4", delta_from_bytes,
1216 	 delta_to_bytes, &from_data[4], &to_data[8], error_return ) ;
1217       if( *error_return != NO_ERROR )
1218          return ;
1219       break ;
1220 
1221    case EVAL_2_BYTES( 'X', '8' ):
1222       ADFI_big_endian_to_cray( from_format, from_os_size,
1223 	 to_format, to_os_size, "R8", delta_from_bytes,
1224 	 delta_to_bytes, from_data, to_data, error_return ) ;
1225       if( *error_return != NO_ERROR )
1226          return ;
1227 
1228       ADFI_big_endian_to_cray( from_format, from_os_size,
1229 	 to_format, to_os_size, "R8", delta_from_bytes,
1230 	 delta_to_bytes, &from_data[8], &to_data[8], error_return ) ;
1231       if( *error_return != NO_ERROR )
1232          return ;
1233       break ;
1234 
1235    default:
1236       *error_return = INVALID_DATA_TYPE ;
1237       return ;
1238    } /* end switch */
1239 } /* end of ADFI_big_endian_to_cray */
1240 /* end of file ADFI_big_endian_to_cray.c */
1241 /* file ADFI_big_little_endian_swap.c */
1242 /***********************************************************************
1243 ADFI big little endian swap:
1244 
1245 input:  const char from_format		Format to convert from. 'B','L','C','N'
1246 input:  const char from_os_size		Format to convert from. 'B','L'
1247 input:  const char to_format		Format to convert to.
1248 input:  const char to_os_size		Format to convert to. 'B','L'
1249 input:  const char data_type[2]		The type of data to convert.
1250 					   MT I4 I8 U4 U8 R4 R8 X4 X8 C1 B1
1251 input:  const unsigned long delta_from_bytes Number of from_bytes used.
1252 input:  const unsigned long delta_to_bytes	Number of to_bytes used.
1253 input:  const char *from_data		The data to convert from.
1254 output: char *to_data			The resulting data.
1255 output:	int *error_return		Error return.
1256 
1257   Recognized data types:
1258 					Machine representations
1259         Type		  Notation     IEEE_BIG	  IEEE_LITTLE   Cray
1260 	                               32    64   32    64
1261   No data                   MT
1262   Integer 32                I4         I4    I4    I4   I4       I8
1263   Integer 64                I8         --    I8    --   I8       I8
1264   Unsigned 32               U4         I4    I4    I4   I4       I8
1265   Unsigned 64               U8         --    I8    --   I8       I8
1266   Real 32                   R4         R4    R4    R4   R4       R8
1267   Real 64                   R8         R8    R8    R8   R8       R8
1268   Complex 64                X4         R4R4  R4R4  R4R4 R4R4     R8R8
1269   Complex 128               X8         R8R8  R8R8  R8R8 R8R8     R8R8
1270   Character (unsigned byte) C1         C1    C1    C1   C1       C1
1271   Byte (unsigned byte)      B1         C1    C1    C1   C1       C1
1272 
1273 Machine Numeric Formats:
1274 ***IEEE_BIG (SGI-Iris Assembly Language Programmer's Guide, pages 1-2, 6-3)
1275 I4:	Byte0	Byte1	Byte2	Byte3
1276 	 MSB---------------------LSB
1277 R4:	Byte0	Byte1	Byte2	Byte3
1278     Bits: sign-bit, 8-bit exponent, 23-bit mantissa
1279     The sign of the exponent is:  1=positive, 0=negative (NOT 2's complement)
1280     The interpretation of the floating-point number is:
1281 	>>> 2.mantissia(fraction) X 2^exponent. <<<
1282 
1283 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
1284     Bits: sign-bit, 11-bit exponent, 52-bit mantissa
1285 
1286 Machine Numeric Formats:
1287 ***IEEE_LITTLE ( The backwards Big Endian )
1288 I4:	Byte0	Byte1	Byte2	Byte3
1289 	 LSB---------------------MSB
1290 R4:	Byte0	Byte1	Byte2	Byte3
1291     Bits: 23-bit mantissa, 8-bit exponent, sign-bit
1292     The sign of the exponent is:  1=positive, 0=negative (NOT 2's complement)
1293     The interpretation of the floating-point number is:
1294 	>>> 2.mantissia(fraction) X 2^exponent. <<<
1295 
1296 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
1297     Bits:  52-bit mantissa, 11-bit exponent, sign-bit
1298 
1299 Note: To convert between these two formats the order of the bytes is reversed
1300 since by definition the Big endian starts at the LSB and goes to the MSB where
1301 the little goes form the MSB to the LSB of the word.
1302 ***
1303 
1304    Possible errors:
1305 NO_ERROR
1306 NULL_STRING_POINTER
1307 NULL_POINTER
1308 ***********************************************************************/
ADFI_big_little_endian_swap(const char from_format,const char from_os_size,const char to_format,const char to_os_size,const char data_type[2],const cgulong_t delta_from_bytes,const cgulong_t delta_to_bytes,const unsigned char * from_data,unsigned char * to_data,int * error_return)1309 void    ADFI_big_little_endian_swap(
1310 		const char from_format,
1311 		const char from_os_size,
1312 		const char to_format,
1313 		const char to_os_size,
1314 		const char data_type[2],
1315 		const cgulong_t delta_from_bytes,
1316 		const cgulong_t delta_to_bytes,
1317 		const unsigned char *from_data,
1318 		unsigned char *to_data,
1319 		int *error_return )
1320 {
1321 int i ;
1322 
1323 if( (from_data == NULL) || (to_data == NULL) ) {
1324    *error_return = NULL_STRING_POINTER ;
1325    return ;
1326    } /* end if */
1327 
1328 if( (delta_from_bytes == 0) || (delta_to_bytes == 0) ) {
1329    *error_return = NULL_POINTER ;
1330    return ;
1331    } /* end if */
1332 
1333 if( (from_format == 'N') || (to_format == 'N') ) {
1334    *error_return = CANNOT_CONVERT_NATIVE_FORMAT ;
1335    return ;
1336    } /* end if */
1337 
1338 if ( from_os_size != to_os_size || delta_to_bytes != delta_from_bytes ) {
1339    *error_return = DATA_TYPE_NOT_SUPPORTED ;
1340    return ;
1341 } /** end if **/
1342 
1343 *error_return = NO_ERROR ;
1344 
1345 for ( i=0; i<(int)delta_from_bytes; i++ )
1346   to_data[i] = from_data[delta_from_bytes-1-i] ;
1347 
1348 } /* end of ADFI_big_little_endian_swap */
1349 /* end of file ADFI_big_little_endian_swap.c */
1350 /* file ADFI_blank_fill_string.c */
1351 /***********************************************************************
1352 ADFI blank fill string:
1353 
1354 input/output: char *str		The string to fill with blanks.
1355 input:  const int length	The total length of the string to fill.
1356 ***********************************************************************/
ADFI_blank_fill_string(char * str,const int length)1357 void ADFI_blank_fill_string(
1358 		char *str,
1359 		const int length )
1360 {
1361 int     i ;
1362 for( i=(int)strlen( str ); i<length; i++ )
1363    str[ i ] = ' ' ;
1364 }
1365 /* end of file ADFI_blank_fill_string.c */
1366 /***********************************************************************
1367 ADFI find file
1368 
1369 input/output: char *filename	The filename to locate
1370 output: int *error_return       Error return.
1371 ***********************************************************************/
ADFI_find_file(char * parentfile,char * filename,int * error_return)1372 void ADFI_find_file(char *parentfile, char *filename, int *error_return)
1373 {
1374   char pathname[ADF_FILENAME_LENGTH+1];
1375 
1376   if (cgio_find_file(parentfile, filename, CGIO_FILE_ADF, sizeof(pathname), pathname)) {
1377     *error_return = LINKED_TO_FILE_NOT_THERE;
1378   }
1379   else {
1380     strcpy(filename, pathname);
1381     *error_return = NO_ERROR;
1382   }
1383 }
1384 /***********************************************************************
1385 ADFI link open
1386 
1387 input:  char *linkfile		The linkfile to open
1388 input:  char *status            open status
1389 output: double *link_ID         root id of opened file
1390 output: unsigned int *link_index file index od link file
1391 output: int *error_return       Error return.
1392 ***********************************************************************/
ADFI_link_open(char * linkfile,char * status,double * link_ID,unsigned int * link_index,int * error_return)1393 static void ADFI_link_open(
1394 	char *linkfile,
1395         char *status,
1396         double *link_ID,
1397         unsigned int *link_index,
1398         int *error_return)
1399 {
1400    cgulong_t file_block, block_offset;
1401 
1402    ADF_Database_Open( linkfile, status, "", link_ID, error_return ) ;
1403    if (*error_return == NO_ERROR) {
1404       ADFI_ID_2_file_block_offset(*link_ID, link_index,
1405          &file_block, &block_offset, error_return);
1406    }
1407 }
1408 /***********************************************************************
1409 ADFI link add
1410 
1411 input:  file_index	the file that references the link
1412 input:  link_index      the link file
1413 input:  found           set if link file was already open
1414 ***********************************************************************/
ADFI_link_add(unsigned int file_index,unsigned int link_index,int found)1415 static void ADFI_link_add(
1416         unsigned int file_index,
1417         unsigned int link_index,
1418         int found)
1419 {
1420    int n, nlinks;
1421    unsigned int *links;
1422 
1423    if (file_index == link_index) return;
1424    nlinks = ADF_file[file_index].nlinks;
1425    if (nlinks == 0) {
1426       links = (unsigned int *) malloc (sizeof(unsigned int));
1427    }
1428    else {
1429       links  = ADF_file[file_index].links;
1430       for (n = 0; n < nlinks; n++) {
1431          if (links[n] == link_index) return;
1432       }
1433       links = (unsigned int *) malloc ((nlinks + 1) * sizeof(unsigned int));
1434    }
1435    if (links == NULL) return;
1436    if (nlinks) {
1437       for (n = 0; n < nlinks; n++)
1438          links[n] = ADF_file[file_index].links[n];
1439       free (ADF_file[file_index].links);
1440    }
1441    links[nlinks] = link_index;
1442    ADF_file[file_index].nlinks = nlinks + 1;
1443    ADF_file[file_index].links  = links;
1444    if (found) {
1445       (ADF_file[link_index].in_use)++;
1446    }
1447 }
1448 /* file ADFI_chase_link.c */
1449 /***********************************************************************
1450 ADFI chase link:
1451     Given an ID, return the ID, file, block/offset, and node header
1452     of the node.  If the ID is a link, traverse the link(s) until a
1453     non-link node is found.  This is the data returned.
1454 
1455 input:  const double ID         ID of the node.
1456 output: double *LID             ID of the non-link node (may == ID)
1457 output: unsigned int *file_index           File-index for LID.
1458 output: struct DISK_POINTER *block_offset  Block/offset for LID.
1459 output: struct NODE_HEADER *node_header    The node header for LID.
1460 output: int *error_return       Error return.
1461 ***********************************************************************/
ADFI_chase_link(const double ID,double * LID,unsigned int * file_index,struct DISK_POINTER * block_offset,struct NODE_HEADER * node_header,int * error_return)1462 void    ADFI_chase_link(
1463         const double ID,
1464         double *LID,
1465         unsigned int *file_index,
1466         struct DISK_POINTER *block_offset,
1467         struct NODE_HEADER *node_header,
1468         int *error_return )
1469 {
1470 double        Link_ID, temp_ID ;
1471 int           done = FALSE ;
1472 int           link_depth = 0 ;
1473 int           found ;
1474 unsigned int  link_file_index ;
1475 char          status[10] ;
1476 char          link_file[ADF_FILENAME_LENGTH+1],
1477               link_path[ADF_MAX_LINK_DATA_SIZE+1] ;
1478 
1479 if( (LID == NULL) || (file_index == NULL) || (block_offset == NULL) ||
1480    (node_header == NULL ) ) {
1481    *error_return = NULL_POINTER ;
1482    return ;
1483 } /* end if */
1484 
1485 if (ID == last_link_ID) {
1486    *LID = last_link_LID;
1487    ADFI_ID_2_file_block_offset( last_link_LID, file_index, &block_offset->block,
1488                 &block_offset->offset, error_return ) ;
1489    if( *error_return != NO_ERROR )
1490       return ;
1491    ADFI_read_node_header( *file_index, block_offset, node_header,
1492                 error_return ) ;
1493    return ;
1494 }
1495 
1496 Link_ID = ID ;
1497 while( done == FALSE ) {
1498     /** Get the file, block, and offset numbers from the ID **/
1499    ADFI_ID_2_file_block_offset( Link_ID, file_index, &block_offset->block,
1500                 &block_offset->offset, error_return ) ;
1501    CHECK_ABORT(*error_return);
1502 
1503         /** Get node_header for the node **/
1504    ADFI_read_node_header( *file_index, block_offset, node_header,
1505                 error_return ) ;
1506    CHECK_ABORT(*error_return);
1507 
1508    if( (node_header->data_type[0] == 'L') &&
1509        (node_header->data_type[1] == 'K')) {
1510 
1511     /** node is a link get file and path data  **/
1512       ADF_Get_Link_Path( Link_ID, link_file, link_path, error_return ) ;
1513       CHECK_ABORT(*error_return);
1514 
1515       if( link_file[0] != '\0' ) { /* A filename is specified, open it. **/
1516          /* locate the file */
1517          ADFI_find_file(ADF_file[*file_index].file_name, link_file, error_return);
1518          CHECK_ABORT(*error_return);
1519 
1520          /** Link_ID = root-node of the new file.
1521              note:  the file could already be opened, and may be the
1522 	     current file! **/
1523 
1524          ADFI_get_file_index_from_name( link_file, &found, &link_file_index,
1525                                         &Link_ID, error_return ) ;
1526          if( ! found ) { /** Not found; try to open it **/
1527             if (ACCESS(link_file,2)) /* check for read-only mode */
1528                strcpy (status, "READ_ONLY");
1529             else /* open in same mode as current file */
1530                strcpy (status, ADF_file[*file_index].open_mode) ;
1531             if ( ADFI_stridx_c(status, "READ_ONLY" ) != 0 )
1532                 strcpy (status, "OLD") ;
1533             ADFI_link_open( link_file, status, &Link_ID,
1534                             &link_file_index, error_return );
1535             CHECK_ABORT(*error_return);
1536          } /* end else */
1537          ADFI_link_add( *file_index, link_file_index, found );
1538       } /* end if */
1539       else {  /* filename NOT specified, file must be root of link */
1540          ADF_Get_Node_ID( Link_ID, "/", &temp_ID, error_return ) ;
1541          CHECK_ABORT(*error_return);
1542          Link_ID = temp_ID ;
1543       } /* end else */
1544 
1545         /** Get the node ID of the link to node (may be other links) **/
1546       ADF_Get_Node_ID( Link_ID, link_path, &temp_ID, error_return ) ;
1547       if( *error_return == CHILD_NOT_OF_GIVEN_PARENT )
1548          *error_return = LINK_TARGET_NOT_THERE ; /* A better error message */
1549       CHECK_ABORT(*error_return);
1550 
1551       Link_ID = temp_ID ;
1552       if( ++link_depth > ADF_MAXIMUM_LINK_DEPTH ) {
1553          *error_return = LINKS_TOO_DEEP ;
1554          return ;
1555       } /* end if */
1556    } /* end if */
1557    else { /** node is NOT a link **/
1558       done = TRUE ;
1559    } /* end else */
1560 } /* end while */
1561 
1562 *LID = Link_ID ;
1563 if (Link_ID != ID) {
1564    last_link_ID = ID;
1565    last_link_LID = Link_ID;
1566 }
1567 
1568 } /* end of ADFI_chase_link */
1569 /* end of file ADFI_chase_link.c */
1570 /* file ADFI_check_4_child_name.c */
1571 /***********************************************************************
1572 ADFI check 4 child name:
1573 
1574 input:  const int file_index		Index of ADF file.
1575 input:  const struct DISK_POINTER *parent Location of the parent
1576 input:  const char *name		The name of the new child.
1577 output: int *found			0 if NOT found, else 1.
1578 output: struct DISK_POINTER *sub_node_entry_location
1579 output: struct SUB_NODE_TABLE_ENTRY *sub_node_entry
1580 output:	int *error_return		Error return.
1581 
1582    Possible errors:
1583 NO_ERROR
1584 NULL_POINTER
1585 NULL_STRING_POINTER
1586 ADF_FILE_NOT_OPENED
1587 MEMORY_ALLOCATION_FAILED
1588 ***********************************************************************/
ADFI_check_4_child_name(const int file_index,const struct DISK_POINTER * parent,const char * name,int * found,struct DISK_POINTER * sub_node_entry_location,struct SUB_NODE_TABLE_ENTRY * sub_node_entry,int * error_return)1589 void    ADFI_check_4_child_name(
1590 		const int file_index,
1591 		const struct DISK_POINTER *parent,
1592 		const char *name,
1593 		int *found,
1594 		struct DISK_POINTER *sub_node_entry_location,
1595 		struct SUB_NODE_TABLE_ENTRY *sub_node_entry,
1596 		int *error_return )
1597 {
1598 struct	NODE_HEADER	parent_node ;
1599 struct SUB_NODE_TABLE_ENTRY *sub_node_table ;
1600 int			i ;
1601 
1602 if( (parent == NULL) || (found == NULL) || (sub_node_entry_location == NULL) ||
1603 	(sub_node_entry == NULL ) ) {
1604    *error_return = NULL_POINTER ;
1605    return ;
1606    } /* end if */
1607 
1608 if( name == NULL ) {
1609    *error_return = NULL_STRING_POINTER ;
1610    return ;
1611    } /* end if */
1612 
1613 if( file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
1614    *error_return = ADF_FILE_NOT_OPENED ;
1615    return ;
1616    } /* end if */
1617 
1618 *error_return = NO_ERROR ;
1619 *found = 0 ;	/* default to NOT found */
1620 
1621 	/** Get node_header for the node **/
1622 ADFI_read_node_header( file_index, parent, &parent_node, error_return ) ;
1623 if( *error_return != NO_ERROR )
1624    return ;
1625 
1626 	/** Check for valid node name **/
1627 
1628 	/** If parent has no children, the new name MUST be NOT found **/
1629 if( parent_node.num_sub_nodes == 0 ) {
1630    *found = 0 ;
1631    return ;
1632    } /* end if */
1633 
1634 	/** Allocate memory for the required table space in memory **/
1635 sub_node_table = (struct SUB_NODE_TABLE_ENTRY *)
1636                  malloc( parent_node.entries_for_sub_nodes *
1637 	         sizeof( *sub_node_table ) ) ;
1638 if( sub_node_table == NULL ) {
1639    *error_return = MEMORY_ALLOCATION_FAILED ;
1640    return ;
1641    } /* end if */
1642 
1643 if( parent_node.entries_for_sub_nodes > 0 ) {
1644    ADFI_read_sub_node_table( file_index, &parent_node.sub_node_table,
1645 	   sub_node_table, error_return ) ;
1646    if( *error_return != NO_ERROR )
1647       return ;
1648    } /* end if */
1649 
1650 	/** Check all names for our new name **/
1651 for( i=0; i<(int)parent_node.num_sub_nodes; i++ ) {
1652    ADFI_compare_node_names( sub_node_table[i].child_name, name,
1653 	found, error_return ) ;
1654    if( *error_return != NO_ERROR )
1655       break ;
1656    if( *found == 1 ) {	/* name was found, save off addresses */
1657       sub_node_entry_location->block = parent_node.sub_node_table.block ;
1658       sub_node_entry_location->offset = parent_node.sub_node_table.offset +
1659 		TAG_SIZE + DISK_POINTER_SIZE +
1660 		(ADF_NAME_LENGTH + DISK_POINTER_SIZE) * i ;
1661 
1662       ADFI_adjust_disk_pointer( sub_node_entry_location, error_return ) ;
1663       if( *error_return != NO_ERROR )
1664          return ;
1665 
1666 	/** Also save off the child's name **/
1667       strncpy( sub_node_entry->child_name, sub_node_table[i].child_name,
1668 		ADF_NAME_LENGTH ) ;
1669       sub_node_entry->child_location.block =
1670 		sub_node_table[i].child_location.block ;
1671       sub_node_entry->child_location.offset =
1672 		sub_node_table[i].child_location.offset ;
1673 
1674 	/** Get out of the for loop **/
1675       break ;
1676       } /* end if */
1677    } /* end for */
1678 
1679 free( sub_node_table ) ;
1680 } /* end of ADFI_check_4_child_name */
1681 /* end of file ADFI_check_4_child_name.c */
1682 /* file ADFI_check_string_length.c */
1683 /***********************************************************************
1684 ADFI check string length:
1685 	Check a character string for:
1686 	   being a NULL pointer,
1687 	   being too long,
1688 	   being zero length.
1689 
1690 input:  const char *str			The input string.
1691 input:  const int max_length		Maximum allowable length of the string.
1692 output:	int *error_return		Error return.
1693 
1694    Possible errors:
1695 NO_ERROR
1696 NULL_STRING_POINTER
1697 STRING_LENGTH_ZERO
1698 STRING_LENGTH_TOO_BIG
1699 ***********************************************************************/
ADFI_check_string_length(const char * str,const int max_length,int * error_return)1700 void    ADFI_check_string_length(
1701 		const char *str,
1702 		const int max_length,
1703 		int *error_return )
1704 {
1705 int	str_length, i ;
1706 
1707 if( str == NULL ) {
1708    *error_return = NULL_STRING_POINTER ;
1709    return ;
1710    } /* end if */
1711 
1712 str_length = (int)strlen( str ) ;
1713 if( str_length == 0 ) {
1714    *error_return = STRING_LENGTH_ZERO ;
1715    return ;
1716    } /* end if */
1717 
1718 if( (int) strlen( str ) > max_length ) {
1719    *error_return = STRING_LENGTH_TOO_BIG ;
1720    return ;
1721    } /* end if */
1722 
1723 	/** Check for blank string **/
1724 *error_return = STRING_LENGTH_ZERO ;
1725 for( i=0; i<str_length; i++ ) {
1726    if( (str[i] != ' ') && (str[i] != '\t') )  {
1727       *error_return = NO_ERROR ;
1728       break ;
1729       } /* end if */
1730    } /* end for */
1731 }
1732 /* end of file ADFI_check_string_length.c */
1733 /* file ADFI_close_file.c */
1734 /***********************************************************************
1735 ADFI close file:
1736 	Close the indicated ADF file, and also all files with this file's
1737 	index as their top index.
1738 
1739 input:  const int top_file_index	Index of top ADF file.
1740 output:	int *error_return		Error return.
1741 
1742    Possible errors:
1743 NO_ERROR
1744 ADF_FILE_NOT_OPENED
1745 ***********************************************************************/
ADFI_close_file(const int file_index,int * error_return)1746 void    ADFI_close_file(
1747 		const int file_index,
1748 		int *error_return )
1749 {
1750 int index ;
1751 
1752 if( file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
1753    *error_return = ADF_FILE_NOT_OPENED ;
1754    return ;
1755 } /* end if */
1756 
1757 *error_return = NO_ERROR ;
1758 
1759 /* close files that his file links to */
1760 for (index = 0; index < ADF_file[file_index].nlinks; index++) {
1761    ADFI_close_file( ADF_file[file_index].links[index], error_return);
1762 }
1763 
1764 /* don't close until in_use is 0 */
1765 index = ADF_file[file_index].in_use - 1;
1766 if ( index == 0) {
1767    ADF_sys_err = 0;
1768    if( ADF_file[file_index].file >= 0 ) {
1769       ADFI_flush_buffers( file_index, FLUSH_CLOSE, error_return );
1770       if( CLOSE( ADF_file[file_index].file ) < 0 ) {
1771          ADF_sys_err = errno;
1772          *error_return = FILE_CLOSE_ERROR ;
1773       }
1774    } /* end if */
1775    ADF_file[file_index].file = -1 ;
1776 	/** Clear this file's entry **/
1777    ADFI_stack_control(file_index,0,0,CLEAR_STK,0,0,NULL);
1778 
1779    if (ADF_file[file_index].nlinks) {
1780        free (ADF_file[file_index].links);
1781        ADF_file[file_index].nlinks = 0;
1782    }
1783    if (ADF_file[file_index].file_name != NULL) {
1784       free (ADF_file[file_index].file_name);
1785       ADF_file[file_index].file_name = NULL;
1786    }
1787 }
1788 ADF_file[file_index].in_use = index;
1789 
1790 /* if no more files open, free data structure */
1791 
1792 for (index = 0; index < maximum_files; index++) {
1793    if (ADF_file[index].in_use) return;
1794 }
1795 free (ADF_file);
1796 maximum_files = 0;
1797 
1798 } /* end of ADFI_close_file */
1799 /* end of file ADFI_close_file.c */
1800 /* file ADFI_compare_node_names.c */
1801 /***********************************************************************
1802 ADFI compare node names:
1803 
1804 input:  const char *name	Existing node name.
1805 input:  const char *new_name	New node name.
1806 output: int *names_match	0 if name do NOT match, else 1.
1807 output:	int *error_return	Error return.
1808 
1809    Possible errors:
1810 NO_ERROR
1811 NULL_STRING_POINTER
1812 NULL_POINTER
1813 ***********************************************************************/
ADFI_compare_node_names(const char * name,const char * new_name,int * names_match,int * error_return)1814 void    ADFI_compare_node_names(
1815 		const char *name,
1816 		const char *new_name,
1817 		int *names_match,
1818 		int *error_return )
1819 {
1820 int	i, new_length ;
1821 
1822 if( (name == NULL) || (new_name == NULL) ) {
1823    *error_return = NULL_STRING_POINTER ;
1824    return ;
1825    } /* end if */
1826 
1827 if( names_match == NULL ) {
1828    *error_return = NULL_POINTER ;
1829    return ;
1830    } /* end if */
1831 
1832 *error_return = NO_ERROR ;
1833 *names_match = 0 ;	/* Default to NO match */
1834 
1835 new_length = (int)strlen( new_name ) ;
1836 for( i=0; i<MIN( new_length, ADF_NAME_LENGTH ); i++ ) {
1837    if( name[i] != new_name[i] ) {
1838       *names_match = 0 ;
1839       return ;
1840       } /* end if */
1841    } /* end for */
1842 
1843 	/** Name mattched for the length of the new name.
1844 	    The existing node name must only contain blanks from here
1845 	**/
1846 for( ; i<ADF_NAME_LENGTH; i++ ) {
1847    if( name[i] != ' ' ) {
1848       *names_match = 0 ;	/* Not blank, NO match, get out **/
1849       return ;
1850       } /* end if */
1851    } /* end for */
1852 
1853 *names_match = 1 ;	/* Yes, they match */
1854 } /* end of ADFI_compare_node_names */
1855 /* end of file ADFI_compare_node_names.c */
1856 /* file ADFI_convert_number_format.c */
1857 /***********************************************************************
1858 ADFI convert number format:
1859 
1860 input:  const char from_format		Format to convert from. 'B','L','C','N'
1861 input:  const char from_os_size		os size to convert from. 'B','L'
1862 input:  const char to_format		Format to convert to.
1863 input:  const char to_os_size		os size to convert to. 'B','L'
1864 input:  const int  convert_dir          Convert direction from/to file format
1865 input:  const struct TOKENIZED_DATA_TYPE *tokenized_data_type Array.
1866 					   MT I4 I8 U4 U8 R4 R8 X4 X8 C1 B1
1867 input:  const unsigned int length	The number of tokens to convert.
1868 input:  const char *from_data		The data to convert from.
1869 output: char *to_data			The resulting data.
1870 output:	int *error_return		Error return.
1871 
1872   Recognized data types:
1873 					Machine representations
1874         Type		  Notation     IEEE_BIG	  IEEE_LITTLE   Cray
1875 	                               32    64   32    64
1876   No data                   MT
1877   Integer 32                I4         I4    I4    I4   I4       I8
1878   Integer 64                I8         --    I8    --   I8       I8
1879   Unsigned 32               U4         I4    I4    I4   I4       I8
1880   Unsigned 64               U8         --    I8    --   I8       I8
1881   Real 32                   R4         R4    R4    R4   R4       R8
1882   Real 64                   R8         R8    R8    R8   R8       R8
1883   Complex 64                X4         R4R4  R4R4  R4R4 R4R4     R8R8
1884   Complex 128               X8         R8R8  R8R8  R8R8 R8R8     R8R8
1885   Character (unsigned byte) C1         C1    C1    C1   C1       C1
1886   Byte (unsigned byte)      B1         C1    C1    C1   C1       C1
1887 
1888 Machine Numeric Formats:
1889 ***IEEE_BIG (SGI-Iris Assembly Language Programmer's Guide, pages 1-2, 6-3)
1890 I4:	Byte0	Byte1	Byte2	Byte3
1891 	 MSB---------------------LSB
1892 R4:	Byte0	Byte1	Byte2	Byte3
1893     Bits: sign-bit, 8-bit exponent, 23-bit mantissa
1894     The sign of the exponent is:  1=positive, 0=negative (NOT 2's complement)
1895     The interpretation of the floating-point number is:
1896 	>>> 2.mantissia(fraction) X 2^exponent. <<<
1897 
1898 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
1899     Bits: sign-bit, 11-bit exponent, 52-bit mantissa
1900 
1901 Machine Numeric Formats:
1902 ***IEEE_LITTLE ( The backwards Big Endian )
1903 I4:	Byte0	Byte1	Byte2	Byte3
1904 	 LSB---------------------MSB
1905 R4:	Byte0	Byte1	Byte2	Byte3
1906     Bits: 23-bit mantissa, 8-bit exponent, sign-bit
1907     The sign of the exponent is:  1=positive, 0=negative (NOT 2's complement)
1908     The interpretation of the floating-point number is:
1909 	>>> 2.mantissia(fraction) X 2^exponent. <<<
1910 
1911 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
1912     Bits:  52-bit mantissa, 11-bit exponent, sign-bit
1913 
1914 ***Cray (Cray CFT77 Reference Manual, pages G-1 G-2)
1915 I8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
1916 	 MSB-----------------------------------------------------LSB
1917 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
1918     Bits: sign-bit, exponent-sign, 14-bit exponent, 48-bit mantissa
1919 Note: Exponent sign:  1 in this bits indicates a positive exponent sign,
1920    thus bit 62 is the inverse of bit 61 (the sign in the exponent).
1921    The exception to this is a zero, in which all 64 bits are zero!
1922     The interpretation of the floating-point number is:
1923 	>>> .mantissia(fraction) X 2^exponent. <<<
1924    The mantissia is left justified (the leftmost bit is a 1).
1925      This MUST be done!
1926 
1927 ***
1928 
1929    Possible errors:
1930 NO_ERROR
1931 NULL_STRING_POINTER
1932 NULL_POINTER
1933 ***********************************************************************/
ADFI_convert_number_format(const char from_format,const char from_os_size,const char to_format,const char to_os_size,const int convert_dir,const struct TOKENIZED_DATA_TYPE * tokenized_data_type,const unsigned int length,unsigned char * from_data,unsigned char * to_data,int * error_return)1934 void    ADFI_convert_number_format(
1935 		const char from_format,
1936 		const char from_os_size,
1937 		const char to_format,
1938 		const char to_os_size,
1939 		const int convert_dir,
1940 		const struct TOKENIZED_DATA_TYPE *tokenized_data_type,
1941 		const unsigned int length,
1942 		unsigned char *from_data,
1943 		unsigned char *to_data,
1944 		int *error_return )
1945 {
1946 unsigned char   temp_data[16] ;
1947 char            data_type[2] ;
1948 int		current_token ;
1949 int             array_size ;
1950 int             l, s ;
1951 cgulong_t	delta_from_bytes, delta_to_bytes ;
1952 
1953 if( (from_data == NULL) || (to_data == NULL) ) {
1954    *error_return = NULL_STRING_POINTER ;
1955    return ;
1956    } /* end if */
1957 
1958 if( length == 0 ) {
1959    *error_return = NUMBER_LESS_THAN_MINIMUM ;
1960    return ;
1961    } /* end if */
1962 
1963 if( (from_format == 'N') || (to_format == 'N') ) {
1964    *error_return = CANNOT_CONVERT_NATIVE_FORMAT ;
1965    return ;
1966    } /* end if */
1967 
1968 switch( EVAL_4_BYTES( from_format, to_format, from_os_size, to_os_size ) ) {
1969   case EVAL_4_BYTES( 'B', 'B', 'B', 'B' ):
1970   case EVAL_4_BYTES( 'C', 'C', 'B', 'B' ):
1971   case EVAL_4_BYTES( 'L', 'L', 'B', 'B' ):
1972   case EVAL_4_BYTES( 'B', 'B', 'L', 'L' ):
1973   case EVAL_4_BYTES( 'C', 'C', 'L', 'L' ):
1974   case EVAL_4_BYTES( 'L', 'L', 'L', 'L' ):
1975     *error_return = CONVERSION_FORMATS_EQUAL ;
1976     return ;
1977   } /* end switch */
1978 
1979 *error_return = NO_ERROR ;
1980 
1981    /** loop over each element **/
1982 for ( l=0; l<(int)length; l++ ) {
1983   current_token = -1 ;
1984   while( tokenized_data_type[ ++current_token ].type[0] != 0 ) {
1985     data_type[0] = tokenized_data_type[ current_token ].type[0] ;
1986     data_type[1] = tokenized_data_type[ current_token ].type[1] ;
1987     array_size   = tokenized_data_type[ current_token ].length ;
1988     if ( convert_dir == FROM_FILE_FORMAT ) {
1989       delta_from_bytes=tokenized_data_type[ current_token ].file_type_size ;
1990       delta_to_bytes  =tokenized_data_type[ current_token ].machine_type_size ;
1991     } /** end if **/
1992     else {
1993       delta_to_bytes  =tokenized_data_type[ current_token ].file_type_size ;
1994       delta_from_bytes=tokenized_data_type[ current_token ].machine_type_size ;
1995     } /** end else **/
1996 
1997     for ( s=0; s<array_size; s++ ) {
1998       switch( EVAL_4_BYTES( from_format,to_format,from_os_size,to_os_size ) ) {
1999 
2000        case EVAL_4_BYTES( 'B', 'B', 'L', 'B' ):
2001        case EVAL_4_BYTES( 'B', 'B', 'B', 'L' ):
2002          ADFI_big_endian_32_swap_64( from_format, from_os_size,
2003 				     to_format, to_os_size, data_type,
2004                                      delta_from_bytes, delta_to_bytes,
2005 				     from_data, to_data, error_return );
2006           break ;
2007 
2008        case EVAL_4_BYTES( 'L', 'L', 'L', 'B' ):
2009        case EVAL_4_BYTES( 'L', 'L', 'B', 'L' ):
2010          ADFI_little_endian_32_swap_64( from_format, from_os_size,
2011 			     	        to_format, to_os_size, data_type,
2012                                         delta_from_bytes, delta_to_bytes,
2013 				        from_data, to_data, error_return );
2014           break ;
2015 
2016        case EVAL_4_BYTES( 'B', 'C', 'L', 'B' ):
2017        case EVAL_4_BYTES( 'B', 'C', 'B', 'B' ):
2018          ADFI_big_endian_to_cray( from_format, from_os_size,
2019 				  to_format, to_os_size, data_type,
2020                                   delta_from_bytes, delta_to_bytes,
2021 				  from_data, to_data, error_return );
2022           break ;
2023 
2024        case EVAL_4_BYTES( 'C', 'B', 'B', 'L' ):
2025        case EVAL_4_BYTES( 'C', 'B', 'B', 'B' ):
2026          ADFI_cray_to_big_endian( from_format, from_os_size,
2027 				  to_format, to_os_size, data_type,
2028                                   delta_from_bytes, delta_to_bytes,
2029 				  from_data, to_data, error_return );
2030         break ;
2031 
2032        case EVAL_4_BYTES( 'B', 'L', 'B', 'L' ):
2033        case EVAL_4_BYTES( 'B', 'L', 'L', 'B' ):
2034          ADFI_big_endian_32_swap_64( from_format, from_os_size,
2035 				     from_format, to_os_size, data_type,
2036                                      delta_from_bytes, delta_to_bytes,
2037 				     from_data, temp_data, error_return );
2038          ADFI_big_little_endian_swap( from_format, to_os_size,
2039 				      to_format, to_os_size, data_type,
2040                                       delta_to_bytes, delta_to_bytes,
2041 			              temp_data, to_data, error_return );
2042          break ;
2043 
2044        case EVAL_4_BYTES( 'L', 'B', 'B', 'L' ):
2045        case EVAL_4_BYTES( 'L', 'B', 'L', 'B' ):
2046          ADFI_little_endian_32_swap_64( from_format, from_os_size,
2047 			  	        from_format, to_os_size, data_type,
2048                                         delta_from_bytes, delta_to_bytes,
2049 				        from_data, temp_data, error_return );
2050          ADFI_big_little_endian_swap( from_format, to_os_size,
2051 				      to_format, to_os_size, data_type,
2052                                       delta_to_bytes, delta_to_bytes,
2053 			              temp_data, to_data, error_return );
2054          break ;
2055 
2056        case EVAL_4_BYTES( 'B', 'L', 'L', 'L' ):
2057        case EVAL_4_BYTES( 'L', 'B', 'L', 'L' ):
2058        case EVAL_4_BYTES( 'B', 'L', 'B', 'B' ):
2059        case EVAL_4_BYTES( 'L', 'B', 'B', 'B' ):
2060          ADFI_big_little_endian_swap( from_format, from_os_size,
2061 				      to_format, to_os_size, data_type,
2062                                       delta_from_bytes, delta_to_bytes,
2063 			              from_data, to_data, error_return );
2064          break ;
2065 
2066        case EVAL_4_BYTES( 'C', 'L', 'B', 'L' ):
2067        case EVAL_4_BYTES( 'C', 'L', 'B', 'B' ):
2068          ADFI_cray_to_little_endian( from_format, from_os_size,
2069 				     to_format, to_os_size, data_type,
2070                                      delta_from_bytes, delta_to_bytes,
2071 				     from_data, to_data, error_return );
2072          break ;
2073 
2074        case EVAL_4_BYTES( 'L', 'C', 'L', 'B' ):
2075        case EVAL_4_BYTES( 'L', 'C', 'B', 'B' ):
2076          ADFI_little_endian_to_cray( from_format, from_os_size,
2077 				  to_format, to_os_size, data_type,
2078                                   delta_from_bytes, delta_to_bytes,
2079 				  from_data, to_data, error_return );
2080          break ;
2081 
2082        default:
2083          *error_return = MACHINE_FORMAT_NOT_RECOGNIZED ;
2084          return ;
2085       } /* end switch */
2086       if ( *error_return != NO_ERROR )
2087  	 return ;
2088          /** Increment the data pointers **/
2089        to_data   += delta_to_bytes ;
2090        from_data += delta_from_bytes ;
2091     } /* end for */
2092   } /* end while */
2093 } /* end for */
2094 
2095 }
2096 /* end of file ADFI_convert_number_format.c */
2097 /* file ADFI_count_total_array_points.c */
2098 /***********************************************************************
2099 ADFI count total array points:
2100 
2101 input:  const unsigned int ndim	The number of dimensions to use (1 to 12)
2102 input:  const unsigned int dims[]The dimensional space
2103 input:  const int dim_start[]	The starting dimension of our sub-space
2104 				first = 1
2105 input:  const int dim_end[]	The ending dimension of our sub-space
2106 				last[n] = dims[n]
2107 input:  const int dim_stride[]	The stride to take in our sub-space
2108 				(every Nth element)
2109 output: ulong *total_points	Total points defined in our sub-space.
2110 output: ulong *starting_offset	Number of elements skipped before first element
2111 output: int *error_return	Error return.
2112 
2113 possible errors:
2114 NO_ERROR
2115 NULL_POINTER
2116 BAD_NUMBER_OF_DIMENSIONS
2117 BAD_DIMENSION_VALUE
2118 START_OUT_OF_DEFINED_RANGE
2119 END_OUT_OF_DEFINED_RANGE
2120 BAD_STRIDE_VALUE
2121 MINIMUM_GT_MAXIMUM
2122 ***********************************************************************/
ADFI_count_total_array_points(const unsigned int ndim,const cgulong_t dims[],const cgsize_t dim_start[],const cgsize_t dim_end[],const cgsize_t dim_stride[],cgulong_t * total_points,cgulong_t * starting_offset,int * error_return)2123 void	ADFI_count_total_array_points(
2124 		const unsigned int ndim,
2125 		const cgulong_t dims[],
2126 		const cgsize_t dim_start[],
2127 		const cgsize_t dim_end[],
2128 		const cgsize_t dim_stride[],
2129 		cgulong_t *total_points,
2130 		cgulong_t *starting_offset,
2131 		int *error_return )
2132 {
2133 unsigned int		i ;
2134 cgulong_t total, offset ;
2135 cgulong_t accumlated_size ;
2136 
2137 if( (dims == NULL) || (dim_start == NULL) || (dim_end == NULL) ||
2138     (dim_stride == NULL) || (total_points == NULL) ||
2139     (starting_offset == NULL) ) {
2140    *error_return = NULL_POINTER ;
2141    return ;
2142    } /* end if */
2143 
2144 if( (ndim <= 0) || (ndim > 12) ) {
2145    *error_return = BAD_NUMBER_OF_DIMENSIONS ;
2146    return ;
2147    } /* end if */
2148 
2149 *error_return = NO_ERROR ;
2150 
2151 	/** Check the inputs **/
2152 for( i=0; i<ndim; i++ ) {
2153 
2154 	/** Check dims[] >=1 **/
2155    if( dims[i] < 1 ) {
2156       *error_return = BAD_DIMENSION_VALUE ;
2157       return ;
2158       } /* end if */
2159 
2160 	/** Check starting values >=1 and <= dims **/
2161    if( (dim_start[i] < 1) || ((cgulong_t)dim_start[i] > dims[i]) ) {
2162       *error_return = START_OUT_OF_DEFINED_RANGE ;
2163       return ;
2164       } /* end if */
2165 
2166 	/** Check ending values >=1 and <= dims and >= dim_start **/
2167    if( (dim_end[i] < 1) || ((cgulong_t)dim_end[i] > dims[i]) ) {
2168       *error_return = END_OUT_OF_DEFINED_RANGE ;
2169       return ;
2170       } /* end if */
2171    if( dim_end[i] < dim_start[i] ) {
2172       *error_return = MINIMUM_GT_MAXIMUM ;
2173       return ;
2174       } /* end if */
2175 
2176 	/** Check stride >= 1 **/
2177    if( dim_stride[i] < 1 ) {
2178       *error_return = BAD_STRIDE_VALUE ;
2179       return ;
2180       } /* end if */
2181    } /* end for */
2182 
2183 total = 1 ;
2184 offset = 0 ;
2185 accumlated_size = 1 ;
2186 for( i=0; i<ndim; i++ ) {
2187    total *= (dim_end[i] - dim_start[i] + dim_stride[i]) / dim_stride[i] ;
2188    offset += (dim_start[i] - 1) * accumlated_size ;
2189    accumlated_size *= dims[i] ;
2190    } /* end for */
2191 *total_points = total ;
2192 *starting_offset = offset ;
2193 } /* end of ADFI_count_total_array_points */
2194 /* end of file ADFI_count_total_array_points.c */
2195 /* file ADFI_cray_to_big_endian.c */
2196 /***********************************************************************
2197 ADFI cray to big endian:
2198 
2199 input:  const char from_format		Format to convert from. 'B','L','C','N'
2200 input:  const char from_os_size		Format to convert from. 'B','L'
2201 input:  const char to_format		Format to convert to.
2202 input:  const char to_os_size		Format to convert to. 'B','L'
2203 input:  const char data_type[2]		The type of data to convert.
2204 					   MT I4 I8 U4 U8 R4 R8 X4 X8 C1 B1
2205 input:  const unsigned long delta_from_bytes Number of from_bytes used.
2206 input:  const unsigned long delta_to_bytes	Number of to_bytes used.
2207 input:  const char *from_data		The data to convert from.
2208 output: char *to_data			The resulting data.
2209 output:	int *error_return		Error return.
2210 
2211   Recognized data types:
2212 					Machine representations
2213 	Type		     Notation	IEEE_BIG	IEEE_L	Cray
2214   No data                   MT
2215   Integer 32                I4         I4    I4    I4   I4       I8
2216   Integer 64                I8         --    I8    --   I8       I8
2217   Unsigned 32               U4         I4    I4    I4   I4       I8
2218   Unsigned 64               U8         --    I8    --   I8       I8
2219   Real 32                   R4         R4    R4    R4   R4       R8
2220   Real 64                   R8         R8    R8    R8   R8       R8
2221   Complex 64                X4         R4R4  R4R4  R4R4 R4R4     R8R8
2222   Complex 128               X8         R8R8  R8R8  R8R8 R8R8     R8R8
2223   Character (unsigned byte) C1         C1    C1    C1   C1       C1
2224   Byte (unsigned byte)      B1         C1    C1    C1   C1       C1
2225 
2226 Machine Numeric Formats:
2227 ***IEEE_BIG (SGI-Iris Assembly Language Programmer's Guide, pages 1-2, 6-3)
2228 I4:	Byte0	Byte1	Byte2	Byte3
2229 	 MSB---------------------LSB
2230 R4:	Byte0	Byte1	Byte2	Byte3
2231     Bits: sign-bit, 8-bit exponent, 23-bit mantissa
2232     The sign of the exponent is:  1=positive, 0=negative (NOT 2's complement)
2233     The interpretation of the floating-point number is:
2234 	>>> 2.mantissia(fraction) X 2^exponent. <<<
2235 
2236 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
2237     Bits: sign-bit, 11-bit exponent, 52-bit mantissa
2238 
2239 ***Cray (Cray CFT77 Reference Manual, pages G-1 G-2)
2240 I8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
2241 	 MSB-----------------------------------------------------LSB
2242 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
2243     Bits: sign-bit, exponent-sign, 14-bit exponent, 48-bit mantissa
2244 Note: Exponent sign:  1 in this bits indicates a positive exponent sign,
2245    thus bit 62 is the inverse of bit 61 (the sign in the exponent).
2246    The exception to this is a zero, in which all 64 bits are zero!
2247     The interpretation of the floating-point number is:
2248 	>>> .mantissia(fraction) X 2^exponent. <<<
2249    The mantissia is left justified (the leftmost bit is a 1).
2250      This MUST be done!
2251 
2252 ***
2253 
2254    Possible errors:
2255 NO_ERROR
2256 NULL_STRING_POINTER
2257 NULL_POINTER
2258 ***********************************************************************/
ADFI_cray_to_big_endian(const char from_format,const char from_os_size,const char to_format,const char to_os_size,const char data_type[2],const cgulong_t delta_from_bytes,const cgulong_t delta_to_bytes,const unsigned char * from_data,unsigned char * to_data,int * error_return)2259 void    ADFI_cray_to_big_endian(
2260 		const char from_format,
2261 		const char from_os_size,
2262 		const char to_format,
2263 		const char to_os_size,
2264 		const char data_type[2],
2265 		const cgulong_t delta_from_bytes,
2266 		const cgulong_t delta_to_bytes,
2267 		const unsigned char *from_data,
2268 		unsigned char *to_data,
2269                 int *error_return )
2270 {
2271 int		i, exp ;
2272 
2273 if( (from_data == NULL) || (to_data == NULL) ) {
2274    *error_return = NULL_STRING_POINTER ;
2275    return ;
2276    } /* end if */
2277 
2278 if( (delta_from_bytes == 0) || (delta_to_bytes == 0) ) {
2279    *error_return = NULL_POINTER ;
2280    return ;
2281    } /* end if */
2282 
2283 if( (from_format == 'N') || (to_format == 'N') ) {
2284    *error_return = CANNOT_CONVERT_NATIVE_FORMAT ;
2285    return ;
2286    } /* end if */
2287 
2288 *error_return = NO_ERROR ;
2289 
2290 switch( EVAL_2_BYTES( data_type[0], data_type[1] ) ) {
2291    case EVAL_2_BYTES( 'M', 'T' ):
2292       *error_return = NO_DATA ;
2293       return ;
2294 
2295    case EVAL_2_BYTES( 'C', '1' ):
2296    case EVAL_2_BYTES( 'B', '1' ):
2297       to_data[0] = from_data[0] ;
2298       break ;
2299 
2300    case EVAL_2_BYTES( 'I', '4' ):
2301    case EVAL_2_BYTES( 'U', '4' ):
2302       to_data[0] = from_data[4] ;
2303       to_data[1] = from_data[5] ;
2304       to_data[2] = from_data[6] ;
2305       to_data[3] = from_data[7] ;
2306       break ;
2307 
2308    case EVAL_2_BYTES( 'I', '8' ):
2309    case EVAL_2_BYTES( 'U', '8' ):
2310       for( i=0; i<(int) delta_to_bytes; i++ )
2311          to_data[i] = from_data[8-delta_to_bytes+i] ;
2312       break ;
2313 
2314    case EVAL_2_BYTES( 'R', '4' ):
2315       for( i=0; i<4; i++ )
2316          to_data[i] = 0x00 ;
2317 
2318    /** Check for zero: a special case on the Cray (exponent sign) **/
2319       if( (from_data[0] == 0x00) && (from_data[1] == 0x00) &&
2320           (from_data[2] == 0x00) && (from_data[3] == 0x00) &&
2321           (from_data[4] == 0x00) && (from_data[5] == 0x00) &&
2322           (from_data[6] == 0x00) && (from_data[7] == 0x00) )
2323          break ;
2324 
2325    /** Convert the sign **/
2326       to_data[0] = from_data[0] & 0x80 ;
2327 
2328    /** Convert the exponent **/
2329    /** 14 bits to 8 bits.  Sign extent from 8 to 14 **/
2330    /** Cray exponent is 2 greater than the Iris **/
2331       exp = from_data[1] + ((from_data[0]&0x3f)<<8) ;
2332       if( (from_data[0] & 0x40) == 0x00 ) /* set sign */
2333          exp -= 16384 ;
2334       exp -= 2 ;
2335 
2336       if( exp >= 128 ) {
2337           *error_return = NUMERIC_OVERFLOW ;
2338           return ;
2339         } /* end if */
2340       else if ( exp < -128 ) {
2341           for( i=0; i<4; i++ ) to_data[i] = 0x00 ; /* underflow set to 0 */
2342           break;
2343         } /* end else */
2344 
2345       to_data[0] |= ((exp&0x7F) >> 1) ;
2346       if( (exp & 0x01) == 0x01 )	/* LSBit of the exponent */
2347          to_data[1] |= 0x80 ;
2348 
2349       if( exp >= 0 )	/* Set exponent sign */
2350          to_data[0] |= 0x40 ;
2351 
2352    /** Convert the mantissia **/
2353    /** 48 bits to 23 bits, skip the first '1' (2.fract) **/
2354       to_data[1] |= (from_data[2] & 0x7f) ;
2355       to_data[2] = from_data[3] ;
2356       to_data[3] = from_data[4] ;
2357       break ;
2358 
2359    case EVAL_2_BYTES( 'R', '8' ):
2360       for( i=0; i<8; i++ )
2361          to_data[i] = 0x00 ;
2362 
2363    /** Check for zero: a special case on the Cray (exponent sign) **/
2364       if( (from_data[0] == 0x00) && (from_data[1] == 0x00) &&
2365           (from_data[2] == 0x00) && (from_data[3] == 0x00) )
2366          break ;
2367 
2368    /** Convert the sign **/
2369       to_data[0] = from_data[0] & 0x80 ;
2370 
2371    /** Convert the exponent **/
2372    /** 14 bits to  11 bits **/
2373    /** Cray exponent is 2 greater than the Iris **/
2374        exp = from_data[1] + ((from_data[0]&0x3f)<<8) ;
2375          /* set sign if exponent is non-zero */
2376        if( (exp != 0) && ((from_data[0] & 0x40) == 0x00) )
2377           exp -= 16384 ;
2378        exp -= 2 ;
2379 
2380        if( exp >= 1024 ) {
2381            *error_return = NUMERIC_OVERFLOW ;
2382            return ;
2383          } /* end if */
2384        else if ( exp < -1024 ) {
2385            for( i=0; i<4; i++ ) to_data[i] = 0x00 ; /* underflow set to 0 */
2386            break;
2387          } /* end else */
2388 
2389        to_data[0] |= ((exp & 0x03F0) >> 4) ;
2390        to_data[1] |= ((exp & 0x000F) << 4) ;
2391 
2392        if( exp >= 0 )   /* Set exponent sign */
2393           to_data[0] |= 0x40 ;
2394 
2395    /** Convert the mantissia **/
2396    /** 48 bits to 52 bits, skip the first '1' (2.fract) **/
2397        to_data[1] |= ((from_data[2] & 0x78) >> 3) ;
2398        for( i=2; i<7; i++ )
2399           to_data[i] = ((from_data[i] & 0x07) << 5) |
2400                        ((from_data[i+1] & 0xf8) >> 3) ;
2401        to_data[7] = ((from_data[7] & 0x07) << 5) ;
2402 
2403 #ifdef PRINT_STUFF
2404 printf("from:" ) ;
2405 for( i=0; i<8; i++ )
2406    printf("%02x ", from_data[i] ) ;
2407 printf("to:" ) ;
2408 for( i=0; i<8; i++ )
2409    printf("%02x ", to_data[i] ) ;
2410 printf("\n" ) ;
2411 #endif
2412        break ;
2413 
2414    case EVAL_2_BYTES( 'X', '4' ):
2415       ADFI_cray_to_big_endian( from_format, from_os_size,
2416 	 to_format, to_os_size, "R4", delta_from_bytes,
2417 	 delta_to_bytes, from_data, to_data, error_return ) ;
2418       if( *error_return != NO_ERROR )
2419          return ;
2420 
2421       ADFI_cray_to_big_endian( from_format, from_os_size,
2422 	 to_format, to_os_size, "R4", delta_from_bytes,
2423 	 delta_to_bytes, &from_data[8], &to_data[4], error_return ) ;
2424       if( *error_return != NO_ERROR )
2425          return ;
2426       break ;
2427 
2428    case EVAL_2_BYTES( 'X', '8' ):
2429       ADFI_cray_to_big_endian( from_format, from_os_size,
2430 	 to_format, to_os_size, "R8", delta_from_bytes,
2431 	 delta_to_bytes, from_data, to_data, error_return ) ;
2432       if( *error_return != NO_ERROR )
2433          return ;
2434 
2435       ADFI_cray_to_big_endian( from_format, from_os_size,
2436 	 to_format, to_os_size, "R8", delta_from_bytes,
2437 	 delta_to_bytes, &from_data[8], &to_data[8], error_return ) ;
2438       if( *error_return != NO_ERROR )
2439          return ;
2440       break ;
2441 
2442    default:
2443       *error_return = INVALID_DATA_TYPE ;
2444       return ;
2445 
2446    } /* end switch */
2447 } /* end of ADFI_cray_to_big_endian */
2448 /* end of file ADFI_cray_to_big_endian.c */
2449 /* file ADFI_cray_to_little_endian.c */
2450 /***********************************************************************
2451 ADFI cray to little endian:
2452 
2453 input:  const char from_format		Format to convert from. 'B','L','C','N'
2454 input:  const char from_os_size		Format to convert from. 'B','L'
2455 input:  const char to_format		Format to convert to.
2456 input:  const char to_os_size		Format to convert to. 'B','L'
2457 input:  const char data_type[2]		The type of data to convert.
2458 					   MT I4 I8 U4 U8 R4 R8 X4 X8 C1 B1
2459 input:  const unsigned long delta_from_bytes Number of from_bytes used.
2460 input:  const unsigned long delta_to_bytes	Number of to_bytes used.
2461 input:  const char *from_data		The data to convert from.
2462 output: char *to_data			The resulting data.
2463 output:	int *error_return		Error return.
2464 
2465   Recognized data types:
2466 					Machine representations
2467 	Type		     Notation	IEEE_BIG	IEEE_L	Cray
2468   No data                   MT
2469   Integer 32                I4         I4    I4    I4   I4       I8
2470   Integer 64                I8         --    I8    --   I8       I8
2471   Unsigned 32               U4         I4    I4    I4   I4       I8
2472   Unsigned 64               U8         --    I8    --   I8       I8
2473   Real 32                   R4         R4    R4    R4   R4       R8
2474   Real 64                   R8         R8    R8    R8   R8       R8
2475   Complex 64                X4         R4R4  R4R4  R4R4 R4R4     R8R8
2476   Complex 128               X8         R8R8  R8R8  R8R8 R8R8     R8R8
2477   Character (unsigned byte) C1         C1    C1    C1   C1       C1
2478   Byte (unsigned byte)      B1         C1    C1    C1   C1       C1
2479 
2480 Machine Numeric Formats:
2481 ***IEEE_BIG (SGI-Iris Assembly Language Programmer's Guide, pages 1-2, 6-3)
2482 I4:	Byte0	Byte1	Byte2	Byte3
2483 	 MSB---------------------LSB
2484 R4:	Byte0	Byte1	Byte2	Byte3
2485     Bits: sign-bit, 8-bit exponent, 23-bit mantissa
2486     The sign of the exponent is:  1=positive, 0=negative (NOT 2's complement)
2487     The interpretation of the floating-point number is:
2488 	>>> 2.mantissia(fraction) X 2^exponent. <<<
2489 
2490 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
2491     Bits: sign-bit, 11-bit exponent, 52-bit mantissa
2492 
2493 ***Cray (Cray CFT77 Reference Manual, pages G-1 G-2)
2494 I8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
2495 	 MSB-----------------------------------------------------LSB
2496 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
2497     Bits: sign-bit, exponent-sign, 14-bit exponent, 48-bit mantissa
2498 Note: Exponent sign:  1 in this bits indicates a positive exponent sign,
2499    thus bit 62 is the inverse of bit 61 (the sign in the exponent).
2500    The exception to this is a zero, in which all 64 bits are zero!
2501     The interpretation of the floating-point number is:
2502 	>>> .mantissia(fraction) X 2^exponent. <<<
2503    The mantissia is left justified (the leftmost bit is a 1).
2504      This MUST be done!
2505 
2506 ***
2507 
2508    Possible errors:
2509 NO_ERROR
2510 NULL_STRING_POINTER
2511 NULL_POINTER
2512 ***********************************************************************/
ADFI_cray_to_little_endian(const char from_format,const char from_os_size,const char to_format,const char to_os_size,const char data_type[2],const cgulong_t delta_from_bytes,const cgulong_t delta_to_bytes,const unsigned char * from_data,unsigned char * to_data,int * error_return)2513 void    ADFI_cray_to_little_endian(
2514 		const char from_format,
2515 		const char from_os_size,
2516 		const char to_format,
2517 		const char to_os_size,
2518 		const char data_type[2],
2519 		const cgulong_t delta_from_bytes,
2520 		const cgulong_t delta_to_bytes,
2521 		const unsigned char *from_data,
2522 		unsigned char *to_data,
2523                 int *error_return )
2524 {
2525 int		i, exp ;
2526 
2527 if( (from_data == NULL) || (to_data == NULL) ) {
2528    *error_return = NULL_STRING_POINTER ;
2529    return ;
2530    } /* end if */
2531 
2532 if( (delta_from_bytes == 0) || (delta_to_bytes == 0) ) {
2533    *error_return = NULL_POINTER ;
2534    return ;
2535    } /* end if */
2536 
2537 if( (from_format == 'N') || (to_format == 'N') ) {
2538    *error_return = CANNOT_CONVERT_NATIVE_FORMAT ;
2539    return ;
2540    } /* end if */
2541 
2542 *error_return = NO_ERROR ;
2543 
2544 switch( EVAL_2_BYTES( data_type[0], data_type[1] ) ) {
2545    case EVAL_2_BYTES( 'M', 'T' ):
2546       *error_return = NO_DATA ;
2547       return ;
2548 
2549    case EVAL_2_BYTES( 'C', '1' ):
2550    case EVAL_2_BYTES( 'B', '1' ):
2551       to_data[0] = from_data[0] ;
2552       break ;
2553 
2554    case EVAL_2_BYTES( 'I', '4' ):
2555    case EVAL_2_BYTES( 'U', '4' ):
2556       to_data[3] = from_data[4] ;
2557       to_data[2] = from_data[5] ;
2558       to_data[1] = from_data[6] ;
2559       to_data[0] = from_data[7] ;
2560       break ;
2561 
2562    case EVAL_2_BYTES( 'I', '8' ):
2563    case EVAL_2_BYTES( 'U', '8' ):
2564       for( i=0; i<(int) delta_to_bytes; i++ )
2565          to_data[delta_to_bytes-1-i] = from_data[8-delta_to_bytes+i] ;
2566       break ;
2567 
2568    case EVAL_2_BYTES( 'R', '4' ):
2569       for( i=0; i<4; i++ )
2570          to_data[i] = 0x00 ;
2571 
2572    /** Check for zero: a special case on the Cray (exponent sign) **/
2573       if( (from_data[0] == 0x00) && (from_data[1] == 0x00) &&
2574           (from_data[2] == 0x00) && (from_data[3] == 0x00) &&
2575           (from_data[4] == 0x00) && (from_data[5] == 0x00) &&
2576           (from_data[6] == 0x00) && (from_data[7] == 0x00) )
2577          break ;
2578 
2579    /** Convert the sign **/
2580       to_data[3] = from_data[0] & 0x80 ;
2581 
2582    /** Convert the exponent **/
2583    /** 14 bits to 8 bits.  Sign extent from 8 to 14 **/
2584    /** Cray exponent is 2 greater than the Iris **/
2585       exp = from_data[1] + ((from_data[0]&0x3f)<<8) ;
2586       if( (from_data[0] & 0x40) == 0x00 ) /* set sign */
2587          exp -= 16384 ;
2588       exp -= 2 ;
2589 
2590       if( exp >= 128 ) {
2591           *error_return = NUMERIC_OVERFLOW ;
2592           return ;
2593         } /* end if */
2594       else if ( exp < -128 ) {
2595           for( i=0; i<4; i++ ) to_data[i] = 0x00 ; /* underflow set to 0 */
2596           break;
2597         } /* end else */
2598 
2599       to_data[3] |= ((exp&0x7F) >> 1) ;
2600       if( (exp & 0x01) == 0x01 )	/* LSBit of the exponent */
2601          to_data[2] |= 0x80 ;
2602 
2603       if( exp >= 0 )	/* Set exponent sign */
2604          to_data[3] |= 0x40 ;
2605 
2606    /** Convert the mantissia **/
2607    /** 48 bits to 23 bits, skip the first '1' (2.fract) **/
2608       to_data[2] |= (from_data[2] & 0x7f) ;
2609       to_data[1] = from_data[3] ;
2610       to_data[0] = from_data[4] ;
2611       break ;
2612 
2613    case EVAL_2_BYTES( 'R', '8' ):
2614       for( i=0; i<8; i++ )
2615          to_data[i] = 0x00 ;
2616 
2617    /** Check for zero: a special case on the Cray (exponent sign) **/
2618       if( (from_data[0] == 0x00) && (from_data[1] == 0x00) &&
2619           (from_data[2] == 0x00) && (from_data[3] == 0x00) )
2620          break ;
2621 
2622    /** Convert the sign **/
2623       to_data[7] = from_data[0] & 0x80 ;
2624 
2625    /** Convert the exponent **/
2626    /** 14 bits to  11 bits **/
2627    /** Cray exponent is 2 greater than the Iris **/
2628        exp = from_data[1] + ((from_data[0]&0x3f)<<8) ;
2629          /* set sign if exponent is non-zero */
2630        if( (exp != 0) && ((from_data[0] & 0x40) == 0x00) )
2631           exp -= 16384 ;
2632        exp -= 2 ;
2633 
2634        if( exp >= 1024 ) {
2635            *error_return = NUMERIC_OVERFLOW ;
2636            return ;
2637          } /* end if */
2638        else if ( exp < -1024 ) {
2639            for( i=0; i<4; i++ ) to_data[i] = 0x00 ; /* underflow set to 0 */
2640            break;
2641          } /* end else */
2642 
2643        to_data[7] |= ((exp & 0x03F0) >> 4) ;
2644        to_data[6] |= ((exp & 0x000F) << 4) ;
2645 
2646        if( exp >= 0 )   /* Set exponent sign */
2647           to_data[7] |= 0x40 ;
2648 
2649    /** Convert the mantissia **/
2650    /** 48 bits to 52 bits, skip the first '1' (2.fract) **/
2651        to_data[6] |= ((from_data[2] & 0x78) >> 3) ;
2652        for( i=2; i<7; i++ )
2653           to_data[7-i] = ((from_data[i] & 0x07) << 5) |
2654                          ((from_data[i+1] & 0xf8) >> 3) ;
2655        to_data[0] = ((from_data[7] & 0x07) << 5) ;
2656 
2657 #ifdef PRINT_STUFF
2658 printf("from:" ) ;
2659 for( i=0; i<8; i++ )
2660    printf("%02x ", from_data[i] ) ;
2661 printf("to:" ) ;
2662 for( i=0; i<8; i++ )
2663    printf("%02x ", to_data[i] ) ;
2664 printf("\n" ) ;
2665 #endif
2666        break ;
2667 
2668    case EVAL_2_BYTES( 'X', '4' ):
2669       ADFI_cray_to_little_endian( from_format, from_os_size,
2670 	 to_format, to_os_size, "R4", delta_from_bytes,
2671 	 delta_to_bytes, from_data, to_data, error_return ) ;
2672       if( *error_return != NO_ERROR )
2673          return ;
2674 
2675       ADFI_cray_to_little_endian( from_format, from_os_size,
2676 	 to_format, to_os_size, "R4", delta_from_bytes,
2677 	 delta_to_bytes, &from_data[8], &to_data[4], error_return ) ;
2678       if( *error_return != NO_ERROR )
2679          return ;
2680       break ;
2681 
2682    case EVAL_2_BYTES( 'X', '8' ):
2683       ADFI_cray_to_little_endian( from_format, from_os_size,
2684 	 to_format, to_os_size, "R8", delta_from_bytes,
2685 	 delta_to_bytes, from_data, to_data, error_return ) ;
2686       if( *error_return != NO_ERROR )
2687          return ;
2688 
2689       ADFI_cray_to_little_endian( from_format, from_os_size,
2690 	 to_format, to_os_size, "R8", delta_from_bytes,
2691 	 delta_to_bytes, &from_data[8], &to_data[8], error_return ) ;
2692       if( *error_return != NO_ERROR )
2693          return ;
2694       break ;
2695 
2696    default:
2697       *error_return = INVALID_DATA_TYPE ;
2698       return ;
2699 
2700    } /* end switch */
2701 } /* end of ADFI_cray_to_little_endian */
2702 /* end of file ADFI_cray_to_little_endian.c */
2703 /* file ADFI_delete_data.c */
2704 /***********************************************************************
2705 ADFI delete data:
2706 
2707 Deletes all data from the file for a node.
2708 
2709 input:  const int  file_index      The file index.
2710 input:  const struct NODE_HEADER   Node header information.
2711 output: int *error_return          Error return.
2712 ***********************************************************************/
ADFI_delete_data(const int file_index,const struct NODE_HEADER * node_header,int * error_return)2713 void    ADFI_delete_data(
2714         const int file_index,
2715         const struct NODE_HEADER  *node_header,
2716         int *error_return )
2717 {
2718 struct  DATA_CHUNK_TABLE_ENTRY	*data_chunk_table ;
2719 int     i ;
2720 
2721 *error_return = NO_ERROR ;
2722 
2723 if( node_header == NULL ) {
2724    *error_return = NULL_POINTER ;
2725    return ;
2726    } /* end if */
2727 
2728 if( file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
2729    *error_return = ADF_FILE_NOT_OPENED ;
2730    return ;
2731    } /* end if */
2732 
2733 switch( node_header->number_of_data_chunks ) {
2734 case 0 :    /** No data to free, do nothing **/
2735    return ;
2736 
2737 case 1 : /** A single data-chunk to free, so free it **/
2738    ADFI_file_free( file_index, &node_header->data_chunks, 0, error_return ) ;
2739    if( *error_return != NO_ERROR )
2740       return ;
2741    break ;
2742 
2743 default : /** Multiple data-chunks to free.  Free them,
2744               and also the data_chunk table **/
2745           /** Allocate memory for the required table space in memory **/
2746    data_chunk_table = (struct  DATA_CHUNK_TABLE_ENTRY *)
2747        malloc( node_header->number_of_data_chunks * sizeof( *data_chunk_table ) ) ;
2748    if( data_chunk_table == NULL ) {
2749       *error_return = MEMORY_ALLOCATION_FAILED ;
2750       return ;
2751    } /* end if */
2752 
2753     /** Read in the table **/
2754    ADFI_read_data_chunk_table( file_index, &node_header->data_chunks,
2755                                data_chunk_table, error_return ) ;
2756    if( *error_return != NO_ERROR )
2757       return ;
2758 
2759     /** Free each entry in the table **/
2760    for( i=0; i<(int)node_header->number_of_data_chunks; i++ ) {
2761       ADFI_file_free( file_index, &data_chunk_table[i].start,
2762                       0, error_return ) ;
2763       if( *error_return != NO_ERROR )
2764          return ;
2765       } /* end for */
2766    free( data_chunk_table ) ;
2767    ADFI_file_free( file_index, &node_header->data_chunks, 0, error_return ) ;
2768    if( *error_return != NO_ERROR )
2769       return ;
2770    break ;
2771    }/* end switch */
2772 
2773 /** Clear all disk entries off the priority stack for file **/
2774 ADFI_stack_control(file_index, 0, 0, CLEAR_STK_TYPE, DISK_PTR_STK,
2775 		   0, NULL ) ;
2776 
2777 } /* end of ADFI_delete_data */
2778 /* end of file ADFI_delete_data.c */
2779 /* file ADFI_delete_from_sub_node_table.c */
2780 /***********************************************************************
2781 ADFI delete from sub node table:
2782 	Delete a child from a parent's sub-node table.
2783 
2784 input:  const int file_index	Index of ADF file.
2785 input:  const struct DISK_POINTER *parent Location of the parent
2786 input:  const struct DISK_POINTER *child Location of the child.
2787 output:	int *error_return		Error return.
2788 
2789    Possible errors:
2790 NO_ERROR
2791 NULL_POINTER
2792 ADF_FILE_NOT_OPENED
2793 ***********************************************************************/
ADFI_delete_from_sub_node_table(const int file_index,const struct DISK_POINTER * parent,const struct DISK_POINTER * child,int * error_return)2794 void    ADFI_delete_from_sub_node_table(
2795 		const int file_index,
2796 		const struct DISK_POINTER *parent,
2797 		const struct DISK_POINTER *child,
2798 		int *error_return )
2799 {
2800 
2801 int i, found ;
2802 struct NODE_HEADER  parent_node ;
2803 struct SUB_NODE_TABLE_ENTRY  *sub_node_table ;
2804 
2805 if( (parent == NULL) || (child == NULL) ) {
2806    *error_return = NULL_POINTER ;
2807    return ;
2808    } /* end if */
2809 
2810 if( file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
2811    *error_return = ADF_FILE_NOT_OPENED ;
2812    return ;
2813    } /* end if */
2814 
2815 *error_return = NO_ERROR ;
2816 
2817 ADFI_read_node_header( file_index, parent, &parent_node, error_return ) ;
2818 if( *error_return != NO_ERROR )
2819    return ;
2820 
2821 sub_node_table = (struct SUB_NODE_TABLE_ENTRY *)
2822                   malloc( parent_node.entries_for_sub_nodes *
2823                           sizeof( struct SUB_NODE_TABLE_ENTRY ) ) ;
2824 if( sub_node_table == NULL ) {
2825    *error_return = MEMORY_ALLOCATION_FAILED ;
2826    return ;
2827    } /* end if */
2828 
2829 ADFI_read_sub_node_table( file_index, &parent_node.sub_node_table,
2830                           sub_node_table, error_return ) ;
2831 if( *error_return != NO_ERROR )
2832    return ;
2833 
2834     /** Find the child in the parent's sub-node table **/
2835 for( i=0, found = -1 ; i<(int)parent_node.num_sub_nodes ; i++ ) {
2836    if( child->block  == sub_node_table[i].child_location.block  &&
2837        child->offset == sub_node_table[i].child_location.offset ) {
2838       found = i ;
2839       break ;
2840    } /* end if */
2841 } /* end for */
2842 
2843 if( found == -1 ) {
2844    *error_return = SUB_NODE_TABLE_ENTRIES_BAD ;
2845    free(sub_node_table);
2846    return ;
2847 }
2848 
2849     /** Move the rest of the table up to fill the hole **/
2850 for( i=found ; i<(int) (parent_node.num_sub_nodes-1) ; i++ ) {
2851    sub_node_table[i].child_location.block =
2852                                 sub_node_table[i+1].child_location.block ;
2853    sub_node_table[i].child_location.offset =
2854                                 sub_node_table[i+1].child_location.offset ;
2855    strncpy ( sub_node_table[i].child_name, sub_node_table[i+1].child_name,
2856              ADF_NAME_LENGTH ) ;
2857    } /* end for */
2858 
2859 i = parent_node.num_sub_nodes - 1 ;
2860 sub_node_table[i].child_location.block = 0 ;
2861 sub_node_table[i].child_location.offset = 0 ;
2862 strncpy ( sub_node_table[i].child_name,
2863           "unused entry in sub-node-table     ", ADF_NAME_LENGTH ) ;
2864 
2865     /** Re-write the parent's sub-node table **/
2866 
2867 ADFI_write_sub_node_table( file_index, &parent_node.sub_node_table,
2868                            parent_node.entries_for_sub_nodes,
2869                            sub_node_table, error_return ) ;
2870 if( *error_return != NO_ERROR )
2871    return ;
2872 
2873     /** Update the sub-node count and write the parent's node-header **/
2874 parent_node.num_sub_nodes -= 1;
2875 ADFI_write_node_header( file_index, parent, &parent_node, error_return ) ;
2876 if( *error_return != NO_ERROR )
2877    return ;
2878 
2879 /** Clear all subnode/disk entries off the priority stack for file **/
2880 ADFI_stack_control(file_index, 0, 0, CLEAR_STK_TYPE, SUBNODE_STK,
2881 		   0, NULL ) ;
2882 ADFI_stack_control(file_index, 0, 0, CLEAR_STK_TYPE, DISK_PTR_STK,
2883 		   0, NULL ) ;
2884 
2885 free(sub_node_table);
2886 
2887 } /* end of ADFI_delete_from_sub_node_table */
2888 /* end of file ADFI_delete_from_sub_node_table.c */
2889 /* file ADFI_delete_sub_node_table.c */
2890 /***********************************************************************
2891 ADFI delete sub node table:
2892     Deletes a sub-node table from the file.
2893 
2894 input:  const int file_index                      Index of ADF file.
2895 input:  const struct DISK_POINTER  *block_offset  The block & offset of
2896                                                   the sub node table.
2897 input:  const unsigned int size_sub_node_table    Current size of the sub
2898                   node table (usually node_header.entries_for_sub_nodes).
2899                   If zero, then no action performed.
2900 output:	int *error_return                         Error return.
2901 
2902    Possible errors:
2903 NO_ERROR
2904 NULL_POINTER
2905 ADF_FILE_NOT_OPENED
2906 FREE_OF_ROOT_NODE
2907 ADF_DISK_TAG_ERROR
2908 FREE_OF_FREE_CHUNK_TABLE
2909 ***********************************************************************/
ADFI_delete_sub_node_table(const int file_index,const struct DISK_POINTER * block_offset,const unsigned int size_sub_node_table,int * error_return)2910 void    ADFI_delete_sub_node_table(
2911         const int  file_index,
2912         const struct DISK_POINTER  *block_offset,
2913         const unsigned int  size_sub_node_table,
2914         int *error_return )
2915 {
2916 unsigned int  num_bytes ;
2917 
2918 
2919 *error_return = NO_ERROR ;
2920 
2921 if( block_offset == NULL ) {
2922    *error_return = NULL_POINTER ;
2923    return ;
2924    } /* end if */
2925 
2926 if( file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
2927    *error_return = ADF_FILE_NOT_OPENED ;
2928    return ;
2929    } /* end if */
2930 
2931 if( size_sub_node_table == 0 )
2932    return ; /* assume nothing to delete */
2933 
2934 /* calculate size */
2935 num_bytes = TAG_SIZE + TAG_SIZE + DISK_POINTER_SIZE +
2936    size_sub_node_table * (ADF_NAME_LENGTH + DISK_POINTER_SIZE);
2937 
2938 ADFI_file_free( file_index, block_offset, num_bytes, error_return ) ;
2939 if( *error_return != NO_ERROR )
2940    return ;
2941 
2942 /** Clear all subnode/disk entries off the priority stack for file **/
2943 ADFI_stack_control(file_index, 0, 0, CLEAR_STK_TYPE, SUBNODE_STK,
2944 		   0, NULL ) ;
2945 ADFI_stack_control(file_index, 0, 0, CLEAR_STK_TYPE, DISK_PTR_STK,
2946 		   0, NULL ) ;
2947 
2948 } /* end of ADFI_delete_sub_node_table */
2949 /* end of file ADFI_delete_sub_node_table.c */
2950 /* file ADFI_disk_pointer_2_ASCII_Hex.c */
2951 /***********************************************************************
2952 ADFI disk pointer to ASCII Hex:
2953 	Convert a disk pointer into an ASCII-Hex representation (for disk).
2954 
2955 input:  const struct DISK_POINTER *block_offset	Disk-pointer struct.
2956 output: char block[8]		ASCII block number.
2957 output: char offset[4]		ASCII offset number.
2958 output: int *error_return		Error return.
2959 
2960    Possible errors:
2961 NO_ERROR
2962 NULL_POINTER
2963 NULL_STRING_POINTER
2964 ***********************************************************************/
ADFI_disk_pointer_2_ASCII_Hex(const struct DISK_POINTER * block_offset,char block[8],char offset[4],int * error_return)2965 void    ADFI_disk_pointer_2_ASCII_Hex(
2966 		const struct DISK_POINTER *block_offset,
2967 		char block[8],
2968 		char offset[4],
2969 		int *error_return )
2970 {
2971 
2972 if( block_offset == NULL ) {
2973    *error_return = NULL_POINTER ;
2974    return ;
2975    } /* end if */
2976 
2977 if( (block == NULL) || (offset == NULL) ) {
2978    *error_return = NULL_STRING_POINTER ;
2979    return ;
2980    } /* end if */
2981 
2982 *error_return = NO_ERROR ;
2983 
2984 	/** Convert into ASCII-Hex form **/
2985 ADFI_unsigned_int_2_ASCII_Hex( (unsigned int)block_offset->block, 0, MAXIMUM_32_BITS,
2986 		8, block, error_return ) ;
2987 if( *error_return != NO_ERROR )
2988    return ;
2989 
2990 ADFI_unsigned_int_2_ASCII_Hex( (unsigned int)block_offset->offset, 0, DISK_BLOCK_SIZE,
2991 		4, offset, error_return ) ;
2992 if( *error_return != NO_ERROR )
2993    return ;
2994 
2995 } /* end of ADFI_disk_pointer_2_ASCII_Hex */
2996 /* end of file ADFI_disk_pointer_2_ASCII_Hex.c */
2997 /* file ADFI_disk_pointer_from_ASCII_Hex.c */
2998 /***********************************************************************
2999 ADFI disk pointer from ASCII Hex:
3000 	Convert an ASCII-Hex representation into a disk-pointer (for memory).
3001 
3002 input:  const char block[8]		ASCII block number.
3003 input:  const char offset[4]		ASCII offset number.
3004 output: struct DISK_POINTER *block_offset	Disk-pointer struct.
3005 output: int *error_return		Error return.
3006 
3007    Possible errors:
3008 NO_ERROR
3009 NULL_POINTER
3010 NULL_STRING_POINTER
3011 ***********************************************************************/
ADFI_disk_pointer_from_ASCII_Hex(const char block[8],const char offset[4],struct DISK_POINTER * block_offset,int * error_return)3012 void    ADFI_disk_pointer_from_ASCII_Hex(
3013 		const char block[8],
3014 		const char offset[4],
3015 		struct DISK_POINTER *block_offset,
3016 		int *error_return )
3017 {
3018 unsigned int	tmp ;
3019 
3020 if( (block == NULL) || (offset == NULL) ) {
3021    *error_return = NULL_STRING_POINTER ;
3022    return ;
3023    } /* end if */
3024 
3025 if( block_offset == NULL ) {
3026    *error_return = NULL_POINTER ;
3027    return ;
3028    } /* end if */
3029 
3030 *error_return = NO_ERROR ;
3031 
3032 	/** Convert into numeric form **/
3033 ADFI_ASCII_Hex_2_unsigned_int( 0, MAXIMUM_32_BITS, 8, block,
3034 		&tmp, error_return ) ;
3035 if( *error_return != NO_ERROR )
3036    return ;
3037 block_offset->block = tmp ;
3038 
3039 ADFI_ASCII_Hex_2_unsigned_int( 0, DISK_BLOCK_SIZE, 4, offset,
3040 		&tmp, error_return ) ;
3041 if( *error_return != NO_ERROR )
3042    return ;
3043 
3044 block_offset->offset = tmp ;
3045 } /* end of ADFI_disk_pointer_from_ASCII_Hex */
3046 /* end of file ADFI_disk_pointer_from_ASCII_Hex.c */
3047 /*----------------------------------------------------------------------------------*/
ADFI_write_disk_pointer(const unsigned int file_index,const struct DISK_POINTER * block_offset,char block[8],char offset[4],int * error_return)3048 void ADFI_write_disk_pointer(
3049 		const unsigned int file_index,
3050 		const struct DISK_POINTER *block_offset,
3051 		char block[8],
3052 		char offset[4],
3053 		int *error_return)
3054 {
3055     if (ADF_file[file_index].old_version) {
3056         ADFI_disk_pointer_2_ASCII_Hex(block_offset, block, offset, error_return);
3057     }
3058     else {
3059 	unsigned int boff = (unsigned int)block_offset->offset;
3060         ADFI_convert_integers(8, 1, ADF_this_machine_format, ADF_file[file_index].format,
3061 	   (char *)&block_offset->block, block, error_return);
3062 	if (*error_return != NO_ERROR) return;
3063         ADFI_convert_integers(4, 1, ADF_this_machine_format, ADF_file[file_index].format,
3064 	   (char *)&boff, offset, error_return);
3065     }
3066 }
3067 /*----------------------------------------------------------------------------------*/
ADFI_read_disk_pointer(const unsigned int file_index,const char block[8],const char offset[4],struct DISK_POINTER * block_offset,int * error_return)3068 void ADFI_read_disk_pointer(
3069 		const unsigned int file_index,
3070 		const char block[8],
3071 		const char offset[4],
3072 		struct DISK_POINTER *block_offset,
3073 		int *error_return )
3074 {
3075     if (ADF_file[file_index].old_version) {
3076         ADFI_disk_pointer_from_ASCII_Hex(block, offset, block_offset, error_return);
3077     }
3078     else {
3079 	unsigned int boff;
3080         ADFI_convert_integers(8, 1, ADF_file[file_index].format, ADF_this_machine_format,
3081 	   block, (char *)&block_offset->block, error_return);
3082 	if (*error_return != NO_ERROR) return;
3083         ADFI_convert_integers(4, 1, ADF_file[file_index].format, ADF_this_machine_format,
3084 	   offset, (char *)&boff, error_return);
3085 	block_offset->offset = boff;
3086     }
3087 }
3088 /*----------------------------------------------------------------------------------*/
3089 /* file ADFI_evaluate_datatype.c */
3090 /***********************************************************************
3091 ADFI evaluate datatype:
3092 
3093 input:  const int file_index	The file index (0 to MAXIMUM_FILES).
3094 input:  const char *data_type.	Data-type string.
3095 output: int *file_bytes.	Number of bytes used by the data type.
3096 output: int *machine_ bytes.	Number of bytes used by the data type.
3097 output: struct TOKENIZED_DATA_TYPE *tokenized_data_type Array.
3098 output: char *file_format	The format of this file.
3099 output: char *machine_format	The format of this machine.
3100 output: int error_return.	Error return.
3101 
3102   Recognized data types:
3103 	Type				Notation
3104 	No data				MT
3105 	Integer 32			I4
3106 	Integer 64			I8
3107 	Unsigned 32			U4
3108 	Unsigned 64			U8
3109 	Real 32				R4
3110 	Real 64				R8
3111 	Complex 64			X4
3112 	Complex 128			X8
3113 	Character (unsigned byte)	C1
3114 	Link (same as C1)       	LK
3115 	Byte (unsigned byte)		B1
3116    A structure is represented as the string "I4,I4,R8".
3117    An array of 25 integers is "I4[25]".
3118 
3119    Possible errors:
3120 NO_ERROR
3121 NULL_POINTER
3122 NULL_STRING_POINTER
3123 DATA_TYPE_TOO_LONG
3124 INVALID_DATA_TYPE
3125 ***********************************************************************/
ADFI_evaluate_datatype(const int file_index,const char data_type[],int * file_bytes,int * machine_bytes,struct TOKENIZED_DATA_TYPE * tokenized_data_type,char * file_format,char * machine_format,int * error_return)3126 void	ADFI_evaluate_datatype(
3127 		const int file_index,
3128 		const char data_type[],
3129 		int *file_bytes,
3130 		int *machine_bytes,
3131 		struct TOKENIZED_DATA_TYPE *tokenized_data_type,
3132 		char *file_format,
3133 		char *machine_format,
3134 		int *error_return )
3135 {
3136 int	str_position = 0 ;
3137 int	current_token = 0 ;
3138 int	i, str_len, size_file, size_machine ;
3139 char	data_type_string[ADF_DATA_TYPE_LENGTH + 1 ] ;
3140 struct	FILE_HEADER	file_header ;
3141 
3142 if( (file_format == NULL) || (machine_format == NULL) ) {
3143    *error_return = NULL_STRING_POINTER ;
3144    return ;
3145    } /* end if */
3146 
3147 if( (file_bytes == NULL) || (machine_bytes == NULL) ) {
3148    *error_return = NULL_POINTER ;
3149    return ;
3150    } /* end if */
3151 
3152 *file_bytes = 0 ;
3153 *machine_bytes = 0 ;
3154 *error_return = NO_ERROR ;
3155 
3156 	/** Return the file & machine's format info **/
3157 if( file_index >= maximum_files ) {
3158    *error_return = FILE_INDEX_OUT_OF_RANGE ;
3159    return ;
3160    } /* end if */
3161 *file_format = ADF_file[file_index].format ;
3162 *machine_format = ADF_this_machine_format ;
3163 
3164 	/** Convert blank-filled datatype into C string **/
3165 ADFI_string_2_C_string( data_type, ADF_DATA_TYPE_LENGTH, data_type_string,
3166 	error_return ) ;
3167 if( *error_return != NO_ERROR )
3168    return ;
3169 
3170 	/** Upper_CASE the data-type string **/
3171 str_len = (int)strlen( data_type_string ) ;
3172 if ( str_len == 0 ) {
3173   *error_return = STRING_LENGTH_ZERO ;
3174   return ;
3175 } /** end if **/
3176 for( i=0; i<str_len; i++ )
3177    data_type_string[i] = TO_UPPER( data_type_string[i] ) ;
3178 
3179 	/** Get file_header for the file variable sizes **/
3180 ADFI_read_file_header( file_index, &file_header, error_return ) ;
3181 if( *error_return != NO_ERROR )
3182    return ;
3183 
3184 	/** Loop to calculate the compound data-type length and validity **/
3185 while( data_type_string[ str_position ] != '\0' ) {
3186    size_file = 0 ;
3187    size_machine = 0 ;
3188 
3189 	/** Look at the 2-byte datatype code **/
3190    switch( EVAL_2_BYTES( data_type_string[str_position],
3191 			 data_type_string[str_position+1])) {
3192       case EVAL_2_BYTES( 'M', 'T' ) :
3193          tokenized_data_type[ current_token ].type[0] = 'M' ;
3194          tokenized_data_type[ current_token ].type[1] = 'T' ;
3195 	 if( (str_position == 0) && (data_type_string[ 2 ] == '\0') )
3196 	    return ;
3197 	 else {	/* ERROR, cannot have 'MT' with any other definition */
3198 	    *error_return = INVALID_DATA_TYPE ;
3199 	    return ;
3200 	    } /* end else */
3201 
3202       case EVAL_2_BYTES( 'I', '4' ) :
3203 	 size_file = file_header.sizeof_int ;
3204 	 size_machine = sizeof( int ) ;
3205          tokenized_data_type[ current_token ].type[0] = 'I' ;
3206          tokenized_data_type[ current_token ].type[1] = '4' ;
3207 	 break ;
3208 
3209       case EVAL_2_BYTES( 'I', '8' ) :
3210 	 size_file = file_header.sizeof_long ;
3211 #if 0
3212 	 size_machine = sizeof( long ) ;
3213 #else
3214 	 size_machine = sizeof( cglong_t ) ;
3215 #endif
3216          tokenized_data_type[ current_token ].type[0] = 'I' ;
3217          tokenized_data_type[ current_token ].type[1] = '8' ;
3218 	 break ;
3219 
3220       case EVAL_2_BYTES( 'U', '4' ) :
3221 	 size_file = file_header.sizeof_int ;
3222 	 size_machine = sizeof( int ) ;
3223          tokenized_data_type[ current_token ].type[0] = 'U' ;
3224          tokenized_data_type[ current_token ].type[1] = '4' ;
3225 	 break ;
3226 
3227       case EVAL_2_BYTES( 'U', '8' ) :
3228 	 size_file = file_header.sizeof_long ;
3229 #if 0
3230 	 size_machine = sizeof( long ) ;
3231 #else
3232 	 size_machine = sizeof( cglong_t ) ;
3233 #endif
3234          tokenized_data_type[ current_token ].type[0] = 'U' ;
3235          tokenized_data_type[ current_token ].type[1] = '8' ;
3236 	 break ;
3237 
3238       case EVAL_2_BYTES( 'R', '4' ) :
3239 	 size_file = file_header.sizeof_float ;
3240 	 size_machine = sizeof( float ) ;
3241          tokenized_data_type[ current_token ].type[0] = 'R' ;
3242          tokenized_data_type[ current_token ].type[1] = '4' ;
3243 	 break ;
3244 
3245       case EVAL_2_BYTES( 'R', '8' ) :
3246 	 size_file = file_header.sizeof_double ;
3247 	 size_machine = sizeof( double ) ;
3248          tokenized_data_type[ current_token ].type[0] = 'R' ;
3249          tokenized_data_type[ current_token ].type[1] = '8' ;
3250 	 break ;
3251 
3252       case EVAL_2_BYTES( 'X', '4' ) :
3253 	 size_file = 2 * file_header.sizeof_float ;
3254 	 size_machine = 2 * sizeof( float ) ;
3255          tokenized_data_type[ current_token ].type[0] = 'X' ;
3256          tokenized_data_type[ current_token ].type[1] = '4' ;
3257 	 break ;
3258 
3259       case EVAL_2_BYTES( 'X', '8' ) :
3260 	 size_file = 2 * file_header.sizeof_double ;
3261 	 size_machine = 2 * sizeof( double ) ;
3262          tokenized_data_type[ current_token ].type[0] = 'X' ;
3263          tokenized_data_type[ current_token ].type[1] = '8' ;
3264 	 break ;
3265 
3266       case EVAL_2_BYTES( 'B', '1' ) :
3267 	 size_file = 1 ;
3268 	 size_machine = 1 ;
3269          tokenized_data_type[ current_token ].type[0] = 'B' ;
3270          tokenized_data_type[ current_token ].type[1] = '1' ;
3271 	 break ;
3272 
3273       case EVAL_2_BYTES( 'C', '1' ) :
3274       case EVAL_2_BYTES( 'L', 'K' ) :
3275 	 size_file = file_header.sizeof_char ;
3276 	 size_machine = sizeof( char ) ;
3277          tokenized_data_type[ current_token ].type[0] = 'C' ;
3278          tokenized_data_type[ current_token ].type[1] = '1' ;
3279 	 break ;
3280 
3281       default :	/** Error condition **/
3282 	 *error_return = INVALID_DATA_TYPE ;
3283 	 return ;
3284       } /* end switch */
3285 
3286    tokenized_data_type[ current_token ].file_type_size = size_file ;
3287    tokenized_data_type[ current_token ].machine_type_size = size_machine ;
3288    str_position += 2 ;
3289 
3290 	/** Look for arrays '[', commas ',', of end-of-string '\0' **/
3291    switch( data_type_string[ str_position ] ) {
3292       case '\0' :
3293 	 *file_bytes = *file_bytes + size_file ;
3294 	 *machine_bytes = *machine_bytes + size_machine ;
3295          tokenized_data_type[ current_token++ ].length = 1 ;
3296 	 break ;
3297 
3298       case '[' :
3299 	 {
3300 	 int	array_size = 0 ;
3301 	 str_position += 1 ;
3302 	 while( (data_type_string[ str_position ] >= '0') &&
3303 		(data_type_string[ str_position ] <= '9') ) {
3304 	    array_size = array_size * 10 +
3305 			(data_type_string[ str_position ] - '0') ;
3306 	    str_position += 1 ;
3307 	    } /* end while */
3308 	 if( data_type_string[ str_position ] != ']' ) {
3309 	    *error_return = INVALID_DATA_TYPE ;
3310 	    return ;
3311 	    } /* end if */
3312 	 str_position += 1 ;
3313 		/** Check for comma between types **/
3314 	 if( data_type_string[ str_position ] == ',' ) {
3315 	    str_position += 1 ;
3316 	    } /* end if */
3317 	 *file_bytes = *file_bytes + size_file * array_size ;
3318 	 *machine_bytes = *machine_bytes + size_machine * array_size ;
3319          tokenized_data_type[ current_token++ ].length = array_size ;
3320 	 }
3321 	 break ;
3322 
3323       case ',' :
3324 	 str_position += 1 ;
3325 	 *file_bytes = *file_bytes + size_file ;
3326 	 *machine_bytes = *machine_bytes + size_machine ;
3327 	 break ;
3328 
3329       default :	/** Error condition **/
3330 	 *error_return = INVALID_DATA_TYPE ;
3331 	 return ;
3332       } /* end switch */
3333    } /* end while */
3334 tokenized_data_type[ current_token ].type[0] = 0x00 ;
3335 tokenized_data_type[ current_token ].type[1] = 0x00 ;
3336 tokenized_data_type[ current_token ].file_type_size = *file_bytes;
3337 tokenized_data_type[ current_token ].machine_type_size = *machine_bytes ;
3338 } /* end of ADFI_evaluate_datatype */
3339 /* end of file ADFI_evaluate_datatype.c */
3340 /* file ADFI_fflush_file.c */
3341 /***********************************************************************
3342 ADFI fflush file:
3343     To flush the file output stream.
3344 
3345 input:  const unsigned int file_index   File to use.
3346 output: int *error_return               Error return.
3347 
3348     Possible errors:
3349 NO_ERROR
3350 ADF_FILE_NOT_OPENED
3351 FFLUSH_ERROR
3352 ***********************************************************************/
ADFI_fflush_file(const unsigned int file_index,int * error_return)3353 void    ADFI_fflush_file(
3354         const unsigned int file_index,
3355         int *error_return )
3356 {
3357 
3358 
3359 int  iret ;
3360 
3361 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
3362    *error_return = ADF_FILE_NOT_OPENED ;
3363    return ;
3364    } /* end if */
3365 
3366 *error_return = NO_ERROR ;
3367 
3368 ADF_sys_err = 0;
3369 # ifdef _WIN32
3370 iret = _commit( ADF_file[file_index].file ) ;
3371 # else
3372 iret = fsync( ADF_file[file_index].file ) ;
3373 # endif
3374 if (iret < 0) {
3375    ADF_sys_err = errno;
3376    *error_return = FFLUSH_ERROR ;
3377    } /* end if */
3378 } /* end of ADFI_fflush_file */
3379 /* end of file ADFI_fflush_file.c */
3380 /* file ADFI_figure_machine_format.c */
3381 /* file ADFI_figure_machine_format.c */
3382 /***********************************************************************
3383 ADFI figure machine format:
3384 	Determine if the host computer is IEEE_BIG, IEEE_LITTLE,
3385 	CRAY, or NATIVE.  Once this machines format if determined,
3386 	look at the requested format.  If NATIVE, use this machines
3387 	format, otherwise use the requested format.
3388 
3389 input:  const char *format		IEEE_BIG, IEEE_LITTLE, CRAY, or NATIVE.
3390 output: const char *machine_format	'B', 'L', 'C', 'N'
3391 output: const char *format_to_use	'B', 'L', 'C', 'N'
3392 output: const char *os_to_use    	'B', 'L'
3393 output:	int *error_return		Error return.
3394 
3395    Possible errors:
3396 NO_ERROR
3397 NULL_STRING_POINTER
3398 ***********************************************************************/
3399 
3400 static unsigned char	bits[NUMBER_KNOWN_MACHINES][8][8] = {
3401        /* IEEE BIG 32 */
3402  /* u.i =  123456789:   */	{ { 0x07, 0x5B, 0xCD, 0x15, 0x00, 0x00, 0x00, 0x00 },
3403  /* u.i = -123456789:   */	  { 0xF8, 0xA4, 0x32, 0xEB, 0x00, 0x00, 0x00, 0x00 },
3404  /* u.l =  1234567890L: */	  { 0x49, 0x96, 0x02, 0xD2, 0x00, 0x00, 0x00, 0x00 },
3405  /* u.l = -1234567890L: */	  { 0xB6, 0x69, 0xFD, 0x2E, 0x00, 0x00, 0x00, 0x00 },
3406  /* u.f =  12345.6789:  */	  { 0x46, 0x40, 0xE6, 0xB7, 0x00, 0x00, 0x00, 0x00 },
3407  /* u.f = -12345.6789:  */	  { 0xC6, 0x40, 0xE6, 0xB7, 0x00, 0x00, 0x00, 0x00 },
3408  /* u.d =  12345.6789:  */	  { 0x40, 0xC8, 0x1C, 0xD6, 0xE6, 0x31, 0xF8, 0xA1 },
3409  /* u.d = -12345.6789:  */	  { 0xC0, 0xC8, 0x1C, 0xD6, 0xE6, 0x31, 0xF8, 0xA1 } },
3410 
3411        /* IEEE LITTLE 32 */
3412  /* u.i =  123456789:   */	{ { 0x15, 0xCD, 0x5B, 0x07, 0x00, 0x00, 0x00, 0x00 },
3413  /* u.i = -123456789:   */	  { 0xEB, 0x32, 0xA4, 0xF8, 0x00, 0x00, 0x00, 0x00 },
3414  /* u.l =  1234567890L: */	  { 0xD2, 0x02, 0x96, 0x49, 0x00, 0x00, 0x00, 0x00 },
3415  /* u.l = -1234567890L: */	  { 0x2E, 0xFD, 0x69, 0xB6, 0x00, 0x00, 0x00, 0x00 },
3416  /* u.f =  12345.6789:  */	  { 0xB7, 0xE6, 0x40, 0x46, 0x00, 0x00, 0x00, 0x00 },
3417  /* u.f = -12345.6789:  */	  { 0xB7, 0xE6, 0x40, 0xC6, 0x00, 0x00, 0x00, 0x00 },
3418  /* u.d =  12345.6789:  */	  { 0xA1, 0xF8, 0x31, 0xE6, 0xD6, 0x1C, 0xC8, 0x40 },
3419  /* u.d = -12345.6789:  */	  { 0xA1, 0xF8, 0x31, 0xE6, 0xD6, 0x1C, 0xC8, 0xC0 } },
3420 
3421        /* IEEE BIG 64 */
3422  /* u.i =  123456789:   */	{ { 0x07, 0x5B, 0xCD, 0x15, 0x00, 0x00, 0x00, 0x00 },
3423  /* u.i = -123456789:   */	  { 0xF8, 0xA4, 0x32, 0xEB, 0x00, 0x00, 0x00, 0x00 },
3424  /* u.l =  1234567890L: */	  { 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xD2 },
3425  /* u.l = -1234567890L: */	  { 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x69, 0xFD, 0x2E },
3426  /* u.f =  12345.6789:  */	  { 0x46, 0x40, 0xE6, 0xB7, 0x00, 0x00, 0x00, 0x00 },
3427  /* u.f = -12345.6789:  */	  { 0xC6, 0x40, 0xE6, 0xB7, 0x00, 0x00, 0x00, 0x00 },
3428  /* u.d =  12345.6789:  */	  { 0x40, 0xC8, 0x1C, 0xD6, 0xE6, 0x31, 0xF8, 0xA1 },
3429  /* u.d = -12345.6789:  */	  { 0xC0, 0xC8, 0x1C, 0xD6, 0xE6, 0x31, 0xF8, 0xA1 } },
3430 
3431        /* IEEE LITTLE 64 */
3432  /* u.i =  123456789:   */	{ { 0x15, 0xCD, 0x5B, 0x07, 0x00, 0x00, 0x00, 0x00 },
3433  /* u.i = -123456789:   */	  { 0xEB, 0x32, 0xA4, 0xF8, 0x00, 0x00, 0x00, 0x00 },
3434  /* u.l =  1234567890L: */	  { 0xD2, 0x02, 0x96, 0x49, 0x00, 0x00, 0x00, 0x00 },
3435  /* u.l = -1234567890L: */	  { 0x2E, 0xFD, 0x69, 0xB6, 0xFF, 0xFF, 0xFF, 0xFF },
3436  /* u.f =  12345.6789:  */	  { 0xB7, 0xE6, 0x40, 0x46, 0x00, 0x00, 0x00, 0x00 },
3437  /* u.f = -12345.6789:  */	  { 0xB7, 0xE6, 0x40, 0xC6, 0x00, 0x00, 0x00, 0x00 },
3438  /* u.d =  12345.6789:  */	  { 0xA1, 0xF8, 0x31, 0xE6, 0xD6, 0x1C, 0xC8, 0x40 },
3439  /* u.d = -12345.6789:  */	  { 0xA1, 0xF8, 0x31, 0xE6, 0xD6, 0x1C, 0xC8, 0xC0 } },
3440 
3441 	/* CRAY     */
3442  /* u.i =  123456789:   */	{ { 0x00, 0x00, 0x00, 0x00, 0x07, 0x5B, 0xCD, 0x15 },
3443  /* u.i = -123456789:   */	  { 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xA4, 0x32, 0xEB },
3444  /* u.l =  1234567890L: */	  { 0x00, 0x00, 0x00, 0x00, 0x49, 0x96, 0x02, 0xD2 },
3445  /* u.l = -1234567890L: */	  { 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x69, 0xFD, 0x2E },
3446  /* u.f =  12345.6789:  */	  { 0x40, 0x0E, 0xC0, 0xE6, 0xB7, 0x31, 0x8F, 0xC5 },
3447  /* u.f = -12345.6789:  */	  { 0xC0, 0x0E, 0xC0, 0xE6, 0xB7, 0x31, 0x8F, 0xC5 },
3448  /* u.d =  12345.6789:  */	  { 0x40, 0x0E, 0xC0, 0xE6, 0xB7, 0x31, 0x8F, 0xC5 },
3449  /* u.d = -12345.6789:  */	  { 0xC0, 0x0E, 0xC0, 0xE6, 0xB7, 0x31, 0x8F, 0xC5 } }
3450 	} ;
3451 
ADFI_figure_machine_format(const char * format,char * machine_format,char * format_to_use,char * os_to_use,int * error_return)3452 void    ADFI_figure_machine_format(
3453 		const char *format,
3454 		char *machine_format,
3455 		char *format_to_use,
3456 		char *os_to_use,
3457 		int *error_return )
3458 {
3459 char	requested_format, requested_os, machine_os_size = OS_32_BIT ;
3460 union { int i; long l; float f; double d; unsigned char bytes[8]; } u ;
3461 int	i, k, OK ;
3462 
3463 if( (machine_format == NULL) || (format_to_use == NULL) ||
3464     (os_to_use == NULL) ) {
3465    *error_return = NULL_STRING_POINTER ;
3466    return ;
3467    } /* end if */
3468 
3469 *error_return = NO_ERROR ;
3470 
3471 	/** Check requested format **/
3472 if( format == NULL ) {
3473    requested_format = NATIVE_FORMAT_CHAR ;
3474    requested_os     = OS_32_BIT ;
3475    } /* end if */
3476 else if( (format[0] == '\0') || (format[0] == ' ') ) {
3477    requested_format = NATIVE_FORMAT_CHAR ;
3478    requested_os     = OS_32_BIT ;
3479    } /* end else if */
3480 else if( ADFI_stridx_c( IEEE_BIG_32_FORMAT_STRING, format ) == 0 ) {
3481    requested_format = IEEE_BIG_FORMAT_CHAR ;
3482    requested_os     = OS_32_BIT ;
3483    } /* end else if */
3484 else if( ADFI_stridx_c( IEEE_LITTLE_32_FORMAT_STRING, format ) == 0 ) {
3485    requested_format = IEEE_LITTLE_FORMAT_CHAR ;
3486    requested_os     = OS_32_BIT ;
3487    } /* end else if */
3488 else if( ADFI_stridx_c( IEEE_BIG_64_FORMAT_STRING, format ) == 0 ) {
3489    requested_format = IEEE_BIG_FORMAT_CHAR ;
3490    requested_os     = OS_64_BIT ;
3491    } /* end else if */
3492 else if( ADFI_stridx_c( IEEE_LITTLE_64_FORMAT_STRING, format ) == 0 ) {
3493    requested_format = IEEE_LITTLE_FORMAT_CHAR ;
3494    requested_os     = OS_64_BIT ;
3495    } /* end else if */
3496 else if( ADFI_stridx_c( CRAY_FORMAT_STRING, format ) == 0 ) {
3497    requested_format = CRAY_FORMAT_CHAR ;
3498    requested_os     = OS_64_BIT ;
3499    } /* end else if */
3500 else if( ADFI_stridx_c( NATIVE_FORMAT_STRING, format ) == 0 ||
3501 	 ADFI_stridx_c( LEGACY_FORMAT_STRING, format ) == 0 ) {
3502    requested_format = NATIVE_FORMAT_CHAR ;
3503    requested_os     = OS_32_BIT ;
3504    } /* end else if */
3505 else {
3506    *error_return = ADF_FILE_FORMAT_NOT_RECOGNIZED ;
3507    return ;
3508    } /* end else */
3509 
3510 	/***** Determine this machine's numeric format *****/
3511 	/** Check for numeric bit patterns **/
3512 #define	ZERO_UNION()						\
3513 	for( k=0; k<8; k++ )					\
3514 	   u.bytes[k] = '\0' ;
3515 #define	CHECK_UNION(B)						\
3516    if( (u.bytes[0] != B[0]) || (u.bytes[1] != B[1]) ||		\
3517        (u.bytes[2] != B[2]) || (u.bytes[3] != B[3]) ||		\
3518        (u.bytes[4] != B[4]) || (u.bytes[5] != B[5]) ||		\
3519        (u.bytes[6] != B[6]) || (u.bytes[7] != B[7]) ) continue ;
3520 
3521 OK = FALSE ;
3522 *machine_format = NATIVE_FORMAT_CHAR ;
3523 for( i=0; i<NUMBER_KNOWN_MACHINES; i++ ) {
3524    ZERO_UNION() ;
3525    u.i = 123456789 ;
3526    CHECK_UNION( bits[i][0] ) ;
3527 
3528    ZERO_UNION() ;
3529    u.i = -123456789 ;
3530    CHECK_UNION( bits[i][1] ) ;
3531 
3532    ZERO_UNION() ;
3533    u.l = 1234567890L ;
3534    CHECK_UNION( bits[i][2] ) ;
3535 
3536    ZERO_UNION() ;
3537    u.l = -1234567890L ;
3538    CHECK_UNION( bits[i][3] ) ;
3539 
3540    ZERO_UNION() ;
3541    u.f = (float) 12345.6789 ;
3542    CHECK_UNION( bits[i][4] ) ;
3543 
3544    ZERO_UNION() ;
3545    u.f = (float) -12345.6789 ;
3546    CHECK_UNION( bits[i][5] ) ;
3547 
3548    ZERO_UNION() ;
3549    u.d = 12345.6789 ;
3550    CHECK_UNION( bits[i][6] ) ;
3551 
3552    ZERO_UNION() ;
3553    u.d = -12345.6789 ;
3554    CHECK_UNION( bits[i][7] ) ;
3555 
3556    OK = TRUE ;
3557    switch( i + 1 ) {
3558       case IEEE_BIG_32_FORMAT:
3559 	 *machine_format = IEEE_BIG_FORMAT_CHAR ;
3560 	 machine_os_size = OS_32_BIT ;
3561 	 break ;
3562 
3563       case IEEE_LITTLE_32_FORMAT:
3564 	 *machine_format = IEEE_LITTLE_FORMAT_CHAR ;
3565 	 machine_os_size = OS_32_BIT ;
3566 	 break ;
3567 
3568       case IEEE_BIG_64_FORMAT:
3569 	 *machine_format = IEEE_BIG_FORMAT_CHAR ;
3570 	 machine_os_size = OS_64_BIT ;
3571 	 break ;
3572 
3573       case IEEE_LITTLE_64_FORMAT:
3574 	 *machine_format = IEEE_LITTLE_FORMAT_CHAR ;
3575 	 machine_os_size = OS_64_BIT ;
3576 	 break ;
3577 
3578       case CRAY_FORMAT:
3579 	 *machine_format = CRAY_FORMAT_CHAR ;
3580 	 machine_os_size = OS_64_BIT ;
3581 	 break ;
3582 
3583       default:	/** Some other format, call it NATIVE **/
3584 	 *machine_format = NATIVE_FORMAT_CHAR ;
3585 	 break ;
3586 
3587       } /* end switch */
3588    break ; /* get out of the for loop */
3589    } /* end for */
3590 
3591 if( OK == TRUE ) {
3592 	/* check the size-of pattern */
3593    if( sizeof( char )		!= machine_sizes[i][ 0] ) OK = FALSE ;
3594    if( sizeof( unsigned char )	!= machine_sizes[i][ 1] ) OK = FALSE ;
3595    if( sizeof( signed char )	!= machine_sizes[i][ 2] ) OK = FALSE ;
3596    if( sizeof( short )		!= machine_sizes[i][ 3] ) OK = FALSE ;
3597    if( sizeof( unsigned short )	!= machine_sizes[i][ 4] ) OK = FALSE ;
3598    if( sizeof( int )		!= machine_sizes[i][ 5] ) OK = FALSE ;
3599    if( sizeof( unsigned int )	!= machine_sizes[i][ 6] ) OK = FALSE ;
3600    if( sizeof( long )		!= machine_sizes[i][ 7] ) OK = FALSE ;
3601    if( sizeof( unsigned long )	!= machine_sizes[i][ 8] ) OK = FALSE ;
3602    if( sizeof( float )		!= machine_sizes[i][ 9] ) OK = FALSE ;
3603    if( sizeof( double )		!= machine_sizes[i][10] ) OK = FALSE ;
3604 /* This causes the machine type to not be detected on 64-bit Windows
3605  * since ints and longs are still 32-bit (IEEE_LITTLE_32_FORMAT),
3606  * but pointers are 64-bit instead of 32-bit. I don't think it's
3607  * necessary to check pointer sizes, since pointers are read or
3608  * written to the file - Bruce */
3609 #if 0
3610    if( sizeof( char * )		!= machine_sizes[i][11] ) OK = FALSE ;
3611    if( sizeof( int * )		!= machine_sizes[i][12] ) OK = FALSE ;
3612    if( sizeof( long * )		!= machine_sizes[i][13] ) OK = FALSE ;
3613    if( sizeof( float * )	!= machine_sizes[i][14] ) OK = FALSE ;
3614    if( sizeof( double * )	!= machine_sizes[i][15] ) OK = FALSE ;
3615 #endif
3616    } /* end if */
3617 
3618 if( OK == FALSE ) {
3619    *machine_format = NATIVE_FORMAT_CHAR ;
3620    if ( sizeof( double * ) >= 8 ) machine_os_size = OS_64_BIT ;
3621    else machine_os_size = OS_32_BIT ;
3622    } /* end if */
3623 
3624 if( ADF_this_machine_format == UNDEFINED_FORMAT_CHAR ) {
3625    ADF_this_machine_format  = *machine_format ;
3626    ADF_this_machine_os_size = machine_os_size ;
3627    } /* end if */
3628 
3629 if( requested_format == NATIVE_FORMAT_CHAR ) {
3630    *format_to_use = *machine_format ;
3631    *os_to_use = machine_os_size ;
3632    } /* end if */
3633 else {
3634    *format_to_use = requested_format ;
3635    *os_to_use     = requested_os ;
3636    } /* end if */
3637 
3638 if( *machine_format == NATIVE_FORMAT_CHAR )
3639    *error_return = MACHINE_FORMAT_NOT_RECOGNIZED ;
3640 
3641 } /* end of ADFI_figure_machine_format */
3642 /* end of file ADFI_figure_machine_format.c */
3643 /* end of file ADFI_figure_machine_format.c */
3644 /* file ADFI_file_and_machine_compare.c */
3645 /***********************************************************************
3646 ADFI file and machine compare:
3647    Compares file and machine formats.
3648 
3649 input:  const int file_index      The file index (0 to MAXIMUM_FILES).
3650 output: int  *compare             1 = formats compare, 0 = do not
3651 output: int  *error_return        Error return
3652 
3653    Possible errors:
3654 FILE_INDEX_OUT_OF_RANGE
3655 ***********************************************************************/
ADFI_file_and_machine_compare(const int file_index,const struct TOKENIZED_DATA_TYPE * tokenized_data_type,int * compare,int * error_return)3656 void  ADFI_file_and_machine_compare(
3657          const int file_index,
3658 	 const struct TOKENIZED_DATA_TYPE *tokenized_data_type,
3659          int   *compare,
3660          int   *error_return )
3661 {
3662    int machine_size, file_size, token ;
3663    *compare = 0 ;
3664    *error_return = NO_ERROR ;
3665 
3666    if( file_index < 0 || file_index >= maximum_files ) {
3667       *error_return = FILE_INDEX_OUT_OF_RANGE ;
3668       return ;
3669    }
3670 
3671    if( ADF_this_machine_format == NATIVE_FORMAT_CHAR ||
3672        ADF_file[file_index].format ==  NATIVE_FORMAT_CHAR ) {
3673       unsigned int size_long;
3674       struct	FILE_HEADER	file_header ;
3675 	/** Get file_header for the file variable sizes **/
3676       ADFI_read_file_header( file_index, &file_header, error_return ) ;
3677       if( *error_return != NO_ERROR )
3678          return ;
3679       size_long = ADF_file[file_index].old_version ? sizeof(long) : sizeof(cglong_t);
3680         /** Make sure the sizes are the same or we are cooked!! **/
3681       if ( ADF_file[file_index].format !=  NATIVE_FORMAT_CHAR  ||
3682            file_header.sizeof_char !=	  sizeof( char )    ||
3683            file_header.sizeof_short !=	  sizeof( short )   ||
3684            file_header.sizeof_int !=	  sizeof( int )     ||
3685            file_header.sizeof_long !=	  size_long         ||
3686            file_header.sizeof_float !=	  sizeof( float )   ||
3687 #if 0
3688            file_header.sizeof_double !=   sizeof( double )  ||
3689            file_header.sizeof_char_p !=   sizeof( char * )  ||
3690            file_header.sizeof_short_p !=  sizeof( short * ) ||
3691            file_header.sizeof_int_p !=	  sizeof( int * )   ||
3692            file_header.sizeof_long_p !=   sizeof( long * )  ||
3693            file_header.sizeof_float_p !=  sizeof( float * ) ||
3694            file_header.sizeof_double_p != sizeof( double * )  ) {
3695 #else
3696            file_header.sizeof_double !=   sizeof( double ) ) {
3697 #endif
3698          *error_return = MACHINE_FILE_INCOMPATABLE ;
3699          return ;
3700       } /** end if **/
3701    } /** end if **/
3702 
3703    if( ADF_file[file_index].format  == ADF_this_machine_format &&
3704        ADF_file[file_index].os_size == ADF_this_machine_os_size ) {
3705       *compare = 1 ;
3706    } else if( ADF_file[file_index].format  == ADF_this_machine_format ) {
3707         /** If the file and machine binary type are the same and only the
3708 	    sizes may be different (like long is 32 or 64), then if all the
3709 	    sizes are the same then no conversion is necessary and ws can avoid
3710 	    the conversion overhead and just do direct read/writes. **/
3711       if ( tokenized_data_type == NULL ) return ;
3712       token = -1 ;
3713       *compare = 1 ;
3714       do {
3715          token++ ;
3716 	 machine_size = tokenized_data_type[ token ].machine_type_size ;
3717 	 file_size = tokenized_data_type[ token ].file_type_size ;
3718 	 if ( machine_size != file_size ) {
3719 	   *compare = 0 ;
3720 	   break ;
3721 	 }
3722       } while( tokenized_data_type[ token ].type[0] != 0 ) ;
3723    }
3724 } /* end of ADFI_file_and_machine_compare */
3725 /* end of file ADFI_file_and_machine_compare.c */
3726 /* file ADFI_file_block_offset_2_ID.c */
3727 /***********************************************************************
3728 ADFI file block and offset to ID:
3729 	Convert an ADF file, block, and offset to an ADF ID.
3730 
3731 input:  const int file_index		The file index (0 to MAXIMUM_FILES).
3732 input:  const unsigned long file_block	The block within the file.
3733 input:  const unsigned long block_offset The offset within the block.
3734 output: double *ID			The resulting ADF ID.
3735 output:	int *error_return		Error return.
3736 
3737    Possible errors:
3738 NO_ERROR
3739 NULL_POINTER
3740 FILE_INDEX_OUT_OF_RANGE
3741 BLOCK_OFFSET_OUT_OF_RANGE
3742 ***********************************************************************/
3743 void    ADFI_file_block_offset_2_ID(
3744 		const int file_index,
3745 		const cgulong_t file_block,
3746 		const cgulong_t block_offset,
3747 		double *ID,
3748 		int *error_return )
3749 {
3750 double dd;
3751 unsigned char * cc;
3752 
3753 if( ID == NULL ) {
3754    *error_return = NULL_POINTER ;
3755    return ;
3756    } /* end if */
3757 
3758 *error_return = NO_ERROR ;
3759 if( file_index >= maximum_files ) {
3760    *error_return = FILE_INDEX_OUT_OF_RANGE ;
3761    return ;
3762    } /* end if */
3763 
3764 if( block_offset >= DISK_BLOCK_SIZE ) {
3765    *error_return = BLOCK_OFFSET_OUT_OF_RANGE ;
3766    return ;
3767    } /* end if */
3768 
3769 	/** Map the bytes into the character variable **/
3770    /* Note that there were problems with some machines flushing small numbers
3771       to zero causing problems with the encoding of ID (which is not in
3772       its self a true number). The IEEE standard says that this is not
3773       allowed and so should not be a problem except that you get a major
3774       performance hit on the machine if you have it enforce the IEEE
3775       standard. Thus I force the sign bit on the exponent to always be positive
3776       so that the ID is a number greater than |1|. Previously on the
3777       IEEE big endian the numbers would look like 3.132313E-311. The
3778       new encoding changes the max number of open files to 16K from 64K */
3779 
3780 cc = (unsigned char *) &dd;
3781 #ifdef NEW_ID_MAPPING
3782 #if 0
3783 assert(file_index <= 0xfff);
3784 assert(file_block <= 0x3fffffffff);
3785 assert(block_offset <= 0xfff);
3786 if (ADF_this_machine_format == IEEE_LITTLE_FORMAT_CHAR) {
3787   cc[7] = (unsigned char)((file_index & 0x0FC0) >> 6) + 0x40;
3788   cc[6] = (unsigned char)((file_index & 0x003F) << 2) +
3789           (unsigned char)((file_block & 0x3000000000) >> 36);
3790   cc[5] = (unsigned char)((file_block & 0x0FF0000000) >> 28);
3791   cc[4] = (unsigned char)((file_block & 0x000FF00000) >> 20);
3792   cc[3] = (unsigned char)((file_block & 0x00000FF000) >> 12);
3793   cc[2] = (unsigned char)((file_block & 0x0000000FF0) >> 4);
3794   cc[1] = (unsigned char)((file_block & 0x000000000F) << 4) +
3795           (unsigned char)((block_offset & 0x0F00) >> 8);
3796   cc[0] = (unsigned char) (block_offset & 0x00FF);
3797 }
3798 else {
3799   cc[0] = (unsigned char)((file_index & 0x0FC0) >> 6) + 0x40;
3800   cc[1] = (unsigned char)((file_index & 0x003F) << 2) +
3801           (unsigned char)((file_block & 0x3000000000) >> 36);
3802   cc[2] = (unsigned char)((file_block & 0x0FF0000000) >> 28);
3803   cc[3] = (unsigned char)((file_block & 0x000FF00000) >> 20);
3804   cc[4] = (unsigned char)((file_block & 0x00000FF000) >> 12);
3805   cc[5] = (unsigned char)((file_block & 0x0000000FF0) >> 4);
3806   cc[6] = (unsigned char)((file_block & 0x000000000F) << 4) +
3807           (unsigned char)((block_offset & 0x0F00) >> 8);
3808   cc[7] = (unsigned char) (block_offset & 0x00FF);
3809 }
3810 #else
3811 if (ADF_this_machine_format == IEEE_LITTLE_FORMAT_CHAR) {
3812   cc[7] = (unsigned char)((file_index   >>  6) & 0x3F) + 0x40;
3813   cc[6] = (unsigned char)((file_index   <<  2) & 0xFC) +
3814           (unsigned char)((file_block   >> 36) & 0x03);
3815   cc[5] = (unsigned char)((file_block   >> 28) & 0xFF);
3816   cc[4] = (unsigned char)((file_block   >> 20) & 0xFF);
3817   cc[3] = (unsigned char)((file_block   >> 12) & 0xFF);
3818   cc[2] = (unsigned char)((file_block   >>  4) & 0xFF);
3819   cc[1] = (unsigned char)((file_block   <<  4) & 0xF0) +
3820           (unsigned char)((block_offset >>  8) & 0x0F);
3821   cc[0] = (unsigned char) (block_offset        & 0xFF);
3822 }
3823 else {
3824   cc[0] = (unsigned char)((file_index   >>  6) & 0x3F) + 0x40;
3825   cc[1] = (unsigned char)((file_index   <<  2) & 0xFC) +
3826           (unsigned char)((file_block   >> 36) & 0x03);
3827   cc[2] = (unsigned char)((file_block   >> 28) & 0xFF);
3828   cc[3] = (unsigned char)((file_block   >> 20) & 0xFF);
3829   cc[4] = (unsigned char)((file_block   >> 12) & 0xFF);
3830   cc[5] = (unsigned char)((file_block   >>  4) & 0xFF);
3831   cc[6] = (unsigned char)((file_block   <<  4) & 0xF0) +
3832           (unsigned char)((block_offset >>  8) & 0x0F);
3833   cc[7] = (unsigned char) (block_offset        & 0xFF);
3834 }
3835 #endif
3836 #else
3837 if ( ADF_this_machine_format == IEEE_BIG_FORMAT_CHAR ) {
3838    cc[1] = (unsigned char) (file_index & 0x00ff) ;
3839    cc[0] = (unsigned char) (64 + (( file_index >> 8) & 0x003f)) ;
3840 
3841    cc[2] = (unsigned char) (file_block & 0x000000ff) ;
3842    cc[3] = (unsigned char) ((file_block >> 8) & 0x000000ff) ;
3843    cc[4] = (unsigned char) ((file_block >> 16) & 0x000000ff) ;
3844    cc[5] = (unsigned char) ((file_block >> 24) & 0x000000ff) ;
3845 
3846    cc[6] = (unsigned char) (block_offset & 0x00ff) ;
3847    cc[7] = (unsigned char) ((block_offset >> 8) & 0x00ff) ;
3848    } /* end if */
3849 else if ( ADF_this_machine_format == IEEE_LITTLE_FORMAT_CHAR ) {
3850    cc[6] = (unsigned char) (file_index & 0x00ff) ;
3851    cc[7] = (unsigned char) (64 + (( file_index >> 8) & 0x003f)) ;
3852 
3853    cc[2] = (unsigned char) (file_block & 0x000000ff) ;
3854    cc[3] = (unsigned char) ((file_block >> 8) & 0x000000ff) ;
3855    cc[4] = (unsigned char) ((file_block >> 16) & 0x000000ff) ;
3856    cc[5] = (unsigned char) ((file_block >> 24) & 0x000000ff) ;
3857 
3858    cc[0] = (unsigned char) (block_offset & 0x00ff) ;
3859    cc[1] = (unsigned char) ((block_offset >> 8) & 0x00ff) ;
3860    } /* end else if */
3861 else {
3862    cc[0] = (unsigned char) (file_index & 0x00ff) ;
3863    cc[1] = (unsigned char) ((file_index >> 8) & 0x00ff) ;
3864 
3865    cc[2] = (unsigned char) (file_block & 0x000000ff) ;
3866    cc[3] = (unsigned char) ((file_block >> 8) & 0x000000ff) ;
3867    cc[4] = (unsigned char) ((file_block >> 16) & 0x000000ff) ;
3868    cc[5] = (unsigned char) ((file_block >> 24) & 0x000000ff) ;
3869 
3870    cc[6] = (unsigned char) (block_offset & 0x00ff) ;
3871    cc[7] = (unsigned char) ((block_offset >> 8) & 0x00ff) ;
3872    } /* end else */
3873 #endif
3874 
3875 *ID = dd;
3876 #ifdef PRINT_STUFF
3877 printf("cc[0-7] = %02X %02X %02X %02X %02X %02X %02X %02X \n",
3878 	cc[0], cc[1], cc[2], cc[3],
3879 	cc[4], cc[5], cc[6], cc[7] ) ;
3880 printf("In ADFI_file_block_offset_2_ID: ID=%lf\n",*ID);
3881 #endif
3882 
3883 } /* end of ADFI_file_block_offset_2_ID */
3884 /* end of file ADFI_file_block_offset_2_ID.c */
3885 /* file ADFI_file_free.c */
3886 /***********************************************************************
3887 ADFI file free:
3888      To free-up a chunk of file space.
3889 
3890 input:  const int file_index		The file index (0 to MAXIMUM_FILES).
3891 input:  const struct DISK_POINTER *block_offset  Block & offset in the file.
3892 input:  const long number_of_bytes	Number of bytes to free.  If 0,
3893 					then look at type of chunk to get size.
3894 output:	int *error_return		Error return.
3895 
3896    Possible errors:
3897 NO_ERROR
3898 NULL_POINTER
3899 ADF_FILE_NOT_OPENED
3900 FREE_OF_ROOT_NODE
3901 ADF_DISK_TAG_ERROR
3902 FREE_OF_FREE_CHUNK_TABLE
3903 ***********************************************************************/
3904 void	ADFI_file_free(
3905         const int file_index,
3906         const struct DISK_POINTER *block_offset,
3907         const cglong_t in_number_of_bytes,
3908         int *error_return )
3909 {
3910 char                        tag[TAG_SIZE + 1] ;
3911 struct	DISK_POINTER        end_of_chunk_tag ;
3912 struct  DISK_POINTER        tmp_blk_ofst ;
3913 struct	FREE_CHUNK_TABLE    free_chunk_table ;
3914 struct	FREE_CHUNK          free_chunk ;
3915 int     i ;
3916 cglong_t    number_of_bytes = in_number_of_bytes ;
3917 
3918 if( block_offset == NULL ) {
3919    *error_return = NULL_POINTER ;
3920    return ;
3921    } /* end if */
3922 
3923 if( file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
3924    *error_return = ADF_FILE_NOT_OPENED ;
3925    return ;
3926    } /* end if */
3927 
3928 if( number_of_bytes == 0 ) {
3929 
3930    /** Check the disk tag to see what kind of disk chunk we have.
3931       We need this to determine the length of the chunk. **/
3932    ADFI_read_file( file_index, block_offset->block, block_offset->offset,
3933 	TAG_SIZE, tag, error_return ) ;
3934    if( *error_return != NO_ERROR )
3935       return ;
3936 
3937    tag[TAG_SIZE] = '\0' ; /* Null terminate the string */
3938 
3939    end_of_chunk_tag.block = 0 ;
3940    end_of_chunk_tag.offset = 0 ;
3941    if( ADFI_stridx_c( tag, node_start_tag ) == 0 ) {	/** This is a node **/
3942       if( (block_offset->block == ROOT_NODE_BLOCK) &&
3943           (block_offset->offset == ROOT_NODE_OFFSET) ) {
3944          *error_return = FREE_OF_ROOT_NODE ;
3945          return ;
3946          } /* end if */
3947       end_of_chunk_tag.block = block_offset->block ;
3948       end_of_chunk_tag.offset = block_offset->offset + NODE_HEADER_SIZE -
3949 	                        TAG_SIZE ;
3950       if ( end_of_chunk_tag.offset > DISK_BLOCK_SIZE ) {
3951          ADFI_adjust_disk_pointer( &end_of_chunk_tag, error_return ) ;
3952          if( *error_return != NO_ERROR )
3953             return ;
3954       }
3955 
3956       /** Check disk boundary-tag **/
3957       ADFI_read_file( file_index, end_of_chunk_tag.block,
3958 	   end_of_chunk_tag.offset, TAG_SIZE, tag, error_return ) ;
3959       if( *error_return != NO_ERROR )
3960          return ;
3961       if( ADFI_stridx_c( tag, node_end_tag ) != 0 ) {
3962          *error_return = ADF_DISK_TAG_ERROR ;
3963          return ;
3964          } /* end if */
3965       } /* end if */
3966    else if( ADFI_stridx_c( tag, free_chunk_table_start_tag ) == 0 ) {
3967 	   /** Trying to free the free-chunk-table.  This is BAD. **/
3968       *error_return = FREE_OF_FREE_CHUNK_TABLE ;
3969       return ;
3970       } /* end else if */
3971    else if( ADFI_stridx_c( tag, free_chunk_start_tag ) == 0 ) {
3972 
3973            /** Set a temporary block/offset to read disk pointer **/
3974       tmp_blk_ofst.block = block_offset->block ;
3975       tmp_blk_ofst.offset = block_offset->offset + TAG_SIZE ;
3976       if ( tmp_blk_ofst.offset > DISK_BLOCK_SIZE ) {
3977          ADFI_adjust_disk_pointer( &tmp_blk_ofst, error_return ) ;
3978          if( *error_return != NO_ERROR )
3979             return ;
3980       }
3981 	   /** Get the end_of_chunk-tag block/offset from disk **/
3982       ADFI_read_disk_pointer_from_disk( file_index, tmp_blk_ofst.block,
3983            tmp_blk_ofst.offset, &end_of_chunk_tag, error_return ) ;
3984       if( *error_return != NO_ERROR )
3985          return ;
3986 
3987          /** Check disk boundary-tag **/
3988       ADFI_read_file( file_index, end_of_chunk_tag.block,
3989 	   end_of_chunk_tag.offset, TAG_SIZE, tag, error_return ) ;
3990       if( *error_return != NO_ERROR )
3991          return ;
3992       if( ADFI_stridx_c( tag, free_chunk_end_tag ) != 0 ) {
3993          *error_return = ADF_DISK_TAG_ERROR ;
3994          return ;
3995          } /* end if */
3996       } /* end else if */
3997    else if( ADFI_stridx_c( tag, sub_node_start_tag ) == 0 ) {
3998 
3999            /** Set a temporary block/offset to read disk pointer **/
4000       tmp_blk_ofst.block = block_offset->block ;
4001       tmp_blk_ofst.offset = block_offset->offset + TAG_SIZE ;
4002       if ( tmp_blk_ofst.offset > DISK_BLOCK_SIZE ) {
4003          ADFI_adjust_disk_pointer( &tmp_blk_ofst, error_return ) ;
4004          if( *error_return != NO_ERROR )
4005             return ;
4006       }
4007 
4008          /** Get the end_of_chunk-tag block/offset from disk **/
4009       ADFI_read_disk_pointer_from_disk( file_index, tmp_blk_ofst.block,
4010            tmp_blk_ofst.offset, &end_of_chunk_tag, error_return ) ;
4011       if( *error_return != NO_ERROR )
4012          return ;
4013 
4014          /** Check disk boundary-tag **/
4015       ADFI_read_file( file_index, end_of_chunk_tag.block,
4016 	   end_of_chunk_tag.offset, TAG_SIZE, tag, error_return ) ;
4017       if( *error_return != NO_ERROR )
4018          return ;
4019       if( ADFI_stridx_c( tag, sub_node_end_tag ) != 0 ) {
4020          *error_return = ADF_DISK_TAG_ERROR ;
4021          return ;
4022          } /* end if */
4023       } /* end else if */
4024    else if( ADFI_stridx_c( tag, data_chunk_table_start_tag ) == 0 ) {
4025 
4026            /** Set a temporary block/offset to read disk pointer **/
4027       tmp_blk_ofst.block = block_offset->block ;
4028       tmp_blk_ofst.offset = block_offset->offset + TAG_SIZE ;
4029       if ( tmp_blk_ofst.offset > DISK_BLOCK_SIZE ) {
4030          ADFI_adjust_disk_pointer( &tmp_blk_ofst, error_return ) ;
4031          if( *error_return != NO_ERROR )
4032             return ;
4033       }
4034 
4035 	   /** Get the end_of_chunk-tag block/offset from disk **/
4036       ADFI_read_disk_pointer_from_disk( file_index, tmp_blk_ofst.block,
4037            tmp_blk_ofst.offset, &end_of_chunk_tag, error_return ) ;
4038       if( *error_return != NO_ERROR )
4039          return ;
4040 
4041          /** Check disk boundary-tag **/
4042       ADFI_read_file( file_index, end_of_chunk_tag.block,
4043 	   end_of_chunk_tag.offset, TAG_SIZE, tag, error_return ) ;
4044       if( *error_return != NO_ERROR )
4045          return ;
4046       if( ADFI_stridx_c( tag, data_chunk_table_end_tag ) != 0 ) {
4047          *error_return = ADF_DISK_TAG_ERROR ;
4048          return ;
4049          } /* end if */
4050       } /* end else if */
4051    else if( ADFI_stridx_c( tag, data_chunk_start_tag ) == 0 ) {
4052 
4053            /** Set a temporary block/offset to read disk pointer **/
4054       tmp_blk_ofst.block = block_offset->block ;
4055       tmp_blk_ofst.offset = block_offset->offset + TAG_SIZE ;
4056       if ( tmp_blk_ofst.offset > DISK_BLOCK_SIZE ) {
4057          ADFI_adjust_disk_pointer( &tmp_blk_ofst, error_return ) ;
4058          if( *error_return != NO_ERROR )
4059             return ;
4060       }
4061 
4062            /** Get the end_of_chunk-tag block/offset from disk **/
4063       ADFI_read_disk_pointer_from_disk( file_index, tmp_blk_ofst.block,
4064            tmp_blk_ofst.offset, &end_of_chunk_tag, error_return ) ;
4065       if( *error_return != NO_ERROR )
4066          return ;
4067 
4068          /** Check disk boundary-tag **/
4069       ADFI_read_file( file_index, end_of_chunk_tag.block,
4070 	   end_of_chunk_tag.offset, TAG_SIZE, tag, error_return ) ;
4071       if( *error_return != NO_ERROR )
4072          return ;
4073       if( ADFI_stridx_c( tag, data_chunk_end_tag ) != 0 ) {
4074          *error_return = ADF_DISK_TAG_ERROR ;
4075          return ;
4076          } /* end if */
4077       } /* end else if */
4078    else {
4079       *error_return = ADF_DISK_TAG_ERROR ;
4080       return ;
4081       } /* end else */
4082    number_of_bytes = (end_of_chunk_tag.block - block_offset->block) *
4083 	DISK_BLOCK_SIZE + (end_of_chunk_tag.offset - block_offset->offset +
4084 		TAG_SIZE) ;
4085    } /* end if */
4086 else {	/** Use the number of bytes passed in **/
4087    end_of_chunk_tag.block = block_offset->block ;
4088    end_of_chunk_tag.offset = block_offset->offset + number_of_bytes - TAG_SIZE ;
4089    ADFI_adjust_disk_pointer( &end_of_chunk_tag, error_return ) ;
4090    if( *error_return != NO_ERROR )
4091       return ;
4092    } /* end else */
4093 
4094 if( number_of_bytes <= SMALLEST_CHUNK_SIZE ) { /** Too small, z-gas **/
4095 	/** Initialize the block of 'Z's **/
4096    if( block_of_ZZ_initialized == FALSE ) {
4097       for( i=0; i<SMALLEST_CHUNK_SIZE; i++ )
4098          block_of_ZZ[ i ] = 'z' ;
4099       block_of_ZZ_initialized = TRUE ;
4100       } /* end if */
4101 
4102 assert(block_offset->offset <= 0x1fff);
4103       ADFI_write_file( file_index, block_offset->block, block_offset->offset,
4104 	number_of_bytes, block_of_ZZ, error_return ) ;
4105       if( *error_return != NO_ERROR )
4106         return ;
4107    } /* end if */
4108 else {	/** Add this chunk to the free table **/
4109 	/** Get the free-chunk-table **/
4110    ADFI_read_free_chunk_table( file_index, &free_chunk_table, error_return ) ;
4111    if( *error_return != NO_ERROR )
4112       return ;
4113 
4114    if( block_offset->block == end_of_chunk_tag.block ) { /* small or medium */
4115       if( (end_of_chunk_tag.offset + TAG_SIZE - block_offset->offset) <=
4116 		SMALL_CHUNK_MAXIMUM ) {	/** SMALL chunk **/
4117          free_chunk.end_of_chunk_tag.block = end_of_chunk_tag.block ;
4118          free_chunk.end_of_chunk_tag.offset = end_of_chunk_tag.offset ;
4119          free_chunk.next_chunk.block = free_chunk_table.small_first_block.block;
4120          free_chunk.next_chunk.offset =
4121 		free_chunk_table.small_first_block.offset ;
4122 
4123          free_chunk_table.small_first_block.block = block_offset->block ;
4124          free_chunk_table.small_first_block.offset = block_offset->offset ;
4125 
4126 	/** If linked-list was empty, also point to this as the last. **/
4127          if( free_chunk.next_chunk.offset == BLANK_BLOCK_OFFSET ) {
4128             free_chunk_table.small_last_block.block = block_offset->block ;
4129             free_chunk_table.small_last_block.offset = block_offset->offset ;
4130 	    } /* end if */
4131          } /* end if */
4132       else {				/** MEDIUM chunk **/
4133          free_chunk.end_of_chunk_tag.block = end_of_chunk_tag.block ;
4134          free_chunk.end_of_chunk_tag.offset = end_of_chunk_tag.offset ;
4135          free_chunk.next_chunk.block =
4136 		free_chunk_table.medium_first_block.block ;
4137          free_chunk.next_chunk.offset =
4138 		free_chunk_table.medium_first_block.offset;
4139 
4140          free_chunk_table.medium_first_block.block = block_offset->block ;
4141          free_chunk_table.medium_first_block.offset = block_offset->offset ;
4142 
4143 	/** If linked-list was empty, also point to this as the last. **/
4144          if( free_chunk.next_chunk.offset == BLANK_BLOCK_OFFSET ) {
4145             free_chunk_table.medium_last_block.block = block_offset->block ;
4146             free_chunk_table.medium_last_block.offset = block_offset->offset ;
4147 	    } /* end if */
4148          } /* end else */
4149       } /* end if */
4150    else {					/** LARGE chunk **/
4151          free_chunk.end_of_chunk_tag.block = end_of_chunk_tag.block ;
4152          free_chunk.end_of_chunk_tag.offset = end_of_chunk_tag.offset ;
4153          free_chunk.next_chunk.block = free_chunk_table.large_first_block.block;
4154          free_chunk.next_chunk.offset =
4155 		free_chunk_table.large_first_block.offset ;
4156 
4157          free_chunk_table.large_first_block.block = block_offset->block ;
4158          free_chunk_table.large_first_block.offset = block_offset->offset ;
4159 
4160 	/** If linked-list was empty, also point to this as the last. **/
4161          if( free_chunk.next_chunk.offset == BLANK_BLOCK_OFFSET ) {
4162             free_chunk_table.large_last_block.block = block_offset->block ;
4163             free_chunk_table.large_last_block.offset = block_offset->offset ;
4164 	    } /* end if */
4165       } /* end else */
4166 
4167 	/** Put the free-chunk tags in place **/
4168    strncpy( free_chunk.start_tag, free_chunk_start_tag, TAG_SIZE ) ;
4169    strncpy( free_chunk.end_tag, free_chunk_end_tag, TAG_SIZE ) ;
4170 
4171 	/** Write out the free chunk **/
4172    ADFI_write_free_chunk( file_index, block_offset, &free_chunk, error_return );
4173    if( *error_return != NO_ERROR )
4174       return ;
4175 	/** Update the free-chunk-table **/
4176    ADFI_write_free_chunk_table( file_index, &free_chunk_table, error_return ) ;
4177    if( *error_return != NO_ERROR )
4178       return ;
4179    } /* end else */
4180 
4181         /** Delete the block/offset off the stack **/
4182    ADFI_stack_control(file_index, block_offset->block,
4183 	   (unsigned int)block_offset->offset, DEL_STK_ENTRY, 0, 0, NULL ) ;
4184 
4185 } /* end of ADFI_file_free */
4186 /* end of file ADFI_file_free.c */
4187 /* file ADFI_file_malloc.c */
4188 /***********************************************************************
4189 ADFI file malloc:
4190 	To allocate a chunk of disk space.
4191 
4192 input:  const int file_index		The file index (0 to MAXIMUM_FILES).
4193 input:  size_bytes			The size in bytes to allocate.
4194 output: const struct DISK_POINTER *block_offset  Block & offset in the file.
4195 output:	int *error_return		Error return.
4196 
4197    Possible errors:
4198 NO_ERROR
4199 NULL_POINTER
4200 ADF_FILE_NOT_OPENED
4201 ***********************************************************************/
4202 void	ADFI_file_malloc(
4203 		const int file_index,
4204 		const cglong_t size_bytes,
4205 		struct DISK_POINTER *block_offset,
4206 		int *error_return )
4207 {
4208 struct	FILE_HEADER		file_header ;
4209 int				memory_found = FALSE ;
4210 #if 0
4211 struct	FREE_CHUNK_TABLE	free_chunk_table ;
4212 struct	DISK_POINTER		disk_pointer, previous_disk_pointer ;
4213 struct	DISK_POINTER		*first_free_block, *last_free_block ;
4214 struct	FREE_CHUNK		free_chunk, previous_free_chunk ;
4215 int				i ;
4216 unsigned long			size ;
4217 #endif
4218 
4219 if( block_offset == NULL ) {
4220    *error_return = NULL_POINTER ;
4221    return ;
4222    } /* end if */
4223 
4224 if( file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
4225    *error_return = ADF_FILE_NOT_OPENED ;
4226    return ;
4227    } /* end if */
4228 #if 0
4229 /* skip this, and just write to end of file - this gives a significant
4230    speedup with only a small increase in file size. If the file is
4231    modified, skipping this will leave large holes in the file, but
4232    the entire file is rewritten by cg_close so we can ignore it here */
4233 	/** Get the free-chunk_table **/
4234 ADFI_read_free_chunk_table( file_index, &free_chunk_table, error_return ) ;
4235 if( *error_return != NO_ERROR )
4236    return ;
4237 
4238 	/** Look for the needed space in the 3 free lists.
4239             Note that all file control headers are smaller than
4240             the SMALLEST_CHUNK_SIZE and so will be fit later into
4241             a block at the end of the file.  This greatly improves
4242             node creation efficiency. **/
4243 for( i=0; i<3; i++ ) {
4244    if( memory_found == TRUE || size_bytes <= SMALLEST_CHUNK_SIZE )
4245       break ;
4246    ADFI_set_blank_disk_pointer( &previous_disk_pointer ) ;
4247    switch( i ) {
4248       case 0:	/** SMALL CHUNKS **/
4249 	 if( size_bytes > SMALL_CHUNK_MAXIMUM )
4250 	    continue ; /** Next in the for loop **/
4251 	 first_free_block = &free_chunk_table.small_first_block ;
4252 	 last_free_block  = &free_chunk_table.small_last_block ;
4253 	 break ;
4254       case 1:	/** MEDIUM CHUNKS **/
4255 	 if( size_bytes > MEDIUM_CHUNK_MAXIMUM )
4256 	    continue ; /** Next in the for loop **/
4257 	 first_free_block = &free_chunk_table.medium_first_block ;
4258 	 last_free_block  = &free_chunk_table.medium_last_block ;
4259 	 break ;
4260       case 2:	/** LARGE CHUNKS **/
4261 	 first_free_block = &free_chunk_table.large_first_block ;
4262 	 last_free_block  = &free_chunk_table.large_last_block ;
4263 	 break ;
4264       } /* end switch */
4265 
4266    disk_pointer = *first_free_block ;
4267    while( (memory_found != TRUE) &&
4268 	  ((disk_pointer.block != BLANK_FILE_BLOCK) ||
4269 	   (disk_pointer.offset != BLANK_BLOCK_OFFSET)) ) {
4270       ADFI_read_free_chunk( file_index, &disk_pointer, &free_chunk,
4271 		error_return ) ;
4272       if( *error_return != NO_ERROR )
4273          return ;
4274       size = (free_chunk.end_of_chunk_tag.block - disk_pointer.block) *
4275 	  	DISK_BLOCK_SIZE +
4276              (free_chunk.end_of_chunk_tag.offset - disk_pointer.offset) +
4277 		TAG_SIZE ;
4278       if( (long int) size >= size_bytes ) {
4279 	 *block_offset = disk_pointer ;
4280 	 if( (previous_disk_pointer.block != BLANK_FILE_BLOCK) ||
4281 	     (previous_disk_pointer.offset != BLANK_BLOCK_OFFSET) ) {
4282 
4283 		/** Link previous free-chunk to the next free-chunk,
4284 		    removing this free-chunk from the list
4285 		**/
4286             ADFI_read_free_chunk( file_index, &previous_disk_pointer,
4287 		&previous_free_chunk, error_return ) ;
4288             if( *error_return != NO_ERROR )
4289                return ;
4290 	    previous_free_chunk.next_chunk = free_chunk.next_chunk ;
4291             ADFI_write_free_chunk( file_index, &previous_disk_pointer,
4292 		&previous_free_chunk, error_return ) ;
4293             if( *error_return != NO_ERROR )
4294                return ;
4295 	    } /* end if */
4296 	 else {
4297 
4298   /** Free-chunk was the first one, change entry in the free-chunk-header **/
4299 	    *first_free_block = free_chunk.next_chunk ;
4300 	    ADFI_write_free_chunk_table( file_index, &free_chunk_table,
4301 			error_return ) ;
4302 	    if( *error_return != NO_ERROR )
4303 	       return ;
4304 	    } /* end else */
4305 
4306 	 if((last_free_block->block == disk_pointer.block) &&
4307 	    (last_free_block->offset == disk_pointer.offset)){
4308 	    if( (previous_disk_pointer.block != BLANK_FILE_BLOCK) ||
4309 	        (previous_disk_pointer.offset != BLANK_BLOCK_OFFSET) ) {
4310 	       *last_free_block = previous_disk_pointer ;
4311 	       } /* end if */
4312 	    else {
4313 	       ADFI_set_blank_disk_pointer( last_free_block ) ;
4314 	       } /* end else */
4315 	    ADFI_write_free_chunk_table( file_index, &free_chunk_table,
4316 			error_return ) ;
4317 	    if( *error_return != NO_ERROR )
4318 	       return ;
4319 	    } /* end if */
4320 
4321 	 size -= size_bytes ;
4322 	 if ( size > 0 ) {
4323 	    disk_pointer.offset += size_bytes ;
4324 	    ADFI_adjust_disk_pointer( &disk_pointer, error_return ) ;
4325 	    if( *error_return != NO_ERROR )
4326 	       return ;
4327 	    ADFI_file_free( file_index, &disk_pointer, size, error_return ) ;
4328 	    if( *error_return != NO_ERROR )
4329 	       return ;
4330 	    }
4331 	 memory_found = TRUE ;
4332 	 } /* end if */
4333       else {
4334 	 previous_disk_pointer = disk_pointer ;
4335 	 disk_pointer = free_chunk.next_chunk ;
4336 	 } /* end else */
4337       } /* end while */
4338    } /* end if */
4339 #endif
4340 	/** The end-of_file pointer points to the last byte USED,
4341 	    NOT the next byte TO USE.
4342 	**/
4343 if( memory_found != TRUE ) { /* Append memory at end of file **/
4344    ADFI_read_file_header( file_index, &file_header, error_return ) ;
4345    if( *error_return != NO_ERROR )
4346       return ;
4347 	/** If the end-of_file is NOT at a block boundary, then
4348 	see if the new allocated chunk will span a block boundary.
4349 	If it will, then start at the new block if it will fit within
4350 	the block. This helps efficiency to have file control headers
4351         located within a block boundary.
4352 	**/
4353    if( file_header.end_of_file.offset != DISK_BLOCK_SIZE - 1 ) {
4354       if( (file_header.end_of_file.offset+size_bytes) >= DISK_BLOCK_SIZE  &&
4355 	  size_bytes <= DISK_BLOCK_SIZE ) {
4356 		/** Free rest of block, allocate from next block **/
4357          file_header.end_of_file.offset++ ;
4358 	 ADFI_file_free( file_index, &file_header.end_of_file,
4359 	     DISK_BLOCK_SIZE - file_header.end_of_file.offset, error_return ) ;
4360 	 if( *error_return != NO_ERROR )
4361 	    return ;
4362          block_offset->block = file_header.end_of_file.block + 1 ;
4363          block_offset->offset = 0 ;
4364          file_header.end_of_file.block++ ;
4365          file_header.end_of_file.offset = size_bytes - 1 ;
4366 	 ADFI_adjust_disk_pointer( &file_header.end_of_file, error_return ) ;
4367 	 if( *error_return != NO_ERROR )
4368 	    return ;
4369 
4370 	 } /* end if */
4371       else {	/** Use the remaining block **/
4372          block_offset->block = file_header.end_of_file.block ;
4373          block_offset->offset = file_header.end_of_file.offset + 1 ;
4374          file_header.end_of_file.offset += size_bytes ;
4375 	 ADFI_adjust_disk_pointer( &file_header.end_of_file, error_return ) ;
4376 	 if( *error_return != NO_ERROR )
4377 	    return ;
4378 	 } /* end else */
4379       } /* end if */
4380    else { /* already pointing to start of block **/
4381       block_offset->block = file_header.end_of_file.block + 1 ;
4382       block_offset->offset = 0 ;
4383       file_header.end_of_file.block++ ;
4384       file_header.end_of_file.offset = size_bytes - 1 ;
4385       ADFI_adjust_disk_pointer( &file_header.end_of_file, error_return ) ;
4386       if( *error_return != NO_ERROR )
4387             return ;
4388       } /* end else */
4389 
4390 
4391 	/** Write out the modified file header **/
4392    ADFI_write_file_header( file_index, &file_header, error_return ) ;
4393    if( *error_return != NO_ERROR )
4394       return ;
4395    } /* end if */
4396 
4397 } /* end of ADFI_file_malloc */
4398 /* end of file ADFI_file_malloc.c */
4399 /* file ADFI_fill_initial_file_header.c */
4400 /***********************************************************************
4401 ADFI fill initial file header:
4402 	To determine the file header information...
4403 
4404 input:  const char format		'B', 'L', 'C', 'N'
4405 input:  const char os_size		'B', 'L'
4406 input:  const char *what_string		UNIX "what" identifier.
4407 output: struct FILE_HEADER *file_header	The resulting file header information.
4408 output:	int *error_return		Error return.
4409 
4410    Possible errors:
4411 NO_ERROR
4412 NULL_POINTER
4413 NULL_STRING_POINTER
4414 ADF_FILE_FORMAT_NOT_RECOGNIZED
4415 ***********************************************************************/
4416 void    ADFI_fill_initial_file_header(
4417         const char format,
4418         const char os_size,
4419         const char *what_string,
4420         struct FILE_HEADER *file_header,
4421         int *error_return )
4422 {
4423 int i ;
4424 
4425 if( what_string == NULL ) {
4426    *error_return = NULL_STRING_POINTER ;
4427    return ;
4428    } /* end if */
4429 
4430 if( file_header == NULL ) {
4431    *error_return = NULL_POINTER ;
4432    return ;
4433    } /* end if */
4434 
4435 if( (format != IEEE_BIG_FORMAT_CHAR) && (format != IEEE_LITTLE_FORMAT_CHAR) &&
4436     (format != CRAY_FORMAT_CHAR) && (format != NATIVE_FORMAT_CHAR) ) {
4437    *error_return = ADF_FILE_FORMAT_NOT_RECOGNIZED ;
4438    return ;
4439    } /* end if */
4440 
4441  /** Put the boundary tags in first.  If we then overwrite them, we'll know **/
4442 strncpy( file_header->tag0, file_header_tags[0], TAG_SIZE ) ;
4443 strncpy( file_header->tag1, file_header_tags[1], TAG_SIZE ) ;
4444 strncpy( file_header->tag2, file_header_tags[2], TAG_SIZE ) ;
4445 strncpy( file_header->tag3, file_header_tags[3], TAG_SIZE ) ;
4446 strncpy( file_header->tag4, file_header_tags[4], TAG_SIZE ) ;
4447 strncpy( file_header->tag5, file_header_tags[5], TAG_SIZE ) ;
4448 
4449 	/** The UNIX "what" string" - blank terminated **/
4450 strncpy( file_header->what, what_string, WHAT_STRING_SIZE ) ;
4451 if ( strlen(what_string) < WHAT_STRING_SIZE )
4452 {
4453    ADFI_blank_fill_string ( file_header->what, WHAT_STRING_SIZE ) ;
4454 }
4455 
4456 	/** File creation date/time - blank terminated **/
4457 ADFI_get_current_date( file_header->creation_date ) ;
4458 
4459 	/** File modification date/time - same as creation time **/
4460 strncpy( file_header->modification_date, file_header->creation_date,
4461          DATE_TIME_SIZE ) ;
4462 
4463 file_header->numeric_format = format ;
4464 file_header->os_size = os_size ;
4465 
4466 	/** Set sizeof() information for file data **/
4467 if( (format==ADF_this_machine_format && os_size==ADF_this_machine_os_size) ||
4468      format==NATIVE_FORMAT_CHAR )
4469 {
4470   file_header->sizeof_char =	 sizeof( char ) ;
4471   file_header->sizeof_short =	 sizeof( short ) ;
4472   file_header->sizeof_int =	 sizeof( int ) ;
4473 #if 0
4474   file_header->sizeof_long =	 sizeof( long ) ;
4475 #else
4476   file_header->sizeof_long =	 sizeof( cglong_t ) ;
4477 #endif
4478   file_header->sizeof_float =	 sizeof( float ) ;
4479   file_header->sizeof_double =	 sizeof( double ) ;
4480   file_header->sizeof_char_p =	 sizeof( char * ) ;
4481   file_header->sizeof_short_p =	 sizeof( short * ) ;
4482   file_header->sizeof_int_p =	 sizeof( int * ) ;
4483 #if 0
4484   file_header->sizeof_long_p =	 sizeof( long * ) ;
4485 #else
4486   file_header->sizeof_long_p =	 sizeof( cglong_t * ) ;
4487 #endif
4488   file_header->sizeof_float_p =	 sizeof( float * ) ;
4489   file_header->sizeof_double_p = sizeof( double * ) ;
4490 } /** end if **/
4491 else
4492 {
4493   switch( EVAL_2_BYTES( format, os_size ) ) {
4494     case EVAL_2_BYTES( 'B', 'L' ):
4495       i = IEEE_BIG_32_FORMAT - 1 ;
4496       break ;
4497     case EVAL_2_BYTES( 'L', 'L' ):
4498       i = IEEE_LITTLE_32_FORMAT - 1 ;
4499       break ;
4500     case EVAL_2_BYTES( 'B', 'B' ):
4501       i = IEEE_BIG_64_FORMAT - 1 ;
4502       break ;
4503     case EVAL_2_BYTES( 'L', 'B' ):
4504       i = IEEE_LITTLE_64_FORMAT - 1 ;
4505       break ;
4506     case EVAL_2_BYTES( 'C', 'B' ):
4507       i = CRAY_FORMAT - 1 ;
4508       break ;
4509     default:
4510       *error_return = MACHINE_FORMAT_NOT_RECOGNIZED ;
4511       return ;
4512   } /* end switch */
4513 
4514   file_header->sizeof_char =	 (unsigned int)machine_sizes[i][ 0] ;
4515   file_header->sizeof_short =	 (unsigned int)machine_sizes[i][ 3] ;
4516   file_header->sizeof_int =	 (unsigned int)machine_sizes[i][ 5] ;
4517 #if 0
4518   file_header->sizeof_long =	 (unsigned int)machine_sizes[i][ 7] ;
4519 #else
4520   file_header->sizeof_long =	 (unsigned int)sizeof(cglong_t) ;
4521 #endif
4522   file_header->sizeof_float =	 (unsigned int)machine_sizes[i][ 9] ;
4523   file_header->sizeof_double =	 (unsigned int)machine_sizes[i][10] ;
4524   file_header->sizeof_char_p =	 (unsigned int)machine_sizes[i][11] ;
4525   file_header->sizeof_short_p =	 (unsigned int)machine_sizes[i][12] ;
4526   file_header->sizeof_int_p =	 (unsigned int)machine_sizes[i][12] ;
4527 #if 0
4528   file_header->sizeof_long_p =	 (unsigned int)machine_sizes[i][13] ;
4529 #else
4530   file_header->sizeof_long_p =	 (unsigned int)sizeof(cglong_t *) ;
4531 #endif
4532   file_header->sizeof_float_p =	 (unsigned int)machine_sizes[i][14] ;
4533   file_header->sizeof_double_p = (unsigned int)machine_sizes[i][15] ;
4534 } /** end else **/
4535 
4536 	/** Set root node table pointers **/
4537 file_header->root_node.block = ROOT_NODE_BLOCK ;
4538 file_header->root_node.offset = ROOT_NODE_OFFSET ;
4539 file_header->end_of_file.block = ROOT_NODE_BLOCK ;
4540 file_header->end_of_file.offset = ROOT_NODE_OFFSET + NODE_HEADER_SIZE - 1 ;
4541 file_header->free_chunks.block = FREE_CHUNKS_BLOCK ;
4542 file_header->free_chunks.offset = FREE_CHUNKS_OFFSET ;
4543 ADFI_set_blank_disk_pointer( &file_header->extra ) ;
4544 
4545 } /* end of ADFI_fill_initial_file_header */
4546 /* end of file ADFI_fill_initial_file_header.c */
4547 /* file ADFI_fill_initial_free_chunk_table.c */
4548 /***********************************************************************
4549 ADFI fill initial free chunk header:
4550 	To fill out a new free chunk header.
4551 
4552 output: struct FREE_CHUNK_TABLE *free_chunk_table	Resulting header info.
4553 output:	int *error_return		Error return.
4554 
4555    Possible errors:
4556 NO_ERROR
4557 NULL_POINTER
4558 ***********************************************************************/
4559 void	ADFI_fill_initial_free_chunk_table(
4560 		struct FREE_CHUNK_TABLE *free_chunk_table,
4561 		int *error_return )
4562 {
4563 
4564 if( free_chunk_table == NULL ) {
4565    *error_return = NULL_POINTER ;
4566    return ;
4567    } /* end if */
4568 
4569 strncpy( free_chunk_table->start_tag, free_chunk_table_start_tag,  TAG_SIZE ) ;
4570 strncpy( free_chunk_table->end_tag,   free_chunk_table_end_tag,    TAG_SIZE ) ;
4571 
4572 	/** Small:  First and Last Blocks **/
4573 ADFI_set_blank_disk_pointer( &free_chunk_table->small_first_block ) ;
4574 ADFI_set_blank_disk_pointer( &free_chunk_table->small_last_block ) ;
4575 
4576 	/** Medium:  First and Last Blocks **/
4577 ADFI_set_blank_disk_pointer( &free_chunk_table->medium_first_block ) ;
4578 ADFI_set_blank_disk_pointer( &free_chunk_table->medium_last_block ) ;
4579 
4580 	/** large:  First and Last Blocks **/
4581 ADFI_set_blank_disk_pointer( &free_chunk_table->large_first_block ) ;
4582 ADFI_set_blank_disk_pointer( &free_chunk_table->large_last_block ) ;
4583 } /* end of ADFI_fill_initial_free_chunk_table */
4584 /* end of file ADFI_fill_initial_free_chunk_table.c */
4585 /* file ADFI_fill_initial_node_header.c */
4586 /***********************************************************************
4587 ADFI fill initial node header:
4588 	To fill out a new node header.
4589 
4590 output: struct NODE_HEADER *node_header	The resulting node header information.
4591 output:	int *error_return		Error return.
4592 
4593    Possible errors:
4594 NO_ERROR
4595 NULL_POINTER
4596 ***********************************************************************/
4597 void	ADFI_fill_initial_node_header(
4598 		struct NODE_HEADER *node_header,
4599 		int *error_return )
4600 {
4601 int	i ;
4602 
4603 if( node_header == NULL ) {
4604    *error_return = NULL_POINTER ;
4605    return ;
4606    } /* end if */
4607 
4608 strncpy( node_header->node_start_tag, node_start_tag,  TAG_SIZE ) ;
4609 strncpy( node_header->node_end_tag,   node_end_tag,    TAG_SIZE ) ;
4610 
4611 	/** Blank out the name **/
4612 for( i=0; i<ADF_NAME_LENGTH; i++ )
4613    node_header->name[i] = ' ' ;
4614 
4615 	/** Blank out the label **/
4616 for( i=0; i<ADF_LABEL_LENGTH; i++ )
4617    node_header->label[i] = ' ' ;
4618 
4619 	/** Set number of sub nodes to zero **/
4620 node_header->num_sub_nodes = 0 ;
4621 node_header->entries_for_sub_nodes = 0 ;
4622 ADFI_set_blank_disk_pointer( &node_header->sub_node_table ) ;
4623 
4624 	/** Blank out the Data-Type, then set to eMpTy. **/
4625 for( i=2; i<ADF_DATA_TYPE_LENGTH; i++ )
4626    node_header->data_type[i] = ' ' ;
4627 node_header->data_type[0] = 'M' ;
4628 node_header->data_type[1] = 'T' ;
4629 
4630 
4631 	/** Zero out number of dimensions & Set dimension values to zero **/
4632 node_header->number_of_dimensions = 0 ;
4633 for( i=0; i<ADF_MAX_DIMENSIONS; i++ )
4634    node_header->dimension_values[i] = 0 ;
4635 
4636 	/** Set number of data chunks to zero, zero out data chunk pointer **/
4637 node_header->number_of_data_chunks = 0 ;
4638 ADFI_set_blank_disk_pointer( &node_header->data_chunks ) ;
4639 } /* end of ADFI_fill_initial_node_header */
4640 /* end of file ADFI_fill_initial_node_header.c */
4641 /* file ADFI_flush_buffers.c */
4642 /***********************************************************************
4643 ADFI Flush buffers:
4644 
4645 input:  const unsigned int file_index	The file index.
4646 output:	int *error_return		Error return.
4647 
4648    Possible errors:
4649 NO_ERROR
4650 ADF_FILE_NOT_OPENED
4651 FWRITE_ERROR
4652 ***********************************************************************/
4653 void    ADFI_flush_buffers(
4654 	        const unsigned int file_index,
4655 		int flush_mode,
4656 		int *error_return )
4657 {
4658 char data;
4659 
4660 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
4661    *error_return = ADF_FILE_NOT_OPENED ;
4662    return ;
4663 } /* end if */
4664 
4665 *error_return = NO_ERROR ;
4666 
4667 if ( (int)file_index == last_wr_file ) {
4668       /** Flush any active write buffer, file block is set to a nonsense
4669           value so that the buffer flags are not reset **/
4670   ADFI_write_file ( file_index, MAXIMUM_32_BITS, 0, 0, &data, error_return ) ;
4671       /** Reset control flags **/
4672   if ( flush_mode == FLUSH_CLOSE ) {
4673     last_wr_block  = -2;
4674     last_wr_file   = -2;
4675     flush_wr_block = -2 ;
4676   }
4677 }
4678 
4679 if ( (int) file_index == last_rd_file && flush_mode == FLUSH_CLOSE ) {
4680       /** Reset control flags **/
4681   last_rd_block   = -1;
4682   last_rd_file    = -1;
4683   num_in_rd_block = -1;
4684 }
4685 
4686 } /* end of ADFI_flush_buffers */
4687 /* end of file ADFI_flush_buffers.c */
4688 /* file ADFI_fseek_file.c */
4689 /***********************************************************************
4690 ADFI_fseek_file:
4691 	To position the current position for fread() or fwrite().
4692 	Need to allow for files larger than what a long int can
4693 	represent (the offset for fseek).
4694 
4695 input:	const unsigned int file_index	File to use.
4696 input:	const unsigned long file_block	Block within the file.
4697 input:	const unsigned long block_offset Offset within the block.
4698 output:	int *error_return		Error return.
4699 
4700    Possible errors:
4701 NO_ERROR
4702 ADF_FILE_NOT_OPENED
4703 FSEEK_ERROR
4704 ***********************************************************************/
4705 void	ADFI_fseek_file(
4706 		const unsigned int file_index,
4707 		const cgulong_t file_block,
4708 		const cgulong_t block_offset,
4709 		int *error_return )
4710 {
4711 file_offset_t offset;
4712 file_offset_t iret;
4713 
4714 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
4715    *error_return = ADF_FILE_NOT_OPENED ;
4716    return ;
4717    } /* end if */
4718 
4719 offset = (file_offset_t)(file_block * DISK_BLOCK_SIZE + block_offset) ;
4720 if (offset < 0) {
4721    *error_return = MAX_FILE_SIZE_EXCEEDED;
4722    return;
4723 }
4724 
4725 *error_return = NO_ERROR ;
4726 
4727 ADF_sys_err = 0;
4728 iret = file_seek( ADF_file[file_index].file, offset, SEEK_SET ) ;
4729 if( iret < 0 ) {
4730    ADF_sys_err = errno;
4731    *error_return = FSEEK_ERROR ;
4732    } /* end if */
4733 } /* end of ADFI_fseek_file */
4734 /* end of file ADFI_fseek_file.c */
4735 /* file ADFI_get_current_date.c */
4736 /***********************************************************************
4737 ADFI get current date:
4738     Returns the current date and time in a blank-filled character array.
4739 
4740 output:	char  date[]        Current date/time in an array blank-filled
4741                             to DATE_TIME_SIZE.  Array must be allocated
4742                             to at least DATE_TIME_SIZE.  No null added.
4743 
4744 ***********************************************************************/
4745 void	ADFI_get_current_date(
4746         char  date[] )
4747 {
4748 time_t  ct ;
4749 int	    i_len ;
4750 char    *current_time_p ;
4751 
4752 
4753      /** get the current time **/
4754 ct = time( (time_t *)NULL ) ;
4755 current_time_p = ctime( &ct ) ;
4756 
4757      /** remove '\n' from ctime format **/
4758 i_len = (int)strcspn ( current_time_p, "\n" ) ;
4759 strcpy( date, current_time_p ) ;
4760 date[i_len] = '\0' ;
4761 
4762      /** blank fill **/
4763 ADFI_blank_fill_string ( date, DATE_TIME_SIZE ) ;
4764 
4765 } /* end of ADFI_get_current_date */
4766 /* end of file ADFI_get_current_date.c */
4767 /* file ADFI_get_direct_children_ids.c */
4768 /***********************************************************************
4769 ADFI get direct children ids:
4770 
4771 Get Children ids of a Node.  Return the ids of children nodes directly
4772 associated with a parent node (no links are followed).  The ids of the
4773 children are NOT guaranteed to be returned in any particular order.
4774 If it is desired to follow potential links for the node ID, then
4775 call ADFI_chase_link() and pass the resultant link ID to this function.
4776 NOTE:  link nodes do not have direct children.
4777 
4778 
4779 ADFI_get_direct_children_ids( ID, num_ids, ids, error_return )
4780 input:  const unsigned int file_index     The file index.
4781 input:  const struct DISK_POINTER *node_block_offset   Block & offset in file.
4782 output: int *num_ids        The number of ids returned.
4783 output: double **ids        An allocated array of ids (free this space).
4784 output: int *error_return   Error return.
4785 
4786    Possible errors:
4787 NO_ERROR
4788 NULL_POINTER
4789 MEMORY_ALLOCATION_FAILED
4790 FILE_INDEX_OUT_OF_RANGE
4791 BLOCK_OFFSET_OUT_OF_RANGE
4792 ADF_FILE_NOT_OPENED
4793 ADF_DISK_TAG_ERROR
4794 ADF_MEMORY_TAG_ERROR
4795 ***********************************************************************/
4796 void    ADFI_get_direct_children_ids(
4797         const unsigned int  file_index,
4798         const struct DISK_POINTER *node_block_offset,
4799         int *num_ids,
4800         double **ids,
4801         int *error_return )
4802 {
4803 int                     i ;
4804 struct DISK_POINTER     sub_node_block_offset ;
4805 struct NODE_HEADER      node ;
4806 struct SUB_NODE_TABLE_ENTRY	sub_node_table_entry ;
4807 
4808 *error_return = NO_ERROR ;
4809 
4810 if( num_ids == NULL || ids == NULL ) {
4811    *error_return = NULL_POINTER ;
4812    return ;
4813    } /* end if */
4814 
4815 *num_ids = 0 ;
4816 *ids = NULL ;
4817 
4818 ADFI_read_node_header( file_index, node_block_offset, &node, error_return ) ;
4819 if( *error_return != NO_ERROR )
4820    return ;
4821 
4822 	/** Check for zero children, return if 0 **/
4823 if( node.num_sub_nodes == 0 ) {
4824    return ;
4825    } /* end if */
4826 
4827 *ids = (double *) malloc ( node.num_sub_nodes * sizeof(double) ) ;
4828 if( *ids == NULL ) {
4829    *error_return = MEMORY_ALLOCATION_FAILED ;
4830    return ;
4831    } /* end if */
4832 
4833     /** point to the first child **/
4834 sub_node_block_offset.block  = node.sub_node_table.block ;
4835 sub_node_block_offset.offset = node.sub_node_table.offset +
4836     (TAG_SIZE + DISK_POINTER_SIZE ) ;
4837 
4838     /** Return the ids for all the children **/
4839 *num_ids = node.num_sub_nodes ;
4840 for( i=0; i< *num_ids; i++ ) {
4841    ADFI_adjust_disk_pointer( &sub_node_block_offset, error_return ) ;
4842    if( *error_return != NO_ERROR )
4843       return ;
4844 
4845     /** Read one sub-node table entry **/
4846    ADFI_read_sub_node_table_entry( file_index, &sub_node_block_offset,
4847                 &sub_node_table_entry, error_return ) ;
4848    if( *error_return != NO_ERROR )
4849       return ;
4850 
4851     /** Get the ID from the sub-node table **/
4852    ADFI_file_block_offset_2_ID( file_index,
4853                 sub_node_table_entry.child_location.block,
4854                 sub_node_table_entry.child_location.offset, &(*ids)[i],
4855                 error_return ) ;
4856    if( *error_return != NO_ERROR )
4857       return ;
4858 
4859     /** Increment the disk-pointer **/
4860    sub_node_block_offset.offset += (ADF_NAME_LENGTH + DISK_POINTER_SIZE) ;
4861    } /* end for */
4862 }
4863 /* end of file ADFI_get_direct_children_ids.c */
4864 /* file ADFI_get_file_index_from_name.c */
4865 /***********************************************************************
4866 ADFI get file index from name:
4867 
4868 Searches file list for given name.  Returns file index and Root ID
4869 if name is found in list.
4870 
4871 input:  const char *file_name     Name of file
4872 output: int *found                1 = name found, 0 = not found
4873 output: unsigned int *file_index  File-index
4874 output: double *ID                ID of files root node
4875 output: int  *error_return        Error return
4876 ***********************************************************************/
4877 void    ADFI_get_file_index_from_name(
4878         const char *file_name,
4879         int  *found,
4880         unsigned int *file_index,
4881         double *ID,
4882         int *error_return )
4883 {
4884 double     root_ID = 0;
4885 int        i ;
4886 
4887 
4888 *error_return = NO_ERROR ;
4889 
4890 if( (file_index == NULL) || (ID == NULL) || (found == NULL) ) {
4891    *error_return = NULL_POINTER ;
4892    return ;
4893    } /* end if */
4894 
4895 if( file_name == NULL ) {
4896    *error_return = NULL_STRING_POINTER ;
4897    return ;
4898    } /* end if */
4899 
4900 *found = 0;
4901 for( i=0; i<maximum_files; i++ ) {
4902    if( ADF_file[i].in_use && ADF_file[i].file_name != NULL ) {
4903       if( strcmp( file_name, ADF_file[i].file_name ) == 0 ) {
4904            /** A Match!!! **/
4905          ADFI_file_block_offset_2_ID( i, ROOT_NODE_BLOCK, ROOT_NODE_OFFSET,
4906                                       &root_ID, error_return ) ;
4907          *ID = root_ID ;
4908          *file_index = i ;
4909          *found = 1 ;
4910          return ; /* done */
4911          } /* end if */
4912       } /* end if */
4913    } /* end for */
4914 } /* end of ADFI_get_file_index_from_name */
4915 /* end of file ADFI_get_file_index_from_name.c */
4916 /* file ADFI_increment_array.c */
4917 /***********************************************************************
4918 ADFI increment array:
4919 
4920 input:  const unsigned int ndim	The number of dimensions to use (1 to 12)
4921 input:  const unsigned int dims[]The dimensional space
4922 input:  const int dim_start[]	The starting dimension of our sub-space
4923 				first = 1
4924 input:  const int dim_end[]	The ending dimension of our sub-space
4925 				last[n] = dims[n]
4926 input:  const int dim_stride[]	The stride to take in our sub-space
4927 				(every Nth element)
4928 in/out: int current_position	The position in the N-D space.
4929 output: ulong *element_offset	Number of elements to jump to next (1 to N)
4930 output: int *error_return	Error return.
4931 
4932 possible errors: Note:  Extensive error check is NOT done...
4933 NO_ERROR
4934 NULL_POINTER
4935 BAD_NUMBER_OF_DIMENSIONS
4936 ***********************************************************************/
4937 void	ADFI_increment_array(
4938 		const unsigned int ndim,
4939 		const cgulong_t dims[],
4940 		const cgsize_t dim_start[],
4941 		const cgsize_t dim_end[],
4942 		const cgsize_t dim_stride[],
4943 		cglong_t current_position[],
4944 		cgulong_t *element_offset,
4945 		int *error_return )
4946 {
4947 unsigned int	i ;
4948 cgulong_t   offset, accumlated_size ;
4949 
4950 if( (dims == NULL) || (dim_start == NULL) || (dim_end == NULL) ||
4951     (dim_stride == NULL) || (current_position == NULL) ||
4952     (element_offset == NULL) ) {
4953    *error_return = NULL_POINTER ;
4954    return ;
4955    } /* end if */
4956 
4957 if( (ndim <= 0) || (ndim > 12) ) {
4958    *error_return = BAD_NUMBER_OF_DIMENSIONS ;
4959    return ;
4960    } /* end if */
4961 
4962 *error_return = NO_ERROR ;
4963 
4964 offset = 0 ;
4965 accumlated_size = 1 ;
4966 for( i=0; i<ndim; i++ ) {
4967    if( current_position[i] + dim_stride[i] <= dim_end[i] ) {
4968       current_position[i] += dim_stride[i] ;
4969       offset += 1 + (dim_stride[i] - 1) * accumlated_size ;
4970       break ;
4971       } /* end if */
4972    else {
4973 /* fix from Stephen Guzik - multiply by accumlated_size */
4974       offset += (dims[i] - current_position[i] + dim_start[i] - 1) *
4975                 accumlated_size ;
4976 	/** The -1 above is to let the next loop add its stride **/
4977       current_position[i] = dim_start[i] ;
4978       accumlated_size *= dims[i] ;
4979       } /* end else */
4980    } /* end for */
4981 *element_offset = offset ;
4982 
4983 } /* end of ADFI_increment_array */
4984 /* end of file ADFI_increment_array.c */
4985 /* file ADFI_is_block_in_core.c */
4986 /***********************************************************************
4987 ADFI is block in core:
4988 
4989    Possible errors:
4990 NO_ERROR
4991 ***********************************************************************/
4992 void	ADFI_is_block_in_core()
4993 {
4994 fprintf(stderr,"Subroutine ADFI_is_block_in_core is not yet implemented...\n" ) ;
4995 }
4996 /* end of file ADFI_is_block_in_core.c */
4997 /* file ADFI_little_endian_32_swap_64.c */
4998 /***********************************************************************
4999 ADFI little endian 32 swap 64:
5000 
5001 input:  const char from_format		Format to convert from. 'B','L','C','N'
5002 input:  const char from_os_size		Format to convert from. 'B','L'
5003 input:  const char to_format		Format to convert to.
5004 input:  const char to_os_size		Format to convert to. 'B','L'
5005 input:  const char data_type[2]		The type of data to convert.
5006 					   MT I4 I8 U4 U8 R4 R8 X4 X8 C1 B1
5007 input:  const unsigned long delta_from_bytes Number of from_bytes used.
5008 input:  const unsigned long delta_to_bytes	Number of to_bytes used.
5009 input:  const char *from_data		The data to convert from.
5010 output: char *to_data			The resulting data.
5011 output:	int *error_return		Error return.
5012 
5013   Recognized data types:
5014 					Machine representations
5015         Type		  Notation     IEEE_BIG	  IEEE_LITTLE   Cray
5016 	                               32    64   32    64
5017   No data                   MT
5018   Integer 32                I4         I4    I4    I4   I4       I8
5019   Integer 64                I8         --    I8    --   I8       I8
5020   Unsigned 32               U4         I4    I4    I4   I4       I8
5021   Unsigned 64               U8         --    I8    --   I8       I8
5022   Real 32                   R4         R4    R4    R4   R4       R8
5023   Real 64                   R8         R8    R8    R8   R8       R8
5024   Complex 64                X4         R4R4  R4R4  R4R4 R4R4     R8R8
5025   Complex 128               X8         R8R8  R8R8  R8R8 R8R8     R8R8
5026   Character (unsigned byte) C1         C1    C1    C1   C1       C1
5027   Byte (unsigned byte)      B1         C1    C1    C1   C1       C1
5028 
5029 Machine Numeric Formats:
5030 ***IEEE_BIG (SGI-Iris Assembly Language Programmer's Guide, pages 1-2, 6-3)
5031 I4:	Byte0	Byte1	Byte2	Byte3
5032 	 MSB---------------------LSB
5033 R4:	Byte0	Byte1	Byte2	Byte3
5034     Bits: sign-bit, 8-bit exponent, 23-bit mantissa
5035     The sign of the exponent is:  1=positive, 0=negative (NOT 2's complement)
5036     The interpretation of the floating-point number is:
5037 	>>> 2.mantissia(fraction) X 2^exponent. <<<
5038 
5039 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
5040     Bits: sign-bit, 11-bit exponent, 52-bit mantissa
5041 
5042 Machine Numeric Formats:
5043 ***IEEE_LITTLE ( The backwards Big Endian )
5044 I4:	Byte0	Byte1	Byte2	Byte3
5045 	 LSB---------------------MSB
5046 R4:	Byte0	Byte1	Byte2	Byte3
5047     Bits: 23-bit mantissa, 8-bit exponent, sign-bit
5048     The sign of the exponent is:  1=positive, 0=negative (NOT 2's complement)
5049     The interpretation of the floating-point number is:
5050 	>>> 2.mantissia(fraction) X 2^exponent. <<<
5051 
5052 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
5053     Bits:  52-bit mantissa, 11-bit exponent, sign-bit
5054 
5055 Note: To convert between these two formats the order of the bytes is reversed
5056 since by definition the Big endian starts at the LSB and goes to the MSB where
5057 the little goes form the MSB to the LSB of the word.
5058 ***
5059 
5060    Possible errors:
5061 NO_ERROR
5062 NULL_STRING_POINTER
5063 NULL_POINTER
5064 ***********************************************************************/
5065 void    ADFI_little_endian_32_swap_64(
5066 		const char from_format,
5067 		const char from_os_size,
5068 		const char to_format,
5069 		const char to_os_size,
5070 		const char data_type[2],
5071 		const cgulong_t delta_from_bytes,
5072 		const cgulong_t delta_to_bytes,
5073 		const unsigned char *from_data,
5074 		unsigned char *to_data,
5075 		int *error_return )
5076 {
5077 
5078 if( (from_data == NULL) || (to_data == NULL) ) {
5079    *error_return = NULL_STRING_POINTER ;
5080    return ;
5081    } /* end if */
5082 
5083 if( (delta_from_bytes == 0) || (delta_to_bytes == 0) ) {
5084    *error_return = NULL_POINTER ;
5085    return ;
5086    } /* end if */
5087 
5088 if( (from_format == 'N') || (to_format == 'N') ) {
5089    *error_return = CANNOT_CONVERT_NATIVE_FORMAT ;
5090    return ;
5091    } /* end if */
5092 
5093 *error_return = NO_ERROR ;
5094 
5095 if ( delta_to_bytes == delta_from_bytes ) {
5096   memcpy( to_data, from_data, (size_t)delta_from_bytes ) ;
5097   } /* end if */
5098 else if ( delta_from_bytes < delta_to_bytes ) {
5099   switch( EVAL_2_BYTES( data_type[0], data_type[1] ) ) {
5100     case EVAL_2_BYTES( 'I', '8' ):
5101       if( (from_data[3] & 0x80) == 0x80 ) { /* Negative number */
5102          to_data[7] = 0xff ;
5103          to_data[6] = 0xff ;
5104          to_data[5] = 0xff ;
5105          to_data[4] = 0xff ;
5106       } /* end if */
5107       else {
5108          to_data[7] = 0x00 ;
5109          to_data[6] = 0x00 ;
5110          to_data[5] = 0x00 ;
5111          to_data[4] = 0x00 ;
5112       } /* end else */
5113       to_data[3] = from_data[3] ;
5114       to_data[2] = from_data[2] ;
5115       to_data[1] = from_data[1] ;
5116       to_data[0] = from_data[0] ;
5117       break ;
5118     default:
5119       *error_return = INVALID_DATA_TYPE ;
5120       return ;
5121     } /* end switch */
5122   } /* end else if */
5123 else {
5124   switch( EVAL_2_BYTES( data_type[0], data_type[1] ) ) {
5125     case EVAL_2_BYTES( 'I', '8' ):
5126       to_data[3] = from_data[3] ;
5127       to_data[2] = from_data[2] ;
5128       to_data[1] = from_data[1] ;
5129       to_data[0] = from_data[0] ;
5130       break ;
5131     default:
5132       *error_return = INVALID_DATA_TYPE ;
5133       return ;
5134     } /* end switch */
5135   } /* end else */
5136 
5137 } /* end of ADFI_little_endian_32_swap_64 */
5138 /* end of file ADFI_little_endian_32_swap_64.c */
5139 /* file ADFI_little_endian_to_cray.c */
5140 /***********************************************************************
5141 ADFI little endian to cray:
5142 
5143 input:  const char from_format		Format to convert from. 'B','L','C','N'
5144 input:  const char from_os_size		Format to convert from. 'B','L'
5145 input:  const char to_format		Format to convert to.
5146 input:  const char to_os_size		Format to convert to. 'B','L'
5147 input:  const char data_type[2]		The type of data to convert.
5148 					   MT I4 I8 U4 U8 R4 R8 X4 X8 C1 B1
5149 input:  const unsigned long delta_from_bytes Number of from_bytes used.
5150 input:  const unsigned long delta_to_bytes	Number of to_bytes used.
5151 input:  const char *from_data		The data to convert from.
5152 output: char *to_data			The resulting data.
5153 output:	int *error_return		Error return.
5154 
5155   Recognized data types:
5156 					Machine representations
5157         Type		  Notation     IEEE_BIG	  IEEE_LITTLE   Cray
5158 	                               32    64   32    64
5159   No data                   MT
5160   Integer 32                I4         I4    I4    I4   I4       I8
5161   Integer 64                I8         --    I8    --   I8       I8
5162   Unsigned 32               U4         I4    I4    I4   I4       I8
5163   Unsigned 64               U8         --    I8    --   I8       I8
5164   Real 32                   R4         R4    R4    R4   R4       R8
5165   Real 64                   R8         R8    R8    R8   R8       R8
5166   Complex 64                X4         R4R4  R4R4  R4R4 R4R4     R8R8
5167   Complex 128               X8         R8R8  R8R8  R8R8 R8R8     R8R8
5168   Character (unsigned byte) C1         C1    C1    C1   C1       C1
5169   Byte (unsigned byte)      B1         C1    C1    C1   C1       C1
5170 
5171 Machine Numeric Formats:
5172 ***IEEE_BIG (SGI-Iris Assembly Language Programmer's Guide, pages 1-2, 6-3)
5173 I4:	Byte0	Byte1	Byte2	Byte3
5174 	 MSB---------------------LSB
5175 R4:	Byte0	Byte1	Byte2	Byte3
5176     Bits: sign-bit, 8-bit exponent, 23-bit mantissa
5177     The sign of the exponent is:  1=positive, 0=negative (NOT 2's complement)
5178     The interpretation of the floating-point number is:
5179 	>>> 2.mantissia(fraction) X 2^exponent. <<<
5180 
5181 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
5182     Bits: sign-bit, 11-bit exponent, 52-bit mantissa
5183 
5184 ***Cray (Cray CFT77 Reference Manual, pages G-1 G-2)
5185 I8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
5186 	 MSB-----------------------------------------------------LSB
5187 R8:	Byte0	Byte1	Byte2	Byte 3	Byte 4	Byte5	Byte6	Byte7
5188     Bits: sign-bit, exponent-sign, 14-bit exponent, 48-bit mantissa
5189 Note: Exponent sign:  1 in this bits indicates a positive exponent sign,
5190    thus bit 62 is the inverse of bit 61 (the sign in the exponent).
5191    The exception to this is a zero, in which all 64 bits are zero!
5192     The interpretation of the floating-point number is:
5193 	>>> .mantissia(fraction) X 2^exponent. <<<
5194    The mantissia is left justified (the leftmost bit is a 1).
5195      This MUST be done!
5196 
5197 ***
5198 
5199    Possible errors:
5200 NO_ERROR
5201 NULL_STRING_POINTER
5202 NULL_POINTER
5203 ***********************************************************************/
5204 void    ADFI_little_endian_to_cray(
5205 		const char from_format,
5206 		const char from_os_size,
5207 		const char to_format,
5208 		const char to_os_size,
5209 		const char data_type[2],
5210 		const cgulong_t delta_from_bytes,
5211 		const cgulong_t delta_to_bytes,
5212 		const unsigned char *from_data,
5213 		unsigned char *to_data,
5214 		int *error_return )
5215 {
5216 int		i, exp ;
5217 
5218 if( (from_data == NULL) || (to_data == NULL) ) {
5219    *error_return = NULL_STRING_POINTER ;
5220    return ;
5221    } /* end if */
5222 
5223 if( (delta_from_bytes == 0) || (delta_to_bytes == 0) ) {
5224    *error_return = NULL_POINTER ;
5225    return ;
5226    } /* end if */
5227 
5228 if( (from_format == 'N') || (to_format == 'N') ) {
5229    *error_return = CANNOT_CONVERT_NATIVE_FORMAT ;
5230    return ;
5231    } /* end if */
5232 
5233 *error_return = NO_ERROR ;
5234 
5235 switch( EVAL_2_BYTES( data_type[0], data_type[1] ) ) {
5236 
5237    case EVAL_2_BYTES( 'M', 'T' ):
5238       *error_return = NO_DATA ;
5239       return ;
5240 
5241    case EVAL_2_BYTES( 'C', '1' ):
5242    case EVAL_2_BYTES( 'B', '1' ):
5243       to_data[0] = from_data[0] ;
5244       break ;
5245 
5246    case EVAL_2_BYTES( 'I', '4' ):
5247       if( (from_data[3] & 0x80) == 0x80 ) { /* Negative number */
5248          to_data[0] = 0xff ;
5249          to_data[1] = 0xff ;
5250          to_data[2] = 0xff ;
5251          to_data[3] = 0xff ;
5252       } /* end if */
5253       else {
5254          to_data[0] = 0x00 ;
5255          to_data[1] = 0x00 ;
5256          to_data[2] = 0x00 ;
5257          to_data[3] = 0x00 ;
5258       } /* end else */
5259       to_data[4] = from_data[3] ;
5260       to_data[5] = from_data[2] ;
5261       to_data[6] = from_data[1] ;
5262       to_data[7] = from_data[0] ;
5263       break ;
5264 
5265    case EVAL_2_BYTES( 'U', '4' ):
5266       to_data[0] = 0x00 ;
5267       to_data[1] = 0x00 ;
5268       to_data[2] = 0x00 ;
5269       to_data[3] = 0x00 ;
5270       to_data[4] = from_data[3] ;
5271       to_data[5] = from_data[2] ;
5272       to_data[6] = from_data[1] ;
5273       to_data[7] = from_data[0] ;
5274       break ;
5275 
5276    case EVAL_2_BYTES( 'I', '8' ):
5277       if( (from_data[3] & 0x80) == 0x80 ) { /* Negative number */
5278          to_data[0] = 0xff ;
5279          to_data[1] = 0xff ;
5280          to_data[2] = 0xff ;
5281          to_data[3] = 0xff ;
5282       } /* end if */
5283       else {
5284          to_data[0] = 0x00 ;
5285          to_data[1] = 0x00 ;
5286          to_data[2] = 0x00 ;
5287          to_data[3] = 0x00 ;
5288       } /* end else */
5289       for( i=0; i<(int)delta_from_bytes; i++ )
5290          to_data[8-delta_from_bytes+i] = from_data[delta_from_bytes-1-i] ;
5291       break ;
5292 
5293    case EVAL_2_BYTES( 'U', '8' ):
5294       to_data[0] = 0x00 ;
5295       to_data[1] = 0x00 ;
5296       to_data[2] = 0x00 ;
5297       to_data[3] = 0x00 ;
5298       for( i=0; i<(int)delta_from_bytes; i++ )
5299          to_data[8-delta_from_bytes+i] = from_data[delta_from_bytes-1-i] ;
5300       break ;
5301 
5302    case EVAL_2_BYTES( 'R', '4' ):
5303       for( i=0; i<8; i++ )
5304          to_data[i] = 0x00 ;
5305 
5306    /** Check for zero: a special case on the Cray (exponent sign) **/
5307       if( (from_data[3] == 0x00) && (from_data[2] == 0x00) &&
5308           (from_data[1] == 0x00) && (from_data[0] == 0x00) )
5309       break ;
5310 
5311    /** Convert the sign **/
5312       to_data[0] = from_data[3] & 0x80 ;
5313 
5314    /** Convert the exponent **/
5315    /** 8 bits to  14 bits.  Sign extent from 8 to 14 **/
5316    /** Cray exponent is 2 greater than the Iris **/
5317       exp = (from_data[3] & 0x3f) << 1 ;
5318       if( (from_data[2] & 0x80) == 0x80 )
5319          exp += 1 ;
5320       if( (from_data[3] & 0x40) == 0x00 ) /* set sign */
5321          exp -= 128 ;
5322       exp += 2 ;
5323 
5324       to_data[1] = exp & 0xff ;
5325       if( exp < 0 )
5326          to_data[0] |= 0x3f ; /* exponent sign 0, sign extend exponent */
5327       else
5328          to_data[0] |= 0x40 ; /* exponent sign 1 */
5329 
5330    /** Convert the mantissia **/
5331    /** 23 bits to 48 bits.  Left shift 25 bits, zero fill **/
5332       to_data[2] = from_data[2] | 0x80 ;
5333       to_data[3] = from_data[1] ;
5334       to_data[4] = from_data[0] ;
5335       break ;
5336 
5337    case EVAL_2_BYTES( 'R', '8' ):
5338       for( i=0; i<8; i++ )
5339          to_data[i] = 0x00 ;
5340 
5341    /** Check for zero: a special case on the Cray (exponent sign) **/
5342       if( (from_data[7] == 0x00) && (from_data[6] == 0x00) &&
5343           (from_data[5] == 0x00) && (from_data[4] == 0x00) )
5344       break ;
5345 
5346    /** Convert the sign **/
5347       to_data[0] = from_data[7] & 0x80 ;
5348 
5349    /** Convert the exponent **/
5350    /** 11 bits to  14 bits.  Sign extent from 11 to 14 **/
5351    /** Cray exponent is 2 greater than the Iris **/
5352       exp = ((from_data[7] & 0x3f) << 4) + ((from_data[6]>>4)&0x0f) ;
5353 
5354       if( (from_data[7] & 0x40) == 0x00 ) /* set sign */
5355          exp -= 1024 ;
5356       exp += 2 ;
5357 
5358       to_data[1] = (unsigned int)(exp & 0xff) ;
5359       to_data[0] |= ((exp>>8) & 0x03) ;
5360       if( exp < 0 )
5361          to_data[0] |= 0x3c ; /* exponent sign 0, sign extend exponent */
5362       else
5363          to_data[0] |= 0x40 ; /* exponent sign 1 */
5364 
5365    /** Convert the mantissia **/
5366    /** 52 bits to 48 bits.  Use 48, drop last 4 bits **/
5367       to_data[2] = 0x80 | ((from_data[6]<<3)&0x78) |
5368                           ((from_data[5]>>5)&0x07) ;
5369       for( i=3; i<8; i++ )
5370          to_data[i] = ((from_data[7-i+1]<<3)&0xF8) |
5371                       ((from_data[7-i]>>5)&0x07) ;
5372 #ifdef PRINT_STUFF
5373 printf("from:" ) ;
5374 for( i=0; i<8; i++ )
5375    printf("%02x ", from_data[i] ) ;
5376 printf("to:" ) ;
5377 for( i=0; i<8; i++ )
5378    printf("%02x ", to_data[i] ) ;
5379 printf("\n" ) ;
5380 #endif
5381       break ;
5382 
5383    case EVAL_2_BYTES( 'X', '4' ):
5384       ADFI_little_endian_to_cray( from_format, from_os_size,
5385 	 to_format, to_os_size, "R4", delta_from_bytes,
5386 	 delta_to_bytes, from_data, to_data, error_return ) ;
5387       if( *error_return != NO_ERROR )
5388          return ;
5389 
5390       ADFI_little_endian_to_cray( from_format, from_os_size,
5391 	 to_format, to_os_size, "R4", delta_from_bytes,
5392 	 delta_to_bytes, &from_data[4], &to_data[8], error_return ) ;
5393       if( *error_return != NO_ERROR )
5394          return ;
5395       break ;
5396 
5397    case EVAL_2_BYTES( 'X', '8' ):
5398       ADFI_little_endian_to_cray( from_format, from_os_size,
5399 	 to_format, to_os_size, "R8", delta_from_bytes,
5400 	 delta_to_bytes, from_data, to_data, error_return ) ;
5401       if( *error_return != NO_ERROR )
5402          return ;
5403 
5404       ADFI_little_endian_to_cray( from_format, from_os_size,
5405 	 to_format, to_os_size, "R8", delta_from_bytes,
5406 	 delta_to_bytes, &from_data[8], &to_data[8], error_return ) ;
5407       if( *error_return != NO_ERROR )
5408          return ;
5409       break ;
5410 
5411    default:
5412       *error_return = INVALID_DATA_TYPE ;
5413       return ;
5414    } /* end switch */
5415 } /* end of ADFI_little_endian_to_cray */
5416 /* end of file ADFI_little_endian_to_cray.c */
5417 /* file ADFI_open_file.c */
5418 /***********************************************************************
5419 ADFI open file:
5420 
5421     Track the files used by index.
5422     Also track which files are within a given system so a close for
5423     the system can close all related files.
5424 
5425 input:  const char *file    The filename to open.
5426 input:  const char *status  The status in which to open the file.
5427         Allowable values are:
5428                 READ_ONLY - File must exist.  Writing NOT allowed.
5429                 OLD - File must exist.  Reading and writing allowed.
5430                 NEW - File must not exist.
5431                 SCRATCH - New file.  Filename is ignored.
5432                 UNKNOWN - OLD if file exists, else NEW is used.
5433 input:  const int top_file_index  -1 if this is the top file.
5434 output: unsigned int *file_index  Returned index of the file.
5435 output: int *error_return   Error return.
5436 
5437    Possible errors:
5438 NO_ERROR
5439 NULL_POINTER
5440 NULL_STRING_POINTER
5441 TOO_MANY_ADF_FILES_OPENED
5442 ADF_FILE_STATUS_NOT_RECOGNIZED
5443 FILE_OPEN_ERROR
5444 ***********************************************************************/
5445 void    ADFI_open_file(
5446         const char *file,
5447         const char *status,
5448         unsigned int *file_index,
5449         int *error_return )
5450 {
5451 int index;
5452 int f_ret, f_mode;
5453 char header_data[102];
5454 
5455 if( (status == NULL) ||
5456     ((file == NULL) && (ADFI_stridx_c( status, "SCRATCH" ) != 0) ) ) {
5457    *error_return = NULL_STRING_POINTER ;
5458    return ;
5459 } /* end if */
5460 
5461 if( file_index == NULL ) {
5462    *error_return = NULL_POINTER ;
5463    return ;
5464 } /* end if */
5465 
5466 *error_return = NO_ERROR ;
5467 
5468 for( index=0; index<maximum_files; index++ ) {
5469    if( ADF_file[index].in_use == 0 )
5470       break ;
5471 } /* end for */
5472 
5473 if( index >= maximum_files ) {
5474    ADF_FILE *files;
5475    /* I don't use realloc, because I don't want to lose
5476       any currently open file information if it fails */
5477    files = (ADF_FILE *) calloc (maximum_files + ADF_FILE_INC, sizeof(ADF_FILE));
5478    if (files == NULL) {
5479       *error_return = MEMORY_ALLOCATION_FAILED ;
5480       return ;
5481    }
5482    if (maximum_files) {
5483       memcpy (files, ADF_file, maximum_files * sizeof(ADF_FILE));
5484       free (ADF_file);
5485    } else {
5486       ADFI_stack_control(0,0,0,INIT_STK,0,0,NULL);
5487    }
5488    ADF_file = files;
5489    index = maximum_files;
5490    maximum_files += ADF_FILE_INC;
5491 } /* end if */
5492 
5493 if (index > MAXIMUM_FILES) {
5494    *error_return = TOO_MANY_ADF_FILES_OPENED;
5495    return;
5496 }
5497 
5498 ADF_file[index].in_use = 1 ;
5499 ADF_file[index].nlinks = 0;
5500 ADF_file[index].links = NULL;
5501 ADF_file[index].file_name = NULL;
5502 ADF_file[index].version_update[0] = '\0' ;
5503 ADF_file[index].format  = UNDEFINED_FORMAT ;
5504 ADF_file[index].os_size = UNDEFINED_FORMAT ;
5505 ADF_file[index].link_separator = '>' ;
5506 ADF_file[index].old_version = 0 ;
5507 
5508 /***
5509                 READ_ONLY - File must exist.  Writing NOT allowed.
5510                 OLD - File must exist.  Reading and writing allowed.
5511                 NEW - File must not exist.
5512                 SCRATCH - New file.  Filename is ignored.
5513                 UNKNOWN - OLD if file exists, else NEW is used.
5514 ***/
5515 
5516 ADF_file[index].file = -1;
5517 ADF_sys_err = 0;
5518 #ifdef _WIN32
5519    f_mode = O_BINARY ;
5520 #else
5521    f_mode = 0;
5522 #endif
5523 if( ADFI_stridx_c( status, "READ_ONLY" ) == 0 )
5524    f_ret = file_open( file, f_mode | O_RDONLY, 0666);
5525 else if( ADFI_stridx_c( status, "OLD" ) == 0 )
5526    f_ret = file_open( file, f_mode | O_RDWR, 0666);
5527 else if( ADFI_stridx_c( status, "NEW" ) == 0 )
5528    f_ret = file_open( file, f_mode | O_RDWR | O_CREAT, 0666);
5529 else if( ADFI_stridx_c( status, "SCRATCH" ) == 0 ) {
5530    FILE *ftmp = tmpfile();
5531    f_ret = ftmp == NULL ? -1 : FILENO(ftmp);
5532 }
5533 else if( ADFI_stridx_c( status, "UNKNOWN" ) == 0 )
5534    f_ret = file_open( file, f_mode | O_RDWR | O_CREAT, 0666);
5535 else {
5536    *error_return = ADF_FILE_STATUS_NOT_RECOGNIZED ;
5537    goto Error_Exit ;
5538 } /* end else */
5539 
5540 if( f_ret < 0 ) {
5541    ADF_sys_err = errno;
5542    if (errno == EMFILE)
5543       *error_return = TOO_MANY_ADF_FILES_OPENED;
5544    else
5545       *error_return = FILE_OPEN_ERROR ;
5546    goto Error_Exit ;
5547 } /* end if */
5548 
5549 ADF_file[index].file = f_ret ;
5550 *file_index = index ;
5551 strcpy( ADF_file[index].open_mode, status);
5552 if( ADFI_stridx_c( status, "SCRATCH" ) ) {
5553    ADF_file[index].file_name = (char *) malloc (strlen(file) + 1);
5554    if (ADF_file[index].file_name == NULL) {
5555       *error_return = MEMORY_ALLOCATION_FAILED;
5556       goto Error_Exit;
5557    }
5558    strcpy( ADF_file[index].file_name, file ) ;
5559 } /* end else */
5560 
5561 /* try to read first part of header to determine version and format */
5562 if (102 == READ(f_ret, header_data, 102)) {
5563     if (header_data[25] != 'B') ADF_file[index].old_version = 1;
5564     ADF_file[index].format  = header_data[100];
5565     ADF_file[index].os_size = header_data[101];
5566 }
5567 return ;
5568 
5569 Error_Exit:
5570     /** Clear this file's entry **/
5571 if( ADF_file[index].file >= 0 ) {
5572    if( CLOSE( ADF_file[index].file ) < 0 ) {
5573       ADF_sys_err = errno;
5574       *error_return = FILE_CLOSE_ERROR ;
5575    }
5576 } /* end if */
5577 ADF_file[index].file = -1 ;
5578 ADF_file[index].in_use = 0 ;
5579 if (ADF_file[index].file_name != NULL) {
5580    free (ADF_file[index].file_name);
5581    ADF_file[index].file_name = NULL;
5582 }
5583 
5584 } /* end of ADFI_open_file */
5585 /* end of file ADFI_open_file.c */
5586 /* file ADFI_read_chunk_length.c */
5587 /***********************************************************************
5588 ADFI read chunk length:
5589 	Read the header of the chunk.  If it is a variable sized
5590 	chunk, then the first 2 things in is are:
5591 		Tag, and pointer to end_of_chunk-tag
5592 	If NOT variable, then determine what type of chunk it is
5593 	and return a pointer to the end_of_chunk-tag:
5594 
5595 	If the incoming pointers are 0 0, then we are looking
5596 	at the file header.
5597 
5598 input:  const unsigned int file_index	The file index.
5599 input:  const struct DISK_POINTER *block_offset  Block & offset in the file.
5600 output: char tag[TAG_SIZE]			The tag from the chunk.
5601 output: struct DISK_POINTER *end_of_chunk_tag End of chunk.
5602 output:	int *error_return		Error return.
5603 
5604    Possible errors:
5605 NO_ERROR
5606 NULL_POINTER
5607 NULL_STRING_POINTER
5608 ADF_FILE_NOT_OPENED
5609 ***********************************************************************/
5610 
5611 void    ADFI_read_chunk_length(
5612 		const unsigned int file_index,
5613 		const struct DISK_POINTER *block_offset,
5614 		char tag[TAG_SIZE+1],
5615 		struct DISK_POINTER *end_of_chunk_tag,
5616 		int *error_return )
5617 {
5618 char	info[ TAG_SIZE + DISK_POINTER_SIZE ] ;
5619 struct DISK_POINTER	current_block_offset ;
5620 cgulong_t	count ;
5621 
5622 if( (block_offset == NULL) || (end_of_chunk_tag == NULL) ) {
5623    *error_return = NULL_POINTER ;
5624    return ;
5625    } /* end if */
5626 
5627 if( tag == NULL ) {
5628    *error_return = NULL_STRING_POINTER ;
5629    return ;
5630    } /* end if */
5631 
5632 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
5633    *error_return = ADF_FILE_NOT_OPENED ;
5634    return ;
5635    } /* end if */
5636 
5637 *error_return = NO_ERROR ;
5638 
5639 end_of_chunk_tag->block = 0 ;
5640 end_of_chunk_tag->offset = 0 ;
5641 
5642 	/** File Header **/
5643 if( (block_offset->block == 0) && (block_offset->offset == 0) ) {
5644 
5645 	/** point to end-tag **/
5646    end_of_chunk_tag->offset = FILE_HEADER_SIZE - TAG_SIZE ;
5647    tag[0] = file_header_tags[0][0] ;
5648    tag[1] = file_header_tags[0][1] ;
5649    tag[2] = file_header_tags[0][2] ;
5650    tag[3] = file_header_tags[0][3] ;
5651    } /* end if */
5652 
5653 	/** Free-Chunk Table **/
5654 else if( (block_offset->block == 0) &&
5655 	(block_offset->offset == FREE_CHUNKS_OFFSET) ) {
5656 
5657 	/** point to end-tag **/
5658    end_of_chunk_tag->offset =
5659       (FREE_CHUNKS_OFFSET + FREE_CHUNK_TABLE_SIZE) - TAG_SIZE ;
5660    tag[0] = free_chunk_table_start_tag[0] ;
5661    tag[1] = free_chunk_table_start_tag[1] ;
5662    tag[2] = free_chunk_table_start_tag[2] ;
5663    tag[3] = free_chunk_table_start_tag[3] ;
5664    } /* end if */
5665 else {
5666 
5667 	/** Check for 'z's in the file.  This is free-data, too small
5668 	    to include tags and pointers
5669 	**/
5670    count = 0 ;
5671    ADFI_read_file( file_index, block_offset->block, block_offset->offset,
5672 	1, info, error_return ) ;
5673    if( *error_return != NO_ERROR )
5674       return ;
5675    if( info[0] == 'z' ) {
5676       current_block_offset.block = block_offset->block ;
5677       current_block_offset.offset = block_offset->offset ;
5678       while( info[0] == 'z' ) {
5679          count++ ;
5680          current_block_offset.offset++ ;
5681 	 ADFI_adjust_disk_pointer( &current_block_offset, error_return ) ;
5682          if( *error_return != NO_ERROR )
5683             return ;
5684 
5685 	 info[0] = '\0' ;
5686          ADFI_read_file( file_index, current_block_offset.block,
5687 		current_block_offset.offset, 1, info, error_return ) ;
5688 	 if( (*error_return == FSEEK_ERROR) || (*error_return == FREAD_ERROR)){
5689 	    break ;
5690 	    } /* end if */
5691          if( *error_return != NO_ERROR )
5692             return ;
5693 	 } /* end while */
5694       end_of_chunk_tag->block = block_offset->block ;
5695       end_of_chunk_tag->offset = block_offset->offset + count - TAG_SIZE ;
5696       ADFI_adjust_disk_pointer( end_of_chunk_tag, error_return ) ;
5697       tag[0] = tag[1] = tag[2] = tag[3] = 'z' ;
5698       if( *error_return != NO_ERROR )
5699          return ;
5700       } /* end if */
5701    else {
5702 	/** Read TAG and disk_pointer **/
5703       ADFI_read_file( file_index, block_offset->block, block_offset->offset,
5704 	   TAG_SIZE + DISK_POINTER_SIZE, info, error_return ) ;
5705       if( *error_return != NO_ERROR )
5706          return ;
5707 
5708 	/* Copy the tag **/
5709       tag[0] = info[0] ;
5710       tag[1] = info[1] ;
5711       tag[2] = info[2] ;
5712       tag[3] = info[3] ;
5713       tag[4] = '\0' ;
5714 
5715 	/** Check for known tags **/
5716       if( ADFI_stridx_c( tag, node_start_tag ) == 0 ) { /** Node **/
5717          end_of_chunk_tag->block = block_offset->block ;
5718          end_of_chunk_tag->offset = block_offset->offset +
5719 		NODE_HEADER_SIZE - TAG_SIZE ;
5720          ADFI_adjust_disk_pointer( end_of_chunk_tag, error_return ) ;
5721          if( *error_return != NO_ERROR )
5722             return ;
5723          } /* end if */
5724       else {
5725 
5726 	/** Convert pointers into numeric form **/
5727 #ifdef NEW_DISK_POINTER
5728          ADFI_read_disk_pointer( file_index, &info[TAG_SIZE],
5729 		&info[DISK_POINTER_SIZE], end_of_chunk_tag, error_return ) ;
5730 #else
5731          ADFI_disk_pointer_from_ASCII_Hex( &info[TAG_SIZE],
5732 		&info[DISK_POINTER_SIZE], end_of_chunk_tag, error_return ) ;
5733 #endif
5734          if( *error_return != NO_ERROR )
5735             return ;
5736          } /* end else */
5737       } /* end else */
5738    } /* end else */
5739 
5740 } /* end of ADFI_read_chunk_length */
5741 /* end of file ADFI_read_chunk_length.c */
5742 /* file ADFI_read_data_chunk.c */
5743 /***********************************************************************
5744 ADFI read data chunk:
5745 
5746 input:  const unsigned int file_index	The file index.
5747 input:  const struct DISK_POINTER *block_offset  Block & offset in the file.
5748 input:  const char *data_type		The defined datatype.
5749 input:  const int data_size		Size of data entity in bytes.
5750 input:  const long chunk_bytes		Number of bytes in data chunk.
5751 input:  const long start_offset		Starting offset into the data chunk
5752 input:  const long total_bytes		Number of bytes to read in data chunk.
5753 output: char *data			Pointer to the resulting data.
5754 output:	int *error_return		Error return.
5755 
5756    Possible errors:
5757 NO_ERROR
5758 NULL_POINTER
5759 ADF_FILE_NOT_OPENED
5760 ADF_DISK_TAG_ERROR
5761 REQUESTED_DATA_TOO_LONG
5762 ***********************************************************************/
5763 void    ADFI_read_data_chunk(
5764 		const unsigned int file_index,
5765 		const struct DISK_POINTER *block_offset,
5766 		struct TOKENIZED_DATA_TYPE *tokenized_data_type,
5767 		const int data_size,
5768                 const cglong_t chunk_bytes,
5769 		const cglong_t start_offset,
5770 		const cglong_t total_bytes,
5771 		char *data,
5772 		int *error_return )
5773 {
5774 int format_compare ;
5775 char	tag[TAG_SIZE + 1] ;
5776 struct DISK_POINTER	data_start, end_of_chunk_tag ;
5777 cglong_t			chunk_total_bytes ;
5778 
5779 if( block_offset == NULL ) {
5780    *error_return = NULL_POINTER ;
5781    return ;
5782    } /* end if */
5783 
5784 if( (tokenized_data_type == NULL) || (data == NULL) ) {
5785    *error_return = NULL_STRING_POINTER ;
5786    return ;
5787    } /* end if */
5788 
5789 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
5790    *error_return = ADF_FILE_NOT_OPENED ;
5791    return ;
5792    } /* end if */
5793 
5794 if( total_bytes+start_offset > chunk_bytes ) {
5795    *error_return = REQUESTED_DATA_TOO_LONG ;
5796    return ;
5797    } /* end if */
5798 
5799 *error_return = NO_ERROR ;
5800 
5801 	/** Get tag and chunk length **/
5802 ADFI_read_chunk_length( file_index, block_offset, tag, &end_of_chunk_tag,
5803 		error_return ) ;
5804 if( *error_return != NO_ERROR )
5805    return ;
5806 tag[TAG_SIZE] = '\0' ;
5807 
5808 	/** Check start-of-chunk tag **/
5809 if( ADFI_stridx_c( tag, data_chunk_start_tag ) != 0 ) {
5810    *error_return = ADF_DISK_TAG_ERROR ;
5811    return ;
5812    } /* end if */
5813 
5814 	/** Check end-of-chunk tag **/
5815 ADFI_read_file( file_index, end_of_chunk_tag.block, end_of_chunk_tag.offset,
5816 	TAG_SIZE, tag, error_return ) ;
5817 if( *error_return != NO_ERROR )
5818    return ;
5819 tag[TAG_SIZE] = '\0' ;
5820 
5821 if( ADFI_stridx_c( tag, data_chunk_end_tag ) != 0 ) {
5822    *error_return = ADF_DISK_TAG_ERROR ;
5823    return ;
5824    } /* end if */
5825 
5826 	/** Point to the start of the data **/
5827 data_start.block = block_offset->block ;
5828 data_start.offset = block_offset->offset + start_offset +
5829                     DISK_POINTER_SIZE + TAG_SIZE ;
5830 ADFI_adjust_disk_pointer( &data_start, error_return ) ;
5831 if( *error_return != NO_ERROR )
5832    return ;
5833 
5834 	/** calculate the total number of data bytes **/
5835 chunk_total_bytes = end_of_chunk_tag.offset - data_start.offset + start_offset
5836 	+ (end_of_chunk_tag.block - data_start.block) * DISK_BLOCK_SIZE ;
5837 if( chunk_bytes > chunk_total_bytes ) {
5838    *error_return = REQUESTED_DATA_TOO_LONG ;
5839    return ;
5840    } /* end if */
5841 else {
5842    if( chunk_bytes < chunk_total_bytes )
5843       *error_return = REQUESTED_DATA_TOO_LONG ;
5844 
5845        /** check for need of data translation **/
5846     ADFI_file_and_machine_compare( file_index, tokenized_data_type,
5847 				   &format_compare, error_return );
5848     if( *error_return != NO_ERROR )
5849        return ;
5850     if( format_compare == 1 ) {
5851 	/** Read the data off of disk **/
5852 assert(data_start.offset <= 0x1fff);
5853       ADFI_read_file( file_index, data_start.block, data_start.offset,
5854 		      total_bytes, data, error_return ) ;
5855       if( *error_return != NO_ERROR )
5856          return ;
5857       } /* end if */
5858    else {
5859       ADFI_read_data_translated( file_index, data_start.block,
5860 		data_start.offset, tokenized_data_type, data_size,
5861 		total_bytes, data, error_return ) ;
5862       if( *error_return != NO_ERROR )
5863          return ;
5864       } /* end else */
5865    } /* end else */
5866 
5867 } /* end of ADFI_read_data_chunk */
5868 /* end of file ADFI_read_data_chunk.c */
5869 /* file ADFI_read_data_chunk_table.c */
5870 /***********************************************************************
5871 ADFI read data chunk table:
5872 
5873 input:  const unsigned int file_index	The file index.
5874 input:  const struct DISK_POINTER *block_offset  Block & offset in the file.
5875 output: struct DATA_CHUNK_TABLE_ENTRY data_chunk_table[] Array of DC entries.
5876 output:	int *error_return		Error return.
5877 
5878    Possible errors:
5879 NO_ERROR
5880 NULL_POINTER
5881 ADF_FILE_NOT_OPENED
5882 ***********************************************************************/
5883 void    ADFI_read_data_chunk_table(
5884 		const unsigned int file_index,
5885 		const struct DISK_POINTER *block_offset,
5886 		struct DATA_CHUNK_TABLE_ENTRY data_chunk_table[],
5887 		int *error_return )
5888 {
5889 char	tag[ TAG_SIZE + 1 ] ;
5890 struct	DISK_POINTER	end_of_chunk_tag, tmp_block_offset ;
5891 cgulong_t		i, number_of_bytes_to_read ;
5892 
5893 if( (block_offset == NULL) || (data_chunk_table == NULL) ) {
5894    *error_return = NULL_POINTER ;
5895    return ;
5896    } /* end if */
5897 
5898 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
5899    *error_return = ADF_FILE_NOT_OPENED ;
5900    return ;
5901    } /* end if */
5902 
5903 *error_return = NO_ERROR ;
5904 	/** Get the tag and the length **/
5905 ADFI_read_chunk_length( file_index, block_offset, tag,
5906 		&end_of_chunk_tag, error_return ) ;
5907 if( *error_return != NO_ERROR )
5908    return ;
5909 tag[TAG_SIZE] = '\0' ;
5910 
5911 	/** Compare the start tag **/
5912 if( ADFI_stridx_c( tag, data_chunk_table_start_tag ) != 0 ) {
5913    *error_return = ADF_DISK_TAG_ERROR ;
5914    return ;
5915    } /* end if */
5916 
5917 number_of_bytes_to_read =
5918 	(end_of_chunk_tag.block - block_offset->block) * DISK_BLOCK_SIZE +
5919 	(end_of_chunk_tag.offset - block_offset->offset) -
5920 	(TAG_SIZE + DISK_POINTER_SIZE) ;
5921 
5922 	/** Read the data from disk **/
5923 tmp_block_offset.block = block_offset->block ;
5924 tmp_block_offset.offset = block_offset->offset + TAG_SIZE ;
5925 
5926 for( i=0; i<number_of_bytes_to_read/(2 * DISK_POINTER_SIZE); i++ ) {
5927    tmp_block_offset.offset += DISK_POINTER_SIZE ;
5928    ADFI_adjust_disk_pointer( &tmp_block_offset, error_return ) ;
5929    if( *error_return != NO_ERROR )
5930       return ;
5931    ADFI_read_disk_pointer_from_disk( file_index,
5932 		tmp_block_offset.block, tmp_block_offset.offset,
5933 		&data_chunk_table[i].start, error_return ) ;
5934    if( *error_return != NO_ERROR )
5935       return ;
5936    tmp_block_offset.offset += DISK_POINTER_SIZE ;
5937    ADFI_adjust_disk_pointer( &tmp_block_offset, error_return ) ;
5938    if( *error_return != NO_ERROR )
5939       return ;
5940    ADFI_read_disk_pointer_from_disk( file_index,
5941 		tmp_block_offset.block, tmp_block_offset.offset,
5942 		&data_chunk_table[i].end, error_return ) ;
5943    if( *error_return != NO_ERROR )
5944       return ;
5945    } /* end for */
5946 
5947 ADFI_read_file( file_index, end_of_chunk_tag.block,
5948 	end_of_chunk_tag.offset, TAG_SIZE, tag, error_return ) ;
5949 if( *error_return != NO_ERROR )
5950    return ;
5951 
5952 	/** Compare the end tag **/
5953 if( ADFI_stridx_c( tag, data_chunk_table_end_tag ) != 0 ) {
5954    *error_return = ADF_DISK_TAG_ERROR ;
5955    return ;
5956    } /* end if */
5957 
5958 } /* end of ADFI_read_data_chunk_table */
5959 /* end of file ADFI_read_data_chunk_table.c */
5960 /* file ADFI_read_data_translated.c */
5961 /***********************************************************************
5962 ADFI read data translated:
5963 
5964 input:  const unsigned int file_index	The file index.
5965 input:	const unsigned long file_block	Block within the file.
5966 input:	const unsigned long block_offset Offset within the block.
5967 input:  const char *data_type		The defined datatype.
5968 input:  const struct TOKENIZED_DATA_TYPE *tokenized_data_type Array.
5969 input:  const int data_size		Size of data entity in bytes.
5970 input:  const long total_bytes		Number of bytes expected.
5971 output: char *data			Pointer to the data.
5972 output:	int *error_return		Error return.
5973 
5974    Possible errors:
5975 NO_ERROR
5976 ***********************************************************************/
5977 void    ADFI_read_data_translated(
5978 		const unsigned int file_index,
5979 		const cgulong_t file_block,
5980 		const cgulong_t block_offset,
5981 		const struct TOKENIZED_DATA_TYPE *tokenized_data_type,
5982 		const int data_size,
5983 		const cglong_t total_bytes,
5984 		char *data,
5985 		int *error_return )
5986 {
5987 struct	DISK_POINTER	disk_pointer ;
5988 int	                current_token = -1 ;
5989 int                     machine_size ;
5990 unsigned char		*to_data = (unsigned char *)data ;
5991 unsigned char		*from_data = from_to_data ;
5992 unsigned int		chunk_size ;
5993 unsigned int		delta_from_bytes, delta_to_bytes ;
5994 cgulong_t		number_of_data_elements, number_of_elements_read ;
5995 
5996 if( data_size <= 0 ) {
5997    *error_return = ZERO_LENGTH_VALUE ;
5998    return ;
5999    } /* end if */
6000 
6001   /** Get machine size of element stored in the NULL element **/
6002 do {
6003   machine_size = tokenized_data_type[ ++current_token ].machine_type_size ;
6004 } while( tokenized_data_type[ current_token ].type[0] != 0 ) ;
6005 
6006 disk_pointer.block = file_block ;
6007 disk_pointer.offset = block_offset ;
6008 number_of_data_elements = total_bytes / data_size ;
6009 number_of_elements_read = 0 ;
6010 chunk_size = CONVERSION_BUFF_SIZE / data_size ;
6011 if ( chunk_size < 1 ) {
6012   *error_return = REQUESTED_DATA_TOO_LONG ;
6013   return ;
6014 }
6015 delta_from_bytes = chunk_size * data_size ;
6016 delta_to_bytes = chunk_size * machine_size ;
6017 
6018 while( number_of_elements_read < number_of_data_elements ) {
6019       /** Limit the number to the end of the data. **/
6020    number_of_elements_read += chunk_size ;
6021    if ( number_of_elements_read > number_of_data_elements ) {
6022      chunk_size -= (unsigned int)( number_of_elements_read - number_of_data_elements ) ;
6023      delta_from_bytes = chunk_size * data_size ;
6024      delta_to_bytes   = chunk_size * machine_size ;
6025    }
6026    ADFI_read_file( file_index, disk_pointer.block, disk_pointer.offset,
6027 		   delta_from_bytes, (char *)from_data, error_return ) ;
6028    if( *error_return != NO_ERROR )
6029       return ;
6030    ADFI_convert_number_format(
6031 		ADF_file[file_index].format, /* from format */
6032 		ADF_file[file_index].os_size, /* from os size */
6033 		ADF_this_machine_format, /* to format */
6034 		ADF_this_machine_os_size, /* to os size */
6035 		FROM_FILE_FORMAT,
6036 		tokenized_data_type, chunk_size, from_data,
6037 		to_data, error_return ) ;
6038    if( *error_return != NO_ERROR )
6039       return ;
6040    to_data += delta_to_bytes ;
6041    disk_pointer.offset += delta_from_bytes ;
6042    if ( disk_pointer.offset > DISK_BLOCK_SIZE ) {
6043      ADFI_adjust_disk_pointer( &disk_pointer, error_return ) ;
6044      if( *error_return != NO_ERROR )
6045        return ;
6046      } /* end if */
6047    } /* end while */
6048 
6049 } /* end of ADFI_read_data_translated */
6050 /* end of file ADFI_read_data_translated.c */
6051 /* file ADFI_read_disk_block.c */
6052 /***********************************************************************
6053 ADFI read disk block:
6054 
6055    Possible errors:
6056 NO_ERROR
6057 ***********************************************************************/
6058 void	ADFI_read_disk_block()
6059 {
6060 fprintf(stderr,"Subroutine ADFI_read_disk_block is not yet implemented...\n" ) ;
6061 } /* end of ADFI_read_disk_block */
6062 /* end of file ADFI_read_disk_block.c */
6063 /* file ADFI_read_disk_pointer_from_disk.c */
6064 /***********************************************************************
6065 ADFI read disk pointer from disk:
6066 	Given a pointer to a disk pointer, read it from disk and convert
6067 	it into numeric form.
6068 
6069 input:	const unsigned int file_index	File to read from.
6070 input:	const unsigned long file_block	Block within the file.
6071 input:	const unsigned long block_offset Offset within the block.
6072 output: struct DISK_POINTER *block_and_offset Resulting disk pointer.
6073 output:	int *error_return		Error return.
6074 
6075    Possible errors:
6076 NO_ERROR
6077 NULL_POINTER
6078 ADF_FILE_NOT_OPENED
6079 ***********************************************************************/
6080 void    ADFI_read_disk_pointer_from_disk(
6081 		const unsigned int file_index,
6082 		const cgulong_t file_block,
6083 		const cgulong_t block_offset,
6084 		struct DISK_POINTER *block_and_offset,
6085 		int *error_return )
6086 {
6087 char disk_block_offset[DISK_POINTER_SIZE] ;
6088 
6089 if( block_and_offset == NULL ) {
6090    *error_return = NULL_POINTER ;
6091    return ;
6092    } /* end if */
6093 
6094 if( block_offset > DISK_BLOCK_SIZE ) {
6095    *error_return = BLOCK_OFFSET_OUT_OF_RANGE ;
6096    return ;
6097    } /* end if */
6098 
6099 
6100 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
6101    *error_return = ADF_FILE_NOT_OPENED ;
6102    return ;
6103    } /* end if */
6104 
6105 *error_return = NO_ERROR ;
6106 
6107         /** Check the stack for block/offset **/
6108 #if 0
6109 if ( ADFI_stack_control(file_index, file_block, (unsigned int)block_offset,
6110 		        GET_STK, DISK_PTR_STK,
6111 		        DISK_POINTER_SIZE, disk_block_offset ) != NO_ERROR ) {
6112 #endif
6113 
6114 	/** Get the block/offset from disk **/
6115   ADFI_read_file( file_index, file_block, block_offset,
6116 	  DISK_POINTER_SIZE, disk_block_offset, error_return ) ;
6117   if( *error_return != NO_ERROR )
6118      return ;
6119 
6120          /** Set the block/offset onto the stack **/
6121 #if 0
6122   ADFI_stack_control(file_index, file_block, (unsigned int)block_offset,
6123 		     SET_STK, DISK_PTR_STK,
6124 		     DISK_POINTER_SIZE, disk_block_offset );
6125 } /* end if */
6126 #endif
6127 
6128 	/** Convert into numeric form **/
6129 #ifdef NEW_DISK_POINTER
6130 ADFI_read_disk_pointer( file_index, &disk_block_offset[0], &disk_block_offset[8],
6131 		block_and_offset, error_return ) ;
6132 #else
6133 ADFI_disk_pointer_from_ASCII_Hex( &disk_block_offset[0], &disk_block_offset[8],
6134 		block_and_offset, error_return ) ;
6135 #endif
6136 if( *error_return != NO_ERROR )
6137    return ;
6138 
6139 } /* end of ADFI_read_disk_pointer_from_disk */
6140 /* end of file ADFI_read_disk_pointer_from_disk.c */
6141 
6142 /***********************************************************************/
6143 
6144 cglong_t ADFI_read (
6145         const unsigned int file_index,
6146         const cglong_t data_length,
6147         char *data)
6148 {
6149    char *data_ptr = data;
6150    cglong_t bytes_left = data_length;
6151    cglong_t bytes_read = 0;
6152    int nbytes, to_read;
6153 
6154    ADF_sys_err = 0;
6155    while (bytes_left > 0) {
6156       to_read = bytes_left > CG_MAX_INT32 ? CG_MAX_INT32 : (int)bytes_left;
6157       nbytes = (int) READ (ADF_file[file_index].file, data_ptr, to_read);
6158       if (0 == nbytes) break;
6159       if (-1 == nbytes) {
6160           if (EINTR != errno) {
6161              ADF_sys_err = errno;
6162              return -1;
6163           }
6164       }
6165       else {
6166           bytes_left -= nbytes;
6167           bytes_read += nbytes;
6168           data_ptr += nbytes;
6169       }
6170    }
6171    return bytes_read;
6172 }
6173 
6174 /* file ADFI_read_file.c */
6175 /***********************************************************************
6176 ADFI read file:
6177     Read a number of bytes from an open ADF file from a given
6178     file, block, and offset.  Buffering is done in an attempt to
6179     improve performance of repeatedly reading small pieces of
6180     contiguous data.  Note:  read buffering also affects the
6181     write function, i.e, all writes must reset the read buffer.
6182 
6183 input:  const unsigned int file_index    File to read from.
6184 input:  const unsigned long file_block   Block within the file.
6185 input:  const unsigned long block_offset Offset within the block.
6186 input:  const unsigned int data_length   Length of the data to read.
6187 input:  char *data                       Address of the data.
6188 output: int *error_return                Error return.
6189 
6190     Possible errors:
6191 NO_ERROR
6192 NULL_STRING_POINTER
6193 ADF_FILE_NOT_OPENED
6194 FREAD_ERROR
6195 ***********************************************************************/
6196 void    ADFI_read_file(
6197         const unsigned int file_index,
6198         const cgulong_t file_block,
6199         const cgulong_t block_offset,
6200         const cglong_t data_length,
6201         char *data,
6202         int *error_return )
6203 {
6204 cglong_t iret ;
6205 
6206 
6207 if( data == NULL ) {
6208    *error_return = NULL_STRING_POINTER ;
6209    return ;
6210    } /* end if */
6211 
6212 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
6213    *error_return = ADF_FILE_NOT_OPENED ;
6214    return ;
6215    } /* end if */
6216 
6217 *error_return = NO_ERROR ;
6218 
6219     /** No need to buffer large pieces of data or to take special
6220         measures to cross block boundaries **/
6221 
6222 if( data_length + block_offset > DISK_BLOCK_SIZE ) {
6223 
6224 	/** Position the file **/
6225    ADFI_fseek_file( file_index, file_block, block_offset, error_return ) ;
6226    if( *error_return != NO_ERROR ) {
6227       return ;
6228       } /* end if */
6229 
6230 	/** Read the data from disk **/
6231    iret = ADFI_read ( file_index, data_length, data ) ;
6232    if( iret != data_length ) {
6233       *error_return = FREAD_ERROR ;
6234       return ;
6235       } /* end if */
6236 
6237    return;
6238 } /* end if */
6239 
6240     /** For smaller pieces of data, read a block at a time.  This will improve
6241         performance if neighboring data is requested a small piece at a time
6242         (strided reads, file overhead).
6243 
6244         Some assumptions apply to the block size.  With some experimenting,
6245         1K blocks do not offer much improvement.  4K blocks (4096 bytes)
6246         do improve performance remarkably. This is due to the fact that the
6247 	file structure is based of 4K blocks with offsets.
6248     **/
6249 
6250 if( num_in_rd_block < DISK_BLOCK_SIZE ||  /*- buffer is not full -*/
6251     (cglong_t) file_block != last_rd_block       ||  /*- a different block -*/
6252     (int) file_index != last_rd_file ) {        /*- entirely different file -*/
6253 
6254     /** buffer is not current, re-read **/
6255 
6256   if ( (cglong_t) file_block == last_wr_block && (int) file_index == last_wr_file ) {
6257 
6258     /* Copy data from write buffer */
6259     memcpy( rd_block_buffer, wr_block_buffer, DISK_BLOCK_SIZE );
6260     iret = DISK_BLOCK_SIZE;
6261   }
6262   else {
6263 
6264     /** Position the file **/
6265     ADFI_fseek_file( file_index, file_block, 0, error_return ) ;
6266     if( *error_return != NO_ERROR ) {
6267       return ;
6268       } /* end if */
6269 
6270     /** Read the data from disk **/
6271      iret = ADFI_read( file_index, DISK_BLOCK_SIZE, rd_block_buffer ) ;
6272      if( iret <= 0 ) {
6273         *error_return = FREAD_ERROR ;
6274         return ;
6275       } /* end if */
6276 
6277   } /* end if */
6278 
6279   /** Remember buffer information **/
6280   last_rd_block   = file_block ;
6281   last_rd_file    = (int)file_index ;
6282   num_in_rd_block = (int)iret ;
6283 
6284 } /* end if */
6285 
6286    /*read from buffer*/
6287 memcpy( data, &rd_block_buffer[block_offset], (size_t)data_length );
6288 
6289 } /* end of ADFI_read_file */
6290 /* end of file ADFI_read_file.c */
6291 /* file ADFI_read_file_header.c */
6292 /***********************************************************************
6293 ADFI read file header:
6294 
6295 input:  const unsigned int file_index	The file index.
6296 output: struct FILE_HEADER *file_header	Pointer to a file-header struct.
6297 output:	int *error_return		Error return.
6298 
6299    Possible errors:
6300 NO_ERROR
6301 NULL_POINTER
6302 ADF_FILE_NOT_OPENED
6303 ADF_MEMORY_TAG_ERROR
6304 ***********************************************************************/
6305 void	ADFI_read_file_header(
6306 		const unsigned int file_index,
6307 		struct FILE_HEADER *file_header,
6308 		int *error_return )
6309 {
6310 char	disk_header[ FILE_HEADER_SIZE ] ;
6311 
6312 if( file_header == NULL ) {
6313    *error_return = NULL_POINTER ;
6314    return ;
6315    } /* end if */
6316 
6317 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
6318    *error_return = ADF_FILE_NOT_OPENED ;
6319    return ;
6320    } /* end if */
6321 
6322 *error_return = NO_ERROR ;
6323 
6324         /** Check the stack for header **/
6325 if ( ADFI_stack_control(file_index, 0, 0, GET_STK, FILE_STK,
6326 			FILE_HEADER_SIZE, disk_header ) != NO_ERROR ) {
6327 
6328 	/** Read in the header into memory **/
6329   ADFI_read_file( file_index, 0, 0, FILE_HEADER_SIZE, disk_header,
6330 	 	  error_return ) ;
6331   if( *error_return != NO_ERROR )
6332     return ;
6333 
6334 	/** Check memory tags for proper data **/
6335   if( strncmp( &disk_header[32], file_header_tags[0], TAG_SIZE )!= 0 ) {
6336      *error_return = ADF_MEMORY_TAG_ERROR ;
6337      return ;
6338    } /* end if */
6339 
6340   if( strncmp( &disk_header[64], file_header_tags[1], TAG_SIZE )!= 0 ) {
6341      *error_return = ADF_MEMORY_TAG_ERROR ;
6342      return ;
6343    } /* end if */
6344 
6345   if( strncmp( &disk_header[96], file_header_tags[2], TAG_SIZE )!= 0 ) {
6346      *error_return = ADF_MEMORY_TAG_ERROR ;
6347      return ;
6348    } /* end if */
6349 
6350   if( strncmp( &disk_header[102], file_header_tags[3], TAG_SIZE )!= 0 ) {
6351      *error_return = ADF_MEMORY_TAG_ERROR ;
6352      return ;
6353    } /* end if */
6354 
6355   if( strncmp( &disk_header[130], file_header_tags[4], TAG_SIZE )!= 0 ) {
6356      *error_return = ADF_MEMORY_TAG_ERROR ;
6357      return ;
6358    } /* end if */
6359 
6360   if( strncmp( &disk_header[182], file_header_tags[5], TAG_SIZE )!= 0 ) {
6361      *error_return = ADF_MEMORY_TAG_ERROR ;
6362      return ;
6363    } /* end if */
6364 
6365          /** Set the header onto the stack **/
6366   ADFI_stack_control(file_index, 0, 0, SET_STK, FILE_STK,
6367 		     FILE_HEADER_SIZE, disk_header );
6368 } /* end if */
6369 
6370 /** OK the memory tags look good, let's convert disk-formatted header
6371     into memory **/
6372 strncpy( (char *)file_header->what, &disk_header[  0], 32 ) ;
6373 strncpy( (char *)file_header->tag0, &disk_header[ 32], TAG_SIZE ) ;
6374 strncpy( (char *)file_header->creation_date, &disk_header[ 36], DATE_TIME_SIZE);
6375 strncpy( (char *)file_header->tag1, &disk_header[ 64], TAG_SIZE ) ;
6376 strncpy( (char *)file_header->modification_date, &disk_header[ 68],
6377 							DATE_TIME_SIZE ) ;
6378 strncpy( (char *)file_header->tag2, &disk_header[ 96], TAG_SIZE ) ;
6379 file_header->numeric_format = disk_header[100] ;
6380 file_header->os_size        = disk_header[101] ;
6381 strncpy( (char *)file_header->tag3, &disk_header[102], TAG_SIZE ) ;
6382 
6383 #if 0
6384 #ifdef NEW_DISK_POINTER
6385 if (ADF_file[file_index].format == UNDEFINED_FORMAT)
6386     ADF_file[file_index].format = file_header->numeric_format;
6387 if (ADF_file[file_index].os_size == UNDEFINED_FORMAT)
6388     ADF_file[file_index].os_size = file_header->os_size;
6389 #endif
6390 #else
6391 assert(ADF_file[file_index].format != UNDEFINED_FORMAT);
6392 assert(ADF_file[file_index].os_size != UNDEFINED_FORMAT);
6393 #endif
6394 
6395 ADFI_ASCII_Hex_2_unsigned_int( 0, 255, 2, &disk_header[106],
6396 		&file_header->sizeof_char, error_return ) ;
6397 if( *error_return != NO_ERROR )
6398    return ;
6399 
6400 ADFI_ASCII_Hex_2_unsigned_int( 0, 255, 2, &disk_header[108],
6401 		&file_header->sizeof_short, error_return ) ;
6402 if( *error_return != NO_ERROR )
6403    return ;
6404 
6405 ADFI_ASCII_Hex_2_unsigned_int( 0, 255, 2, &disk_header[110],
6406 		&file_header->sizeof_int, error_return ) ;
6407 if( *error_return != NO_ERROR )
6408    return ;
6409 
6410 ADFI_ASCII_Hex_2_unsigned_int( 0, 255, 2, &disk_header[112],
6411 		&file_header->sizeof_long, error_return ) ;
6412 if( *error_return != NO_ERROR )
6413    return ;
6414 
6415 ADFI_ASCII_Hex_2_unsigned_int( 0, 255, 2, &disk_header[114],
6416 		&file_header->sizeof_float, error_return ) ;
6417 if( *error_return != NO_ERROR )
6418    return ;
6419 
6420 ADFI_ASCII_Hex_2_unsigned_int( 0, 255, 2, &disk_header[116],
6421 		&file_header->sizeof_double, error_return ) ;
6422 if( *error_return != NO_ERROR )
6423    return ;
6424 
6425 ADFI_ASCII_Hex_2_unsigned_int( 0, 255, 2, &disk_header[118],
6426 		&file_header->sizeof_char_p, error_return ) ;
6427 if( *error_return != NO_ERROR )
6428    return ;
6429 
6430 ADFI_ASCII_Hex_2_unsigned_int( 0, 255, 2, &disk_header[120],
6431 		&file_header->sizeof_short_p, error_return ) ;
6432 if( *error_return != NO_ERROR )
6433    return ;
6434 
6435 ADFI_ASCII_Hex_2_unsigned_int( 0, 255, 2, &disk_header[122],
6436 		&file_header->sizeof_int_p, error_return ) ;
6437 if( *error_return != NO_ERROR )
6438    return ;
6439 
6440 ADFI_ASCII_Hex_2_unsigned_int( 0, 255, 2, &disk_header[124],
6441 		&file_header->sizeof_long_p, error_return ) ;
6442 if( *error_return != NO_ERROR )
6443    return ;
6444 
6445 ADFI_ASCII_Hex_2_unsigned_int( 0, 255, 2, &disk_header[126],
6446 		&file_header->sizeof_float_p, error_return ) ;
6447 if( *error_return != NO_ERROR )
6448    return ;
6449 
6450 ADFI_ASCII_Hex_2_unsigned_int( 0, 255, 2, &disk_header[128],
6451 		&file_header->sizeof_double_p, error_return ) ;
6452 if( *error_return != NO_ERROR )
6453    return ;
6454 
6455 strncpy( file_header->tag4, &disk_header[130], TAG_SIZE ) ;
6456 
6457 #ifdef NEW_DISK_POINTER
6458 ADFI_read_disk_pointer( file_index, &disk_header[134], &disk_header[142],
6459 		&file_header->root_node, error_return ) ;
6460 #else
6461 ADFI_disk_pointer_from_ASCII_Hex( &disk_header[134], &disk_header[142],
6462 		&file_header->root_node, error_return ) ;
6463 #endif
6464 if( *error_return != NO_ERROR )
6465    return ;
6466 
6467 #ifdef NEW_DISK_POINTER
6468 ADFI_read_disk_pointer( file_index, &disk_header[146], &disk_header[154],
6469 		&file_header->end_of_file, error_return ) ;
6470 #else
6471 ADFI_disk_pointer_from_ASCII_Hex( &disk_header[146], &disk_header[154],
6472 		&file_header->end_of_file, error_return ) ;
6473 #endif
6474 if( *error_return != NO_ERROR )
6475    return ;
6476 
6477 #ifdef NEW_DISK_POINTER
6478 ADFI_read_disk_pointer( file_index, &disk_header[158], &disk_header[166],
6479 		&file_header->free_chunks, error_return ) ;
6480 #else
6481 ADFI_disk_pointer_from_ASCII_Hex( &disk_header[158], &disk_header[166],
6482 		&file_header->free_chunks, error_return ) ;
6483 #endif
6484 if( *error_return != NO_ERROR )
6485    return ;
6486 
6487 #ifdef NEW_DISK_POINTER
6488 ADFI_read_disk_pointer( file_index, &disk_header[170], &disk_header[178],
6489 		&file_header->extra, error_return ) ;
6490 #else
6491 ADFI_disk_pointer_from_ASCII_Hex( &disk_header[170], &disk_header[178],
6492 		&file_header->extra, error_return ) ;
6493 #endif
6494 if( *error_return != NO_ERROR )
6495    return ;
6496 
6497 strncpy( file_header->tag5, &disk_header[182], TAG_SIZE ) ;
6498 
6499 
6500 	/** Check memory tags for proper data **/
6501 if( strncmp( file_header->tag0, file_header_tags[0], TAG_SIZE )!= 0 ) {
6502    *error_return = ADF_MEMORY_TAG_ERROR ;
6503    return ;
6504    } /* end if */
6505 
6506 if( strncmp( file_header->tag1, file_header_tags[1], TAG_SIZE )!= 0 ) {
6507    *error_return = ADF_MEMORY_TAG_ERROR ;
6508    return ;
6509    } /* end if */
6510 
6511 if( strncmp( file_header->tag2, file_header_tags[2], TAG_SIZE )!= 0 ) {
6512    *error_return = ADF_MEMORY_TAG_ERROR ;
6513    return ;
6514    } /* end if */
6515 
6516 if( strncmp( file_header->tag3, file_header_tags[3], TAG_SIZE )!= 0 ) {
6517    *error_return = ADF_MEMORY_TAG_ERROR ;
6518    return ;
6519    } /* end if */
6520 
6521 if( strncmp( file_header->tag4, file_header_tags[4], TAG_SIZE )!= 0 ) {
6522    *error_return = ADF_MEMORY_TAG_ERROR ;
6523    return ;
6524    } /* end if */
6525 
6526 if( strncmp( file_header->tag5, file_header_tags[5], TAG_SIZE )!= 0 ) {
6527    *error_return = ADF_MEMORY_TAG_ERROR ;
6528    return ;
6529    } /* end if */
6530 
6531 } /* end of ADFI_read_file_header */
6532 /* end of file ADFI_read_file_header.c */
6533 /* file ADFI_read_free_chunk.c */
6534 /***********************************************************************
6535 ADFI read free chunk:
6536 
6537 input:  const unsigned int file_index	The file index.
6538 input:  const struct DISK_POINTER *block_offset	Block & offset in the file.
6539 output: struct DISK_POINTER *end_of_chunk_tag	End of free chunk tag.
6540 output: struct DISK_POINTER *next_chunk	Next free chunk in list.
6541 output:	int *error_return		Error return.
6542 
6543    Possible errors:
6544 NO_ERROR
6545 NULL_POINTER
6546 ADF_FILE_NOT_OPENED
6547 ADF_DISK_TAG_ERROR
6548 ***********************************************************************/
6549 void    ADFI_read_free_chunk(
6550 		const unsigned int file_index,
6551 		const struct DISK_POINTER *block_offset,
6552 		struct FREE_CHUNK *free_chunk,
6553 		int *error_return )
6554 {
6555 char	tag[TAG_SIZE + 1] ;
6556 struct DISK_POINTER chunk_block_offset ;
6557 
6558 if( (block_offset == NULL) || (free_chunk == NULL) ) {
6559    *error_return = NULL_POINTER ;
6560    return ;
6561    } /* end if */
6562 
6563 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
6564    *error_return = ADF_FILE_NOT_OPENED ;
6565    return ;
6566    } /* end if */
6567 
6568 *error_return = NO_ERROR ;
6569 
6570 	/** Get the tag and the length **/
6571 ADFI_read_chunk_length( file_index, block_offset, tag,
6572 		&(free_chunk->end_of_chunk_tag), error_return ) ;
6573 if( *error_return != NO_ERROR )
6574    return ;
6575 tag[TAG_SIZE] = '\0' ;
6576 
6577 	/** Compare the start tag **/
6578 if( ADFI_stridx_c( tag, free_chunk_start_tag ) != 0 ) {
6579    *error_return = ADF_DISK_TAG_ERROR ;
6580    return ;
6581    } /* end if */
6582 
6583 	/** Set block offset to the start of the chunk **/
6584 
6585 chunk_block_offset = *block_offset ;
6586 chunk_block_offset.offset += TAG_SIZE + DISK_POINTER_SIZE ;
6587 ADFI_adjust_disk_pointer( &chunk_block_offset, error_return ) ;
6588 if( *error_return != NO_ERROR )
6589    return ;
6590 
6591 	/** Read the data from disk **/
6592 
6593 ADFI_read_disk_pointer_from_disk( file_index, chunk_block_offset.block,
6594 	chunk_block_offset.offset, &(free_chunk->next_chunk), error_return ) ;
6595 if( *error_return != NO_ERROR )
6596    return ;
6597 
6598 ADFI_read_file( file_index, free_chunk->end_of_chunk_tag.block,
6599 	free_chunk->end_of_chunk_tag.offset, TAG_SIZE, tag, error_return ) ;
6600 if( *error_return != NO_ERROR )
6601    return ;
6602 
6603 	/** Compare the end tag **/
6604 if( ADFI_stridx_c( tag, free_chunk_end_tag ) != 0 ) {
6605    *error_return = ADF_DISK_TAG_ERROR ;
6606    return ;
6607    } /* end if */
6608 
6609 strncpy( free_chunk->start_tag, free_chunk_start_tag, 4 ) ;
6610 strncpy( free_chunk->end_tag, free_chunk_end_tag, 4 ) ;
6611 } /* end of ADFI_read_free_chunk */
6612 /* end of file ADFI_read_free_chunk.c */
6613 /* file ADFI_read_free_chunk_table.c */
6614 /***********************************************************************
6615 ADFI read free chunk table:
6616 
6617 input:  const unsigned int file_index	The file index.
6618 output: struct FREE_CHUNK_TABLE *free_chunk_table Pointer to table.
6619 output:	int *error_return		Error return.
6620 
6621    Possible errors:
6622 NO_ERROR
6623 NULL_POINTER
6624 ADF_FILE_NOT_OPENED
6625 ADF_DISK_TAG_ERROR
6626 ADF_MEMORY_TAG_ERROR
6627 ***********************************************************************/
6628 void    ADFI_read_free_chunk_table(
6629 		const unsigned int file_index,
6630 		struct FREE_CHUNK_TABLE *free_chunk_table,
6631 		int *error_return )
6632 {
6633 char	disk_free_chunk_data[ FREE_CHUNK_TABLE_SIZE ] ;
6634 
6635 if( free_chunk_table == NULL ) {
6636    *error_return = NULL_POINTER ;
6637    return ;
6638    } /* end if */
6639 
6640 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
6641    *error_return = ADF_FILE_NOT_OPENED ;
6642    return ;
6643    } /* end if */
6644 
6645 *error_return = NO_ERROR ;
6646 
6647         /** Check the stack for free chunk **/
6648 if ( ADFI_stack_control(file_index, FREE_CHUNKS_BLOCK, FREE_CHUNKS_OFFSET,
6649 	                GET_STK, FREE_CHUNK_STK, FREE_CHUNK_TABLE_SIZE,
6650 	                disk_free_chunk_data ) != NO_ERROR ) {
6651 
6652 	/** Read the free-chunk table off of disk **/
6653   ADFI_read_file( file_index, FREE_CHUNKS_BLOCK, FREE_CHUNKS_OFFSET,
6654 	  FREE_CHUNK_TABLE_SIZE, disk_free_chunk_data, error_return ) ;
6655   if( *error_return != NO_ERROR )
6656      return ;
6657 
6658 	/** Check disk tags **/
6659   if( ADFI_stridx_c( &disk_free_chunk_data[0], free_chunk_table_start_tag ) !=
6660       0 ) {
6661      *error_return = ADF_DISK_TAG_ERROR ;
6662      return ;
6663    } /* end of */
6664 
6665   if( ADFI_stridx_c( &disk_free_chunk_data[FREE_CHUNK_TABLE_SIZE - TAG_SIZE],
6666 	 	     free_chunk_table_end_tag ) != 0 ) {
6667      *error_return = ADF_DISK_TAG_ERROR ;
6668      return ;
6669    } /* end of */
6670 
6671          /** Set the free chunk onto the stack **/
6672   ADFI_stack_control(file_index, FREE_CHUNKS_BLOCK, FREE_CHUNKS_OFFSET,
6673 		     SET_STK, FREE_CHUNK_STK, FREE_CHUNK_TABLE_SIZE,
6674 		     disk_free_chunk_data );
6675 } /* end if */
6676 
6677 	/** Convert into memory **/
6678 strncpy( (char *)free_chunk_table->start_tag, &disk_free_chunk_data[ 0],
6679 								TAG_SIZE ) ;
6680 strncpy( (char *)free_chunk_table->end_tag,
6681 	&disk_free_chunk_data[ FREE_CHUNK_TABLE_SIZE - TAG_SIZE ], TAG_SIZE ) ;
6682 
6683 #ifdef NEW_DISK_POINTER
6684 ADFI_read_disk_pointer( file_index, &disk_free_chunk_data[ TAG_SIZE],
6685 	&disk_free_chunk_data[DISK_POINTER_SIZE],
6686 	&free_chunk_table->small_first_block, error_return ) ;
6687 #else
6688 ADFI_disk_pointer_from_ASCII_Hex( &disk_free_chunk_data[ TAG_SIZE],
6689 	&disk_free_chunk_data[DISK_POINTER_SIZE],
6690 	&free_chunk_table->small_first_block, error_return ) ;
6691 #endif
6692 if( *error_return != NO_ERROR )
6693    return ;
6694 
6695 #ifdef NEW_DISK_POINTER
6696 ADFI_read_disk_pointer( file_index, &disk_free_chunk_data[16],
6697 	&disk_free_chunk_data[24], &free_chunk_table->small_last_block,
6698 	error_return ) ;
6699 #else
6700 ADFI_disk_pointer_from_ASCII_Hex( &disk_free_chunk_data[16],
6701 	&disk_free_chunk_data[24], &free_chunk_table->small_last_block,
6702 	error_return ) ;
6703 #endif
6704 if( *error_return != NO_ERROR )
6705    return ;
6706 
6707 #ifdef NEW_DISK_POINTER
6708 ADFI_read_disk_pointer( file_index, &disk_free_chunk_data[28],
6709 	&disk_free_chunk_data[36], &free_chunk_table->medium_first_block,
6710 	error_return ) ;
6711 #else
6712 ADFI_disk_pointer_from_ASCII_Hex( &disk_free_chunk_data[28],
6713 	&disk_free_chunk_data[36], &free_chunk_table->medium_first_block,
6714 	error_return ) ;
6715 #endif
6716 if( *error_return != NO_ERROR )
6717    return ;
6718 
6719 #ifdef NEW_DISK_POINTER
6720 ADFI_read_disk_pointer( file_index, &disk_free_chunk_data[40],
6721 	&disk_free_chunk_data[48], &free_chunk_table->medium_last_block,
6722 	error_return ) ;
6723 #else
6724 ADFI_disk_pointer_from_ASCII_Hex( &disk_free_chunk_data[40],
6725 	&disk_free_chunk_data[48], &free_chunk_table->medium_last_block,
6726 	error_return ) ;
6727 #endif
6728 if( *error_return != NO_ERROR )
6729    return ;
6730 
6731 #ifdef NEW_DISK_POINTER
6732 ADFI_read_disk_pointer( file_index, &disk_free_chunk_data[52],
6733 	&disk_free_chunk_data[60], &free_chunk_table->large_first_block,
6734 	error_return ) ;
6735 #else
6736 ADFI_disk_pointer_from_ASCII_Hex( &disk_free_chunk_data[52],
6737 	&disk_free_chunk_data[60], &free_chunk_table->large_first_block,
6738 	error_return ) ;
6739 #endif
6740 if( *error_return != NO_ERROR )
6741    return ;
6742 
6743 #ifdef NEW_DISK_POINTER
6744 ADFI_read_disk_pointer( file_index, &disk_free_chunk_data[64],
6745 	&disk_free_chunk_data[72], &free_chunk_table->large_last_block,
6746 	error_return ) ;
6747 #else
6748 ADFI_disk_pointer_from_ASCII_Hex( &disk_free_chunk_data[64],
6749 	&disk_free_chunk_data[72], &free_chunk_table->large_last_block,
6750 	error_return ) ;
6751 #endif
6752 if( *error_return != NO_ERROR )
6753    return ;
6754 
6755 	/** Check memory tags **/
6756 if( ADFI_stridx_c( free_chunk_table->start_tag, free_chunk_table_start_tag )
6757 		!= 0 ) {
6758    *error_return = ADF_MEMORY_TAG_ERROR ;
6759    return ;
6760    } /* end of */
6761 
6762 if( ADFI_stridx_c( free_chunk_table->end_tag, free_chunk_table_end_tag )
6763 		!= 0 ) {
6764    *error_return = ADF_MEMORY_TAG_ERROR ;
6765    return ;
6766    } /* end of */
6767 
6768 } /* end of ADFI_read_free_chunk_table */
6769 /* end of file ADFI_read_free_chunk_table.c */
6770 /* file ADFI_read_node_header.c */
6771 /***********************************************************************
6772 ADFI read node header:
6773 
6774 input:  const unsigned int file_index	The file index.
6775 input:  const struct DISK_POINTER *block_offset  Block & offset in the file.
6776 output: struct NODE_HEADER *node_header	Pointer to node header.
6777 output:	int *error_return		Error return.
6778 
6779    Possible errors:
6780 NO_ERROR
6781 NULL_POINTER
6782 ADF_FILE_NOT_OPENED
6783 ADF_DISK_TAG_ERROR
6784 ADF_MEMORY_TAG_ERROR
6785 ***********************************************************************/
6786 void	ADFI_read_node_header(
6787 		const unsigned int file_index,
6788 		const struct DISK_POINTER *block_offset,
6789 		struct NODE_HEADER *node_header,
6790 		int *error_return )
6791 {
6792 char	disk_node_data[ NODE_HEADER_SIZE ] ;
6793 int	i ;
6794 
6795 if( (block_offset == NULL) || (node_header == NULL) ) {
6796    *error_return = NULL_POINTER ;
6797    return ;
6798    } /* end if */
6799 
6800 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
6801    *error_return = ADF_FILE_NOT_OPENED ;
6802    return ;
6803    } /* end if */
6804 
6805 *error_return = NO_ERROR ;
6806 
6807         /** Check the stack for header **/
6808 if ( ADFI_stack_control(file_index, block_offset->block,
6809 			(unsigned int)block_offset->offset,
6810 			GET_STK, NODE_STK, NODE_HEADER_SIZE,
6811 			disk_node_data ) != NO_ERROR ) {
6812 
6813 	/** Get the node header from disk **/
6814   ADFI_read_file( file_index, block_offset->block, block_offset->offset,
6815   	NODE_HEADER_SIZE, disk_node_data, error_return ) ;
6816   if( *error_return != NO_ERROR )
6817      return ;
6818 
6819 	/** Check disk tags **/
6820   if( ADFI_stridx_c( &disk_node_data[0], node_start_tag ) != 0 ) {
6821      *error_return = ADF_DISK_TAG_ERROR ;
6822      return ;
6823    } /* end of */
6824 
6825   if( ADFI_stridx_c( &disk_node_data[ NODE_HEADER_SIZE - TAG_SIZE ],
6826 		node_end_tag ) != 0 ) {
6827      *error_return = ADF_DISK_TAG_ERROR ;
6828      return ;
6829    } /* end if */
6830 
6831          /** Set the header onto the stack **/
6832   ADFI_stack_control(file_index, block_offset->block,
6833 		(unsigned int)block_offset->offset,
6834 		SET_STK, NODE_STK,  NODE_HEADER_SIZE, disk_node_data );
6835 } /* end if */
6836 
6837 	/** Convert into memory **/
6838 strncpy( (char *)node_header->node_start_tag, &disk_node_data[ 0], TAG_SIZE ) ;
6839 strncpy( (char *)node_header->node_end_tag,
6840 	&disk_node_data[ NODE_HEADER_SIZE - TAG_SIZE], TAG_SIZE ) ;
6841 
6842 strncpy( (char *)node_header->name,  &disk_node_data[ TAG_SIZE],
6843 		ADF_NAME_LENGTH ) ;
6844 strncpy( (char *)node_header->label, &disk_node_data[ 36], ADF_LABEL_LENGTH ) ;
6845 
6846 ADFI_ASCII_Hex_2_unsigned_int( 0, MAXIMUM_32_BITS, 8, &disk_node_data[ 68],
6847 	&node_header->num_sub_nodes, error_return ) ;
6848 if( *error_return != NO_ERROR )
6849    return ;
6850 
6851 ADFI_ASCII_Hex_2_unsigned_int( 0, MAXIMUM_32_BITS, 8, &disk_node_data[ 76],
6852 	&node_header->entries_for_sub_nodes, error_return ) ;
6853 if( *error_return != NO_ERROR )
6854    return ;
6855 
6856 #ifdef NEW_DISK_POINTER
6857 ADFI_read_disk_pointer( file_index, &disk_node_data[84], &disk_node_data[92],
6858 	&node_header->sub_node_table, error_return ) ;
6859 #else
6860 ADFI_disk_pointer_from_ASCII_Hex( &disk_node_data[84], &disk_node_data[92],
6861 	&node_header->sub_node_table, error_return ) ;
6862 #endif
6863 if( *error_return != NO_ERROR )
6864    return ;
6865 
6866 strncpy( (char *)node_header->data_type, &disk_node_data[ 96],
6867 			ADF_DATA_TYPE_LENGTH ) ;
6868 
6869 ADFI_ASCII_Hex_2_unsigned_int( 0, 12, 2, &disk_node_data[128],
6870 		&node_header->number_of_dimensions, error_return ) ;
6871 if( *error_return != NO_ERROR )
6872    return ;
6873 
6874 if (ADF_file[file_index].old_version) {
6875    unsigned int dim;
6876    for( i=0; i<ADF_MAX_DIMENSIONS; i++ ) {
6877       ADFI_ASCII_Hex_2_unsigned_int( 0, MAXIMUM_32_BITS, 8,
6878 	&disk_node_data[130+(i*8)], &dim, error_return ) ;
6879       if( *error_return != NO_ERROR )
6880          return ;
6881       node_header->dimension_values[i] = dim;
6882    } /* end for */
6883 } else {
6884    ADFI_convert_integers(8, 12, ADF_file[file_index].format, ADF_this_machine_format,
6885 	   &disk_node_data[130], (char *)node_header->dimension_values, error_return);
6886    if( *error_return != NO_ERROR ) return ;
6887 }
6888 
6889 ADFI_ASCII_Hex_2_unsigned_int( 0, 65535, 4, &disk_node_data[226],
6890 	&node_header->number_of_data_chunks, error_return ) ;
6891 if( *error_return != NO_ERROR )
6892    return ;
6893 
6894 #ifdef NEW_DISK_POINTER
6895 ADFI_read_disk_pointer( file_index, &disk_node_data[230], &disk_node_data[238],
6896 	&node_header->data_chunks, error_return ) ;
6897 #else
6898 ADFI_disk_pointer_from_ASCII_Hex( &disk_node_data[230], &disk_node_data[238],
6899 	&node_header->data_chunks, error_return ) ;
6900 #endif
6901 if( *error_return != NO_ERROR )
6902    return ;
6903 
6904 	/** Check memory tags **/
6905 if( ADFI_stridx_c( node_header->node_start_tag, node_start_tag ) != 0 ) {
6906    *error_return = ADF_MEMORY_TAG_ERROR ;
6907    return ;
6908    } /* end of */
6909 
6910 if( ADFI_stridx_c( node_header->node_end_tag, node_end_tag ) != 0 ) {
6911    *error_return = ADF_MEMORY_TAG_ERROR ;
6912    return ;
6913    } /* end of */
6914 
6915 } /* end of ADFI_read_node_header */
6916 /* end of file ADFI_read_node_header.c */
6917 /* file ADFI_read_sub_node_table.c */
6918 /***********************************************************************
6919 ADFI read sub node table:
6920 
6921 	At this point, reading of the ENTIRE table is required.
6922 
6923 input:  const unsigned int file_index	The file index.
6924 input:  const struct DISK_POINTER *block_offset  Block & offset in the file.
6925 output: struct SUB_NODE_TABLE_ENTRY sub_node_table[] Array of SN entries.
6926 output:	int *error_return		Error return.
6927 
6928    Possible errors:
6929 NO_ERROR
6930 NULL_POINTER
6931 ADF_FILE_NOT_OPENED
6932 ***********************************************************************/
6933 void    ADFI_read_sub_node_table(
6934 		const unsigned int file_index,
6935 		const struct DISK_POINTER *block_offset,
6936 		struct SUB_NODE_TABLE_ENTRY sub_node_table[],
6937 		int *error_return )
6938 {
6939 char			tag[TAG_SIZE + 1] ;
6940 struct DISK_POINTER	end_of_chunk_tag, current_child ;
6941 unsigned int		number_of_children, i ;
6942 
6943 if( (block_offset == NULL) || (sub_node_table == NULL) ) {
6944    *error_return = NULL_POINTER ;
6945    return ;
6946    } /* end if */
6947 
6948 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
6949    *error_return = ADF_FILE_NOT_OPENED ;
6950    return ;
6951    } /* end if */
6952 
6953 *error_return = NO_ERROR ;
6954 
6955 	/** Get tag and length **/
6956 ADFI_read_chunk_length( file_index, block_offset, tag,
6957                         &end_of_chunk_tag, error_return ) ;
6958 if( *error_return != NO_ERROR )
6959    return ;
6960 tag[TAG_SIZE] = '\0' ;
6961 
6962 	/** calculate the number of chuldren in the sub-node table **/
6963 number_of_children = (unsigned int)(
6964       (end_of_chunk_tag.block - block_offset->block) * DISK_BLOCK_SIZE +
6965       (end_of_chunk_tag.offset - block_offset->offset) ) /
6966 		(DISK_POINTER_SIZE + ADF_NAME_LENGTH) ;
6967 
6968 current_child.block = block_offset->block ;
6969 current_child.offset = block_offset->offset + TAG_SIZE + DISK_POINTER_SIZE ;
6970 ADFI_adjust_disk_pointer( &current_child, error_return ) ;
6971 if( *error_return != NO_ERROR )
6972    return ;
6973 
6974 	/** Read and convert the variable-length table into memory **/
6975 for( i=0; i<number_of_children; i++ ) {
6976    ADFI_adjust_disk_pointer( &current_child, error_return ) ;
6977    if( *error_return != NO_ERROR )
6978       return ;
6979 
6980    ADFI_read_file( file_index, current_child.block, current_child.offset,
6981 	ADF_NAME_LENGTH, sub_node_table[i].child_name, error_return ) ;
6982    if( *error_return != NO_ERROR )
6983       return ;
6984 
6985    current_child.offset += ADF_NAME_LENGTH ;
6986    ADFI_adjust_disk_pointer( &current_child, error_return ) ;
6987    if( *error_return != NO_ERROR )
6988       return ;
6989 
6990    ADFI_read_disk_pointer_from_disk( file_index, current_child.block,
6991 	current_child.offset, &sub_node_table[i].child_location,
6992 	error_return ) ;
6993    if( *error_return != NO_ERROR )
6994       return ;
6995 
6996    current_child.offset += DISK_POINTER_SIZE ;
6997    } /* end for */
6998 
6999 } /* end of ADFI_read_sub_node_table */
7000 /* end of file ADFI_read_sub_node_table.c */
7001 /* file ADFI_read_sub_node_table_entry.c */
7002 /***********************************************************************
7003 ADFI read sub node table entry:
7004 
7005 	Read a single sub-node-table entry.
7006 	No boundary checking is possible!
7007 
7008 input:  const unsigned int file_index	The file index.
7009 input:  const struct DISK_POINTER *block_offset  Block & offset in the file.
7010 output: struct SUB_NODE_TABLE_ENTRY *sub_node_table_entry The result.
7011 output:	int *error_return		Error return.
7012 
7013    Possible errors:
7014 NO_ERROR
7015 NULL_POINTER
7016 ADF_FILE_NOT_OPENED
7017 ***********************************************************************/
7018 void    ADFI_read_sub_node_table_entry(
7019 		const unsigned int file_index,
7020 		const struct DISK_POINTER *block_offset,
7021 		struct SUB_NODE_TABLE_ENTRY *sub_node_table_entry,
7022 		int *error_return )
7023 {
7024 char	sub_node_entry_disk_data[ ADF_NAME_LENGTH + DISK_POINTER_SIZE ] ;
7025 
7026 if( (block_offset == NULL) || (sub_node_table_entry == NULL) ) {
7027    *error_return = NULL_POINTER ;
7028    return ;
7029    } /* end if */
7030 
7031 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
7032    *error_return = ADF_FILE_NOT_OPENED ;
7033    return ;
7034    } /* end if */
7035 
7036 *error_return = NO_ERROR ;
7037 
7038         /** Check the stack for subnode **/
7039 if ( ADFI_stack_control(file_index, block_offset->block,
7040 		    (unsigned int)block_offset->offset,
7041 	            GET_STK, SUBNODE_STK, ADF_NAME_LENGTH + DISK_POINTER_SIZE,
7042 		    sub_node_entry_disk_data ) != NO_ERROR ) {
7043 
7044 	/** Read the entry from disk **/
7045   ADFI_read_file( file_index, block_offset->block, block_offset->offset,
7046 	  ADF_NAME_LENGTH + DISK_POINTER_SIZE, sub_node_entry_disk_data,
7047 	  error_return ) ;
7048   if( *error_return != NO_ERROR )
7049      return ;
7050 
7051          /** Set the subnode onto the stack **/
7052   ADFI_stack_control(file_index, block_offset->block,
7053 		     (unsigned int)block_offset->offset,
7054 		     SET_STK, SUBNODE_STK, ADF_NAME_LENGTH + DISK_POINTER_SIZE,
7055 		     sub_node_entry_disk_data );
7056 } /* end if */
7057 
7058 	/** Copy the name **/
7059 strncpy( sub_node_table_entry->child_name, &sub_node_entry_disk_data[0],
7060 		ADF_NAME_LENGTH ) ;
7061 
7062 	/** Convert the disk-pointer **/
7063 #ifdef NEW_DISK_POINTER
7064 ADFI_read_disk_pointer( file_index, &sub_node_entry_disk_data[ ADF_NAME_LENGTH ],
7065 	&sub_node_entry_disk_data[ ADF_NAME_LENGTH + 8 ],
7066 	&sub_node_table_entry->child_location, error_return ) ;
7067 #else
7068 ADFI_disk_pointer_from_ASCII_Hex( &sub_node_entry_disk_data[ ADF_NAME_LENGTH ],
7069 	&sub_node_entry_disk_data[ ADF_NAME_LENGTH + 8 ],
7070 	&sub_node_table_entry->child_location, error_return ) ;
7071 #endif
7072 if( *error_return != NO_ERROR )
7073    return ;
7074 } /* end of ADFI_read_sub_node_table_entry */
7075 /* end of file ADFI_read_sub_node_table_entry.c */
7076 /* file ADFI_remember_file_format.c */
7077 /**********************************************************************
7078 ADFI remember file format:
7079 	Track the file format used:
7080 
7081 input:  const int file_index		Index for the file.
7082 input:  const char numeric_format	Format for the file.
7083 input:  const char os_size	        operating system size for the file.
7084 output: int *error_return		Error return.
7085 
7086    Possible errors:
7087 NO_ERROR
7088 FILE_INDEX_OUT_OF_RANGE
7089 **********************************************************************/
7090 void    ADFI_remember_file_format(
7091 		const int file_index,
7092 		const char numeric_format,
7093 		const char os_size,
7094 		int *error_return )
7095 {
7096 if( (file_index < 0) || (file_index >= maximum_files) ) {
7097    *error_return = FILE_INDEX_OUT_OF_RANGE ;
7098    return ;
7099    } /* end if */
7100 
7101 *error_return = NO_ERROR ;
7102 ADF_file[file_index].format  = numeric_format ;
7103 ADF_file[file_index].os_size = os_size ;
7104 }
7105 /* end of file ADFI_remember_file_format.c */
7106 /* file ADFI_remember_version_update.c */
7107 /***********************************************************************
7108 ADFI remember version update:
7109     Stores the what-string (which contains the file version number) so
7110     that it can be written after the first successful update.  After the
7111     file has been updated once, the remembered what-string is "forgotten".
7112 
7113 input:  const int  file_index    File index to write to.
7114 input:  const char *what_string  What string to remember (contains version)
7115 output:	int *error_return        Error return.
7116 
7117    Possible errors:
7118 FILE_INDEX_OUT_OF_RANGE
7119 NULL_STRING_POINTER
7120 STRING_LENGTH_ZERO
7121 ***********************************************************************/
7122 void	ADFI_remember_version_update(
7123         const int  file_index,
7124         const char *what_string,
7125         int *error_return )
7126 {
7127 
7128 *error_return = NO_ERROR ;
7129 
7130 if( (file_index < 0) || (file_index >= maximum_files) ) {
7131    *error_return = FILE_INDEX_OUT_OF_RANGE ;
7132    return ;
7133    } /* end if */
7134 
7135 if( what_string == NULL ) {
7136    *error_return = NULL_STRING_POINTER ;
7137    return;
7138    } /* end if */
7139 
7140 if( what_string[0] == '\0' ) {
7141    *error_return = STRING_LENGTH_ZERO ;
7142    return;
7143    } /* end if */
7144 
7145 if( strlen( what_string ) > WHAT_STRING_SIZE ) {
7146    *error_return = STRING_LENGTH_TOO_BIG ;
7147    return ;
7148    } /* end if */
7149 
7150 strcpy( ADF_file[file_index].version_update, what_string ) ;
7151 
7152 } /* end of ADFI_remember_version_update */
7153 /* end of file ADFI_remember_version_update.c */
7154 /* file ADFI_set_blank_disk_pointer.c */
7155 /**********************************************************************
7156 ADFI_set_blank_disk_pointer:
7157 	Set the block and offset to the defined "blank", or unused values.
7158 
7159 output: struct DISK_POINTER *block_offset  Block & offset in the file.
7160 
7161    Possible errors:
7162 None allowed
7163 **********************************************************************/
7164 void	ADFI_set_blank_disk_pointer(
7165 		struct DISK_POINTER *block_offset )
7166 {
7167 block_offset->block = BLANK_FILE_BLOCK ;
7168 block_offset->offset = BLANK_BLOCK_OFFSET ;
7169 } /* end of ADFI_set_blank_disk_pointer */
7170 /* end of file ADFI_set_blank_disk_pointer.c */
7171 /* file ADFI_stack_control.c */
7172 /***********************************************************************
7173 ADFI stack control:
7174 
7175 input:  const unsigned int file_index	The file index.
7176 input:	const unsigned long file_block	Block within the file.
7177 input:	const unsigned long block_offset Offset within the block.
7178 input:  const int stack_mode  Control mode: INIT, GET or SET
7179 input;  const int stack_type  Type of stack entry to process: FILE, NODE, etc..
7180 input:	const unsigned int data_length	Length of the data to buffer.
7181 input/output: char *stack_data  The character string buffered, is input for
7182                                 mode SET and output for mode GET.
7183 
7184    Possible errors:
7185 NO_ERROR
7186 NULL_STRING_POINTER
7187 ADF_FILE_NOT_OPENED
7188 PRISTK_NOT_FOUND
7189    Note: errors are only important for GET mode since you must then go ahead
7190    and read the data fom the file. The stack is only meant to speed things
7191    up, not stop the process !!!
7192 ***********************************************************************/
7193 int     ADFI_stack_control( const unsigned int file_index,
7194 		            const cgulong_t file_block,
7195 		            const unsigned int block_offset,
7196 			    const int stack_mode,
7197 			    const int stack_type,
7198 		            const unsigned int data_length,
7199 			    char *stack_data )
7200 {
7201 int i;
7202 int low_priority;
7203 int insert_index = 0;
7204 int found;
7205 
7206 if( stack_data == NULL && (stack_mode == GET_STK || stack_mode == SET_STK) ) {
7207    return NULL_STRING_POINTER ;
7208    } /* end if */
7209 
7210 if( ((int)file_index >= maximum_files || ADF_file[file_index].in_use == 0) &&
7211     stack_mode != INIT_STK ) {
7212    return ADF_FILE_NOT_OPENED ;
7213    } /* end if */
7214 
7215 /* Process depending on the mode */
7216 
7217    switch( stack_mode ) {
7218       case INIT_STK:
7219       case CLEAR_STK:
7220       case CLEAR_STK_TYPE:
7221 	/* Clear all entries with current file_index and or type,
7222 	   if file_index is 0 then clear all the entries!! */
7223 	 for (i=0; i<MAX_STACK; i++) {
7224 	   if ( stack_mode == INIT_STK ) PRISTK[i].priority_level = -1;
7225 	   else if ( (int) file_index != PRISTK[i].file_index &&
7226 		     file_index != 0 ) continue;
7227 	   if ( stack_mode == CLEAR_STK_TYPE &&
7228 		stack_type != PRISTK[i].stack_type ) continue ;
7229 	   /* Valid entry so clear it! */
7230 	   if ( PRISTK[i].priority_level > 0 ) free(PRISTK[i].stack_data);
7231 	   PRISTK[i].file_index     = -1;
7232 	   PRISTK[i].file_block     = 0;
7233 	   PRISTK[i].block_offset   = 0;
7234 	   PRISTK[i].stack_type     = -1;
7235 	   PRISTK[i].priority_level = -1;
7236 	 } /* end for */
7237          /* just in case link or linked-to node deleted */
7238          last_link_ID = 0.0;
7239 	 break ;
7240       case GET_STK:
7241 	/* Try and find the entry in the current stack by matching the
7242 	   file index, block and offset, if found copy data else if
7243 	   not return with an error.   */
7244 	 for (i=0; i<MAX_STACK; i++) {
7245 	 /* Very time consuming task */
7246 	   if ( PRISTK[i].file_index   != (int) file_index ||
7247 		PRISTK[i].file_block   != file_block ||
7248 		PRISTK[i].block_offset != (unsigned int)block_offset ) continue;
7249 	   if ( PRISTK[i].stack_type == stack_type ) {
7250   	     /* Found the entry so copy it into return string */
7251 	     memcpy( stack_data, PRISTK[i].stack_data, (size_t)data_length );
7252 	     /* Up its priority to number one */
7253 	     PRISTK[i].priority_level = 1;
7254 	     return NO_ERROR;
7255 	   } /* end if */
7256 	   else {
7257 	     /* Type doesn't match so delete the bad entry */
7258 	     free(PRISTK[i].stack_data);
7259 	     PRISTK[i].file_index     = -1;
7260 	     PRISTK[i].file_block     = 0;
7261 	     PRISTK[i].block_offset   = 0;
7262 	     PRISTK[i].stack_type     = -1;
7263 	     PRISTK[i].priority_level = -1;
7264 	   } /* end else */
7265 	 } /* end for */
7266 	 /* Didn't find it, bummer, so return an error */
7267 	 return PRISTK_NOT_FOUND;
7268       case DEL_STK_ENTRY:
7269 	/** Try and find the entry and delete it from the stack **/
7270 	 for (i=0; i<MAX_STACK; i++) {
7271 	   if ( PRISTK[i].file_index   == (int) file_index &&
7272 		PRISTK[i].file_block   == file_block &&
7273 		PRISTK[i].block_offset == (unsigned int)block_offset ) {
7274 	     free(PRISTK[i].stack_data);
7275 	     PRISTK[i].file_index     = -1;
7276 	     PRISTK[i].file_block     = 0;
7277 	     PRISTK[i].block_offset   = 0;
7278 	     PRISTK[i].stack_type     = -1;
7279 	     PRISTK[i].priority_level = -1;
7280 	     return NO_ERROR ;
7281 	   } /* end if */
7282 	 } /* end for */
7283 	 break ;
7284       case SET_STK:
7285 	/** Try and find the entry or an empty slot or the lowest priority
7286 	   slot. If it exist then it has its priority bumped to number 1 **/
7287 	 found = 'f';
7288 	 low_priority = -1;
7289 	 for (i=0; i<MAX_STACK; i++) {
7290          /* Very time consuming task */
7291 	   if ( PRISTK[i].file_index   == (int) file_index &&
7292 		PRISTK[i].file_block   == file_block &&
7293 		PRISTK[i].block_offset == (unsigned int)block_offset ) {
7294 	     found = 't';
7295 	     /* It exists up its priority to number one */
7296 	     PRISTK[i].priority_level = 1;
7297 	     /* Copy possible new stack data */
7298 	     memcpy( PRISTK[i].stack_data, stack_data, (size_t)data_length );
7299 	   } /* end if */
7300 	   else if ( PRISTK[i].stack_type >= 0 ) {
7301 	     /* Existing entry so lower its priority, if it is the lowest
7302 		then save its index for possible replacement. */
7303 	     if ( PRISTK[i].priority_level > low_priority ) {
7304 	       low_priority = PRISTK[i].priority_level;
7305 	       insert_index = i;
7306 	     } /* end if */
7307 	     PRISTK[i].priority_level++;
7308 	   } /* end else if */
7309 	   else if ( found == 'f' ) {
7310 	     /* An empty entry set pointer for possible insertion */
7311 	     low_priority = MAX_STACK * MAX_STACK;
7312 	     insert_index = i;
7313 	     found = 'e';
7314 	   } /* end else if */
7315 	 } /* end for */
7316 	 /* If the item was already on the stack then we are done */
7317 	 if ( found == 't' ) return NO_ERROR;
7318 	 /* Insert the data onto the stack at the index_insert location. */
7319 	 i = insert_index;
7320 	 if ( PRISTK[i].priority_level > 0 ) free(PRISTK[i].stack_data);
7321    	 PRISTK[i].stack_data = ( char * ) malloc((size_t)data_length*sizeof(char));
7322 	 if ( PRISTK[i].stack_data == NULL ) {
7323 	   /* Error allocating memory buffer so clear stack and punt */
7324 	   PRISTK[i].file_index     = -1;
7325 	   PRISTK[i].file_block     = 0;
7326 	   PRISTK[i].block_offset   = 0;
7327 	   PRISTK[i].stack_type     = -1;
7328 	   PRISTK[i].priority_level = -1;
7329            return NO_ERROR;
7330 	 } /* end if */
7331 	 memcpy( PRISTK[i].stack_data, stack_data, (size_t)data_length );
7332 	 PRISTK[i].file_index     = file_index;
7333 	 PRISTK[i].file_block     = file_block;
7334 	 PRISTK[i].block_offset   = (unsigned int)block_offset;
7335 	 PRISTK[i].stack_type     = stack_type;
7336 	 PRISTK[i].priority_level = 1;
7337 	 break ;
7338       } /* end switch */
7339 
7340    return NO_ERROR;
7341 
7342 } /* end of ADFI_stack_control */
7343 /* end of file ADFI_stack_control.c */
7344 /* file ADFI_stridx_c.c */
7345 /**********************************************************************
7346 ADFI stridx c:
7347         To find the location of a substring within a string.  This
7348         routine is case InSeNsItIvE!!!
7349 
7350         It is NOT assumed that the substring is already upper-case!!!
7351 
7352 input:  const char *str		The string to search in.
7353 input:  const char *substr	The substring to search for.
7354 output: int return-value	The position in str where substr was found.
7355 				-1 if substr was not found.
7356 
7357    Possible errors:
7358 none:  Errors are not allowed.
7359 ***********************************************************************/
7360 int   ADFI_stridx_c(
7361             const char *str,
7362             const char *substr )
7363 {
7364 int     i, j, k ;
7365 
7366 if( str == NULL || substr == NULL || substr[0] == '\0' ) {
7367    return -1 ;  /* not found - nothing to check */
7368 }
7369 
7370 for( i=0; str[i] != '\0'; i++ ) {
7371    for( j=i, k=0; TO_UPPER( str[j] ) == TO_UPPER( substr[k] ); j++ ) {
7372       if( substr[++k] == '\0' )
7373          return i  ; /* the substring was found */
7374       } /* end for */
7375    } /* end for */
7376 return -1  ; /* the substring was not found */
7377 } /* end of ADFI_stridx_c */
7378 /* end of file ADFI_stridx_c.c */
7379 /* file ADFI_string_2_C_string.c */
7380 /**********************************************************************
7381 ADFI string to C string:
7382 	Create a C string of the maximum length (+1 for null) which is
7383 	null terminated and has no trailing blanks.
7384 
7385 input:  const char *string		Input string.
7386 input:  const int string_length		Length of input string to use.
7387 output: char *c_string			Returned C string.
7388 output: int *error_return		Error return.
7389 
7390    Possible errors:
7391 NO_ERROR
7392 NULL_STRING_POINTER
7393 **********************************************************************/
7394 void    ADFI_string_2_C_string(
7395 		const char *string,
7396 		const int string_length,
7397 		char *c_string,
7398 		int *error_return )
7399 {
7400 int	i, iend ;
7401 
7402 if( (string == NULL) || (c_string == NULL) ) {
7403    *error_return = NULL_STRING_POINTER ;
7404    return ;
7405    } /* end if */
7406 
7407 *error_return = NO_ERROR ;
7408 
7409 	/** Search for early NULL termination **/
7410 for( iend=0; iend < string_length; iend++ ) {
7411    if( string[ iend ] == '\0' ) {
7412       break ;
7413       } /* end if */
7414    } /* end for */
7415 iend--;
7416 
7417 	/** Skip and trailing blanks **/
7418 for( ; iend>=0; iend-- ) {
7419    if( string[ iend ] != ' ' ) {
7420       break ;
7421       } /* end if */
7422    } /* end for */
7423 
7424 	/** Copy the non-trailing blank portion of the string **/
7425 for( i=0; i<=iend; i++ )
7426    c_string[i] = string[i] ;
7427 
7428 	/** NULL terminate the C string **/
7429 c_string[i] = '\0' ;
7430 } /* end of ADFI_string_2_C_string */
7431 /* end of file ADFI_string_2_C_string.c */
7432 /* file ADFI_unsigned_int_2_ASCII_Hex.c */
7433 /***********************************************************************
7434 ADFI unsigned int to ASCII hex:
7435 	Convert an unsigned int to an ASCII-Hex string.
7436 
7437 input: const unsigned int number	The integer number to convert to ASCII.
7438 input: const unsigned int minimum	The expected minimum number in the int.
7439 input: const unsigned int maximum	The expected maximum number in the int.
7440 input: const unsigned int string_length The length of the returned string.
7441 output: char string[]		The string.
7442 output: int *error_return	Error return.
7443 
7444    Possible errors:
7445 NO_ERROR
7446 NULL_STRING_POINTER
7447 NUMBER_LESS_THAN_MINIMUM
7448 NUMBER_GREATER_THAN_MAXIMUM
7449 STRING_LENGTH_ZERO
7450 STRING_LENGTH_TOO_BIG
7451 ***********************************************************************/
7452 void	ADFI_unsigned_int_2_ASCII_Hex(
7453 		const unsigned int number,
7454 		const unsigned int minimum,
7455 		const unsigned int maximum,
7456 		const unsigned int string_length,
7457 		char string[],
7458 		int *error_return )
7459 {
7460 unsigned int	i,	/** Index from 0 to string_length - 1 **/
7461 		ir,	/** Index from string_length - 1 to 0 **/
7462 		j,	/** Temoprary integer variable **/
7463 		num ;	/** Working value of the number **/
7464 
7465 if( string == NULL ) {
7466    *error_return = NULL_STRING_POINTER ;
7467    return ;
7468    } /* end if */
7469 
7470 if( number < minimum ) {
7471    *error_return = NUMBER_LESS_THAN_MINIMUM ;
7472    return ;
7473    } /* end if */
7474 
7475 if( number > maximum ) {
7476    *error_return = NUMBER_GREATER_THAN_MAXIMUM ;
7477    return ;
7478    } /* end if */
7479 
7480 if( string_length == 0 ) {
7481    *error_return = STRING_LENGTH_ZERO ;
7482    return ;
7483    } /* end if */
7484 
7485 if( string_length > 8 ) {
7486    *error_return = STRING_LENGTH_TOO_BIG ;
7487    return ;
7488    } /* end if */
7489 
7490 *error_return = NO_ERROR ;
7491 
7492 	/** Convert the number using power-of-2 table **/
7493 num = number ;
7494 for( i=0, ir=string_length - 1; i<string_length; i++, ir-- ) {
7495    if( num >= pows[ ir ] ) {
7496       j = num / pows[ ir ] ;
7497       num = num - j * pows[ ir ] ;
7498       } /* end if */
7499    else
7500       j = 0 ;
7501    string[i] = ASCII_Hex[ j ] ;
7502    } /* end for */
7503 } /* end of ADFI_unsignedlong_2_ASCII_Hex */
7504 /* end of file ADFI_unsigned_int_2_ASCII_Hex.c */
7505 /* file ADFI_write_data_chunk.c */
7506 /***********************************************************************
7507 ADFI write data chunk:
7508 
7509 input:  const unsigned int file_index	The file index.
7510 input:  const struct DISK_POINTER *block_offset  Block & offset in the file.
7511 input:  const struct TOKENIZED_DATA_TYPE *tokenized_data_type Array.
7512 input:  const int data_size		Size of data entity in bytes.
7513 input:  const long chunk_bytes		Number of bytes in data chunk.
7514 input:  const long start_offset		Starting offset into the data chunk
7515 input:  const long total_bytes		Number of bytes to write in data chunk.
7516 input:  const char *data		Pointer to the data. If 0, zero data.
7517 output:	int *error_return		Error return.
7518 
7519    Possible errors:
7520 NO_ERROR
7521 NULL_POINTER
7522 NULL_STRING_POINTER
7523 ADF_FILE_NOT_OPENED
7524 ***********************************************************************/
7525 void    ADFI_write_data_chunk(
7526               const unsigned int file_index,
7527               const struct DISK_POINTER *block_offset,
7528               const struct TOKENIZED_DATA_TYPE *tokenized_data_type,
7529               const int data_size,
7530               const cglong_t chunk_bytes,
7531               const cglong_t start_offset,
7532               const cglong_t total_bytes,
7533               const char *data,
7534               int *error_return )
7535 {
7536 int format_compare ;
7537 struct DISK_POINTER	current_location, end_of_chunk_tag ;
7538 
7539 if( block_offset == NULL ) {
7540    *error_return = NULL_POINTER ;
7541    return ;
7542    } /* end if */
7543 
7544 if( tokenized_data_type == NULL ) {
7545    *error_return = NULL_STRING_POINTER ;
7546    return ;
7547    } /* end if */
7548 
7549 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
7550    *error_return = ADF_FILE_NOT_OPENED ;
7551    return ;
7552    } /* end if */
7553 
7554 if( total_bytes+start_offset > chunk_bytes ) {
7555    *error_return = REQUESTED_DATA_TOO_LONG ;
7556    return ;
7557    } /* end if */
7558 
7559 *error_return = NO_ERROR ;
7560 
7561 	/** Write the tag **/
7562 ADFI_write_file( file_index, block_offset->block, block_offset->offset,
7563 	TAG_SIZE, data_chunk_start_tag, error_return ) ;
7564 if( *error_return != NO_ERROR )
7565    return ;
7566 
7567 	/** Calculate the end-of-chunk-tag pointer **/
7568 end_of_chunk_tag.block = block_offset->block ;
7569 end_of_chunk_tag.offset = block_offset->offset + TAG_SIZE +
7570 		DISK_POINTER_SIZE + chunk_bytes ;
7571 ADFI_adjust_disk_pointer( &end_of_chunk_tag, error_return ) ;
7572 if( *error_return != NO_ERROR )
7573    return ;
7574 
7575 	/** Adjust location and write end-of-chunk pointer **/
7576 current_location.block = block_offset->block ;
7577 current_location.offset = block_offset->offset + TAG_SIZE ;
7578 ADFI_adjust_disk_pointer( &current_location, error_return ) ;
7579 if( *error_return != NO_ERROR )
7580    return ;
7581 
7582 ADFI_write_disk_pointer_2_disk( file_index, current_location.block,
7583 	current_location.offset, &end_of_chunk_tag, error_return ) ;
7584 
7585 current_location.offset += start_offset + DISK_POINTER_SIZE ;
7586 ADFI_adjust_disk_pointer( &current_location, error_return ) ;
7587 if( *error_return != NO_ERROR )
7588    return ;
7589 
7590 	/** write the data **/
7591 if( data == NULL ) { /** Zero out the file data **/
7592 
7593 	/** If the data-pointer is NULL, write zeros to the file **/
7594 
7595 	/** Initialize the block of zeros **/
7596    if( block_of_00_initialized == FALSE ) {
7597       int i ;
7598       for( i=0; i<DISK_BLOCK_SIZE; i++ )
7599          block_of_00[ i ] = '\0' ;
7600       block_of_00_initialized = TRUE ;
7601       } /* end if */
7602 
7603    if( total_bytes > DISK_BLOCK_SIZE ) {
7604       cglong_t t_bytes = total_bytes ;
7605 
7606 	/** If the number of bytes to write is larger than the block of
7607 	    zeros we have, write out a series of zero blocks...
7608 	**/
7609 
7610 	/** write out the remainder of this block **/
7611 assert(current_location.offset <= 0x1fff);
7612       ADFI_write_file( file_index, current_location.block,
7613 	current_location.offset, DISK_BLOCK_SIZE - current_location.offset + 1,
7614 	block_of_00, error_return ) ;
7615       if( *error_return != NO_ERROR )
7616          return ;
7617 
7618       current_location.block++ ;
7619       current_location.offset = 0 ;
7620       t_bytes -= (DISK_BLOCK_SIZE - current_location.offset + 1) ;
7621 
7622 	/** Write blocks of zeros, then a partial block **/
7623       while( t_bytes > 0 ) {
7624 assert(current_location.offset <= 0x1fff);
7625          ADFI_write_file( file_index, current_location.block,
7626 		current_location.offset, MIN( DISK_BLOCK_SIZE, t_bytes),
7627 		block_of_00, error_return ) ;
7628          if( *error_return != NO_ERROR )
7629             return ;
7630          t_bytes -= (MIN( DISK_BLOCK_SIZE, t_bytes)) ;
7631          } /* end while */
7632 
7633       } /* end if */
7634    else {
7635 
7636 	/** Write a partial block of zeros to disk **/
7637 assert(current_location.offset <= 0x1fff);
7638       ADFI_write_file( file_index, current_location.block,
7639 	current_location.offset, total_bytes, block_of_00, error_return ) ;
7640       if( *error_return != NO_ERROR )
7641          return ;
7642       } /* end else */
7643    } /* end if */
7644 else {
7645 
7646       /** check for need of data translation **/
7647    ADFI_file_and_machine_compare( file_index, tokenized_data_type,
7648 				  &format_compare, error_return );
7649    if( *error_return != NO_ERROR )
7650       return ;
7651    if( format_compare == 1 ) {
7652 	/** Write the data to disk **/
7653 assert(current_location.offset <= 0x1fff);
7654       ADFI_write_file( file_index, current_location.block,
7655 		current_location.offset, total_bytes, data, error_return ) ;
7656       if( *error_return != NO_ERROR )
7657          return ;
7658       } /* end if */
7659    else {
7660       ADFI_write_data_translated( file_index, current_location.block,
7661 		current_location.offset, tokenized_data_type, data_size,
7662 		total_bytes, data, error_return ) ;
7663       if( *error_return != NO_ERROR )
7664          return ;
7665       } /* end else */
7666    } /* end else */
7667 
7668 	/** Write the ending tag to disk **/
7669 ADFI_write_file( file_index, end_of_chunk_tag.block, end_of_chunk_tag.offset,
7670 	TAG_SIZE, data_chunk_end_tag, error_return ) ;
7671 if( *error_return != NO_ERROR )
7672    return ;
7673 
7674 } /* end of ADFI_write_data_chunk */
7675 /* end of file ADFI_write_data_chunk.c */
7676 /* file ADFI_write_data_chunk_table.c */
7677 /***********************************************************************
7678 ADFI write data chunk table:
7679 
7680 input:  const unsigned int file_index	The file index.
7681 input:  const struct DISK_POINTER *block_offset  Block & offset in the file.
7682 input:  const int number_of_data_chunks	Number of entries to write.
7683 output: struct DATA_CHUNK_TABLE_ENTRY data_chunk_table[] Array of entries.
7684 output:	int *error_return		Error return.
7685 
7686    Possible errors:
7687 NO_ERROR
7688 NULL_POINTER
7689 ADF_FILE_NOT_OPENED
7690 ***********************************************************************/
7691 void    ADFI_write_data_chunk_table(
7692 		const unsigned int file_index,
7693 		const struct DISK_POINTER *block_offset,
7694 		const int number_of_data_chunks,
7695 		struct DATA_CHUNK_TABLE_ENTRY data_chunk_table[],
7696 		int *error_return )
7697 {
7698 struct DISK_POINTER	disk_pointer, end_of_chunk_tag ;
7699 int			i ;
7700 
7701 if( (block_offset == NULL) || (data_chunk_table == NULL) ) {
7702    *error_return = NULL_POINTER ;
7703    return ;
7704    } /* end if */
7705 
7706 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
7707    *error_return = ADF_FILE_NOT_OPENED ;
7708    return ;
7709    } /* end if */
7710 
7711 *error_return = NO_ERROR ;
7712 
7713 	/** Write Starting boundary tag **/
7714 disk_pointer.block = block_offset->block ;
7715 disk_pointer.offset = block_offset->offset ;
7716 ADFI_write_file( file_index, disk_pointer.block, disk_pointer.offset,
7717 	TAG_SIZE, data_chunk_table_start_tag, error_return ) ;
7718 if( *error_return != NO_ERROR )
7719    return ;
7720 
7721 disk_pointer.offset += TAG_SIZE ;
7722 ADFI_adjust_disk_pointer( &disk_pointer, error_return ) ;
7723 if( *error_return != NO_ERROR )
7724    return ;
7725 
7726 	/** Calculate the end-of-chunk-tag location **/
7727 end_of_chunk_tag.block = disk_pointer.block ;
7728 end_of_chunk_tag.offset = disk_pointer.offset + DISK_POINTER_SIZE +
7729 	number_of_data_chunks * 2 * DISK_POINTER_SIZE ;
7730 ADFI_adjust_disk_pointer( &end_of_chunk_tag, error_return ) ;
7731 if( *error_return != NO_ERROR )
7732    return ;
7733 ADFI_write_disk_pointer_2_disk( file_index, disk_pointer.block,
7734 	disk_pointer.offset, &end_of_chunk_tag, error_return ) ;
7735 if( *error_return != NO_ERROR )
7736    return ;
7737 
7738 	/** Write data chunk table entries **/
7739 disk_pointer.offset += DISK_POINTER_SIZE ;
7740 for( i=0; i<number_of_data_chunks; i++ ) {
7741    ADFI_adjust_disk_pointer( &disk_pointer, error_return ) ;
7742    if( *error_return != NO_ERROR )
7743       return ;
7744    ADFI_write_disk_pointer_2_disk( file_index, disk_pointer.block,
7745 	   disk_pointer.offset, &data_chunk_table[i].start, error_return ) ;
7746    if( *error_return != NO_ERROR )
7747       return ;
7748    disk_pointer.offset += DISK_POINTER_SIZE ;
7749    ADFI_adjust_disk_pointer( &disk_pointer, error_return ) ;
7750    ADFI_write_disk_pointer_2_disk( file_index, disk_pointer.block,
7751 	   disk_pointer.offset, &data_chunk_table[i].end, error_return ) ;
7752    if( *error_return != NO_ERROR )
7753       return ;
7754    disk_pointer.offset += DISK_POINTER_SIZE ;
7755    } /* end for */
7756 
7757 	/** Write Ending boundary tag **/
7758 ADFI_write_file( file_index, end_of_chunk_tag.block, end_of_chunk_tag.offset,
7759 	TAG_SIZE, data_chunk_table_end_tag, error_return ) ;
7760 if( *error_return != NO_ERROR )
7761    return ;
7762 
7763 } /* end of ADFI_write_data_chunk_table */
7764 /* end of file ADFI_write_data_chunk_table.c */
7765 /* file ADFI_write_data_translated.c */
7766 /***********************************************************************
7767 ADFI write data translated:
7768 
7769 input:  const unsigned int file_index	The file index.
7770 input:	const unsigned long file_block	Block within the file.
7771 input:	const unsigned long block_offset Offset within the block.
7772 input:  const struct TOKENIZED_DATA_TYPE *tokenized_data_type Array.
7773 input:  const int data_size		Size of data entity in bytes.
7774 input:  const long total_bytes		Number of bytes expected.
7775 input:  const char *data		Pointer to the data.
7776 output:	int *error_return		Error return.
7777 
7778    Possible errors:
7779 NO_ERROR
7780 ***********************************************************************/
7781 void    ADFI_write_data_translated(
7782 		const unsigned int file_index,
7783 		const cgulong_t file_block,
7784 		const cgulong_t block_offset,
7785 		const struct TOKENIZED_DATA_TYPE *tokenized_data_type,
7786 		const int data_size,
7787 		const cglong_t total_bytes,
7788 		const char *data,
7789 		int *error_return )
7790 {
7791 struct	DISK_POINTER	disk_pointer ;
7792 int	                current_token = -1 ;
7793 int                     machine_size ;
7794 unsigned char		*from_data = (unsigned char *)data ;
7795 unsigned char		*to_data = from_to_data ;
7796 unsigned int		chunk_size ;
7797 unsigned int		delta_from_bytes, delta_to_bytes ;
7798 cgulong_t		number_of_data_elements, number_of_elements_written ;
7799 
7800 if( data_size <= 0 ) {
7801    *error_return = ZERO_LENGTH_VALUE ;
7802    return ;
7803    } /* end if */
7804 
7805   /** Get machine size of element stored in the NULL element **/
7806 do {
7807   machine_size = tokenized_data_type[ ++current_token ].machine_type_size ;
7808 } while( tokenized_data_type[ current_token ].type[0] != 0 ) ;
7809 
7810 disk_pointer.block = file_block ;
7811 disk_pointer.offset = block_offset ;
7812 number_of_data_elements = total_bytes / data_size ;
7813 number_of_elements_written = 0 ;
7814 chunk_size = CONVERSION_BUFF_SIZE / data_size ;
7815 if ( chunk_size < 1 ) {
7816   *error_return = REQUESTED_DATA_TOO_LONG ;
7817   return ;
7818 }
7819 delta_to_bytes = chunk_size * data_size ;
7820 delta_from_bytes = chunk_size * machine_size ;
7821 
7822 while( number_of_elements_written < number_of_data_elements ) {
7823       /** Limit the number to the end of the data. **/
7824    number_of_elements_written += chunk_size ;
7825    if ( number_of_elements_written > number_of_data_elements ) {
7826      chunk_size -= (unsigned int)( number_of_elements_written - number_of_data_elements ) ;
7827      delta_to_bytes   = chunk_size * data_size ;
7828      delta_from_bytes = chunk_size * machine_size ;
7829    }
7830    ADFI_convert_number_format(
7831 		ADF_this_machine_format, /* from format */
7832 		ADF_this_machine_os_size, /* from os size */
7833 		ADF_file[file_index].format, /* to format */
7834 		ADF_file[file_index].os_size, /* to os size */
7835 		TO_FILE_FORMAT,
7836 		tokenized_data_type, chunk_size, from_data,
7837 		to_data, error_return ) ;
7838    if( *error_return != NO_ERROR )
7839       return ;
7840    ADFI_write_file( file_index, disk_pointer.block, disk_pointer.offset,
7841 	  	    delta_to_bytes, (char *)to_data, error_return ) ;
7842    if( *error_return != NO_ERROR )
7843       return ;
7844    from_data += delta_from_bytes ;
7845    disk_pointer.offset += delta_to_bytes ;
7846    if ( disk_pointer.offset > DISK_BLOCK_SIZE ) {
7847      ADFI_adjust_disk_pointer( &disk_pointer, error_return ) ;
7848      if( *error_return != NO_ERROR )
7849         return ;
7850      } /* end if */
7851    } /* end while */
7852 
7853 } /* end of ADFI_write_data_translated */
7854 /* end of file ADFI_write_data_translated.c */
7855 /* file ADFI_write_disk_block.c */
7856 /***********************************************************************
7857 ADFI write disk block:
7858 ***********************************************************************/
7859 void	ADFI_write_disk_block()
7860 {
7861 fprintf(stderr,"Subroutine ADFI_write_disk_block is not yet implemented...\n" ) ;
7862 } /* end of ADFI_write_disk_block */
7863 /* end of file ADFI_write_disk_block.c */
7864 /* file ADFI_write_disk_pointer_2_disk.c */
7865 /***********************************************************************
7866 ADFI write disk pointer 2 disk:
7867 	Given a pointer to a disk pointer, convert it to ASCII Hex
7868 	and write it to disk.
7869 
7870 input:	const unsigned int file_index	File to write to.
7871 input:	const unsigned long file_block	Block within the file.
7872 input:	const unsigned long block_offset Offset within the block.
7873 input:  const struct DISK_POINTER *block_and_offset Disk pointer.
7874 output:	int *error_return		Error return.
7875 
7876    Possible errors:
7877 NO_ERROR
7878 NULL_POINTER
7879 ADF_FILE_NOT_OPENED
7880 ***********************************************************************/
7881 void    ADFI_write_disk_pointer_2_disk(
7882 		const unsigned int file_index,
7883 		const cgulong_t file_block,
7884 		const cgulong_t block_offset,
7885 		const struct DISK_POINTER *block_and_offset,
7886 		int *error_return )
7887 {
7888 char disk_block_offset[DISK_POINTER_SIZE] ;
7889 
7890 if( block_and_offset == NULL ) {
7891    *error_return = NULL_POINTER ;
7892    return ;
7893    } /* end if */
7894 
7895 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
7896    *error_return = ADF_FILE_NOT_OPENED ;
7897    return ;
7898    } /* end if */
7899 
7900 *error_return = NO_ERROR ;
7901 
7902 	/** Convert into ASCII_Hex form **/
7903 #ifdef NEW_DISK_POINTER
7904 ADFI_write_disk_pointer( file_index, block_and_offset, &disk_block_offset[0],
7905 		&disk_block_offset[8], error_return ) ;
7906 #else
7907 ADFI_disk_pointer_2_ASCII_Hex( block_and_offset, &disk_block_offset[0],
7908 		&disk_block_offset[8], error_return ) ;
7909 #endif
7910 if( *error_return != NO_ERROR )
7911    return ;
7912 
7913 	/** Put the block/offset to disk **/
7914 ADFI_write_file( file_index, file_block, block_offset,
7915 	DISK_POINTER_SIZE, disk_block_offset, error_return ) ;
7916 if( *error_return != NO_ERROR )
7917    return ;
7918 
7919        /** Set the block/offset onto the stack **/
7920 #if 0
7921 ADFI_stack_control(file_index, file_block, (unsigned int)block_offset,
7922 		   SET_STK, DISK_PTR_STK, DISK_POINTER_SIZE,
7923 		   disk_block_offset );
7924 #endif
7925 
7926 } /* end of ADFI_write_disk_pointer_2_disk */
7927 /* end of file ADFI_write_disk_pointer_2_disk.c */
7928 
7929 /***********************************************************************/
7930 
7931 cglong_t ADFI_write (
7932         const unsigned int file_index,
7933         const cglong_t data_length,
7934         const char *data)
7935 {
7936    char *data_ptr = (char *)data;
7937    cglong_t bytes_left = data_length;
7938    cglong_t bytes_out = 0;
7939    int nbytes, to_write;
7940 
7941    ADF_sys_err = 0;
7942    while (bytes_left > 0) {
7943       to_write = bytes_left > CG_MAX_INT32 ? CG_MAX_INT32 : (int)bytes_left;
7944       nbytes = (int) WRITE (ADF_file[file_index].file, data_ptr, to_write);
7945       if (-1 == nbytes) {
7946           if (EINTR != errno) {
7947              ADF_sys_err = errno;
7948              return -1;
7949           }
7950       }
7951       else {
7952           bytes_left -= nbytes;
7953           bytes_out += nbytes;
7954           data_ptr += nbytes;
7955       }
7956    }
7957    return bytes_out;
7958 }
7959 
7960 /* file ADFI_write_file.c */
7961 /***********************************************************************
7962 ADFI write file:
7963 	Write a number of bytes to an ADF file, given the file,
7964 	block, and block offset.
7965 
7966 input:	const unsigned int file_index	File to write to.
7967 input:	const unsigned long file_block	Block within the file.
7968 input:	const unsigned long block_offset Offset within the block.
7969 input:	const unsigned int data_length	Length of the data to write.
7970 input:	const char *data		Address of the data.
7971 output:	int *error_return		Error return.
7972 
7973    Possible errors:
7974 NO_ERROR
7975 NULL_STRING_POINTER
7976 ADF_FILE_NOT_OPENED
7977 FWRITE_ERROR
7978 ***********************************************************************/
7979 void	ADFI_write_file(
7980 		const unsigned int file_index,
7981 		const cgulong_t file_block,
7982 		const cgulong_t block_offset,
7983 		const cglong_t data_length,
7984 		const char *data,
7985 		int *error_return )
7986 {
7987 cglong_t iret;
7988 cglong_t end_block;
7989 
7990 if( data == NULL ) {
7991    *error_return = NULL_STRING_POINTER ;
7992    return ;
7993    } /* end if */
7994 
7995 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
7996    *error_return = ADF_FILE_NOT_OPENED ;
7997    return ;
7998    } /* end if */
7999 
8000 *error_return = NO_ERROR ;
8001 
8002      /** If the read buffer overlaps the buffer then reset it to make
8003          sure its current **/
8004 
8005 end_block = file_block+(block_offset+data_length)/DISK_BLOCK_SIZE+1;
8006 if ( last_rd_file == (int) file_index && last_rd_block >= (cglong_t) file_block &&
8007      last_rd_block <= end_block ) {
8008    last_rd_block   = -1;
8009    last_rd_file    = -1;
8010    num_in_rd_block = -1 ;
8011 }
8012 
8013     /** Check to see if we need to flush the write buffer. this happens if we
8014         are writing a large chunk or the write moves out of the current block.
8015 	If the data length is zero then just flush the buffer and return.
8016 	Note that the ADF_modification_date routine will flush the buffer
8017 	after any write operations !! **/
8018 
8019 if( ( (cgulong_t) data_length + block_offset > DISK_BLOCK_SIZE ||
8020       last_wr_block != (cglong_t) file_block || last_wr_file != (int) file_index ||
8021       data_length == 0 ) && flush_wr_block > 0 ) {
8022 
8023         /** Position the file **/
8024    ADFI_fseek_file( last_wr_file, last_wr_block, 0, error_return ) ;
8025    if( *error_return != NO_ERROR ) {
8026       return ;
8027    } /* end if */
8028 
8029 	/** write the buffer **/
8030    iret= ADFI_write( last_wr_file, DISK_BLOCK_SIZE, wr_block_buffer );
8031    flush_wr_block = -2 ; /** Make sure we don't flush twice due to error **/
8032    if( iret != DISK_BLOCK_SIZE ) {
8033      *error_return = FWRITE_ERROR ;
8034      return ;
8035    } /* end if */
8036 
8037      /** If the write buffer overlaps the buffer then reset it to make
8038          sure its current, set flush buffer flag to false. **/
8039    if ( last_wr_file == (int) file_index && last_wr_block >= (cglong_t) file_block &&
8040        last_wr_block <= (cglong_t) end_block ) {
8041       last_wr_block = -2;
8042       last_wr_file  = -2;
8043    }
8044 
8045 }  /* end if */
8046 if ( data_length == 0 ) return; /** Just a buffer flush **/
8047 
8048     /** No need to buffer large pieces of data or to take special
8049         measures to cross block boundaries **/
8050 
8051 if( data_length + block_offset > DISK_BLOCK_SIZE ) {
8052 
8053 	/** Position the file **/
8054    ADFI_fseek_file( file_index, file_block, block_offset, error_return ) ;
8055    if( *error_return != NO_ERROR ) {
8056       return ;
8057    } /* end if */
8058 
8059 	/** write the data **/
8060    iret = ADFI_write( file_index, data_length, data ) ;
8061    if( iret != data_length ) {
8062      *error_return = FWRITE_ERROR ;
8063      return ;
8064    } /* end if */
8065 
8066    return;
8067 } /* end if */
8068 
8069     /** For smaller pieces of data, write a block at a time.  This will improve
8070         performance if neighboring data is written a small piece at a time
8071         (strided reads, file overhead).
8072 
8073         Some assumptions apply to the block size.  With some experimenting,
8074         1K blocks do not offer much improvement.  4K blocks (4096 bytes)
8075         do improve performance remarkably. This is due to the fact that the
8076 	file structure is based of 4K blocks with offsets. Also the CRAY
8077 	loves 4K block writes!!
8078     **/
8079 
8080 if( (cglong_t) file_block != last_wr_block       ||  /*- a different block -*/
8081     (int) file_index != last_wr_file ) {        /*- entirely different file -*/
8082 
8083     /** buffer is not current, re-read **/
8084 
8085   if ( (cglong_t) file_block == last_rd_block && (int) file_index == last_rd_file ) {
8086 
8087     /* Copy data from read buffer */
8088     memcpy( wr_block_buffer, rd_block_buffer, DISK_BLOCK_SIZE );
8089     iret = num_in_rd_block;
8090   }
8091   else {
8092 
8093     /** Position the file **/
8094     ADFI_fseek_file( file_index, file_block, 0, error_return ) ;
8095     if( *error_return != NO_ERROR ) {
8096       return ;
8097      } /* end if */
8098 
8099     /** Read the data from disk **/
8100      iret = ADFI_read( file_index, DISK_BLOCK_SIZE, wr_block_buffer ) ;
8101      if( iret < DISK_BLOCK_SIZE ) {
8102        if ( iret < 0 ) iret = 0;
8103        memset( &wr_block_buffer[iret], (size_t) ' ', (size_t)(DISK_BLOCK_SIZE-iret) );
8104       } /* end if */
8105 
8106   } /* end if */
8107 
8108    /** Remember buffer information **/
8109   last_wr_block  = file_block ;
8110   last_wr_file   = (int)file_index ;
8111 
8112 } /* end if */
8113 
8114    /** Write into the buffer and set flush buffer flag **/
8115 memcpy( &wr_block_buffer[block_offset], data, (size_t)data_length );
8116 flush_wr_block = 1 ;
8117 
8118 } /* end of ADFI_write_file */
8119 /* end of file ADFI_write_file.c */
8120 /* file ADFI_write_file_header.c */
8121 /***********************************************************************
8122 ADFI write file header:
8123 	To take information in the FILE_HEADER structure and format it
8124 	for disk, and write it out.
8125 input:  const int file_index		File index to write to.
8126 input:  const FILE_HEADER *file_header	The file header structure.
8127 output: int *error_return		Error return.
8128 
8129    Possible errors:
8130 NO_ERROR
8131 NULL_POINTER
8132 ADF_FILE_NOT_OPENED
8133 ADF_MEMORY_TAG_ERROR
8134 ADF_DISK_TAG_ERROR
8135 ***********************************************************************/
8136 void    ADFI_write_file_header(
8137         const int file_index,
8138         const struct FILE_HEADER *file_header,
8139         int *error_return )
8140 {
8141 char    disk_header[ FILE_HEADER_SIZE ] ;
8142 
8143 if( file_header == NULL ) {
8144    *error_return = NULL_POINTER ;
8145    return ;
8146    } /* end if */
8147 
8148 if( file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
8149    *error_return = ADF_FILE_NOT_OPENED ;
8150    return ;
8151    } /* end if */
8152 
8153 *error_return = NO_ERROR ;
8154 
8155 	/** Check memory tags for proper data **/
8156 if( strncmp( file_header->tag0, file_header_tags[0], TAG_SIZE )!= 0 ) {
8157    *error_return = ADF_MEMORY_TAG_ERROR ;
8158    return ;
8159    } /* end if */
8160 
8161 if( strncmp( file_header->tag1, file_header_tags[1], TAG_SIZE )!= 0 ) {
8162    *error_return = ADF_MEMORY_TAG_ERROR ;
8163    return ;
8164    } /* end if */
8165 
8166 if( strncmp( file_header->tag2, file_header_tags[2], TAG_SIZE )!= 0 ) {
8167    *error_return = ADF_MEMORY_TAG_ERROR ;
8168    return ;
8169    } /* end if */
8170 
8171 if( strncmp( file_header->tag3, file_header_tags[3], TAG_SIZE )!= 0 ) {
8172    *error_return = ADF_MEMORY_TAG_ERROR ;
8173    return ;
8174    } /* end if */
8175 
8176 if( strncmp( file_header->tag4, file_header_tags[4], TAG_SIZE )!= 0 ) {
8177    *error_return = ADF_MEMORY_TAG_ERROR ;
8178    return ;
8179    } /* end if */
8180 
8181 if( strncmp( file_header->tag5, file_header_tags[5], TAG_SIZE )!= 0 ) {
8182    *error_return = ADF_MEMORY_TAG_ERROR ;
8183    return ;
8184    } /* end if */
8185 
8186 /** OK the memory tags look good, let's format the file header information
8187     into the disk format and write it out.
8188 **/
8189 strncpy( &disk_header[  0], (char *)file_header->what,  WHAT_STRING_SIZE ) ;
8190 strncpy( &disk_header[ 32], (char *)file_header->tag0,  TAG_SIZE ) ;
8191 strncpy( &disk_header[ 36], (char *)file_header->creation_date, DATE_TIME_SIZE);
8192 strncpy( &disk_header[ 64], (char *)file_header->tag1,  TAG_SIZE ) ;
8193 strncpy( &disk_header[ 68], (char *)file_header->modification_date,
8194 							DATE_TIME_SIZE ) ;
8195 strncpy( &disk_header[ 96], (char *)file_header->tag2,  TAG_SIZE ) ;
8196 disk_header[100] = file_header->numeric_format ;
8197 disk_header[101] = file_header->os_size ;
8198 strncpy( &disk_header[102], (char *)file_header->tag3,	TAG_SIZE ) ;
8199 
8200 ADFI_unsigned_int_2_ASCII_Hex( file_header->sizeof_char, 0, 255, 2,
8201 		&disk_header[106], error_return ) ;
8202 if( *error_return != NO_ERROR )
8203    return ;
8204 ADFI_unsigned_int_2_ASCII_Hex( file_header->sizeof_short, 0, 255, 2,
8205 		&disk_header[108], error_return ) ;
8206 if( *error_return != NO_ERROR )
8207    return ;
8208 ADFI_unsigned_int_2_ASCII_Hex( file_header->sizeof_int, 0, 255, 2,
8209 		&disk_header[110], error_return ) ;
8210 if( *error_return != NO_ERROR )
8211    return ;
8212 ADFI_unsigned_int_2_ASCII_Hex( file_header->sizeof_long, 0, 255, 2,
8213 		&disk_header[112], error_return ) ;
8214 if( *error_return != NO_ERROR )
8215    return ;
8216 ADFI_unsigned_int_2_ASCII_Hex( file_header->sizeof_float, 0, 255, 2,
8217 		&disk_header[114], error_return ) ;
8218 if( *error_return != NO_ERROR )
8219    return ;
8220 ADFI_unsigned_int_2_ASCII_Hex( file_header->sizeof_double, 0, 255, 2,
8221 		&disk_header[116], error_return ) ;
8222 if( *error_return != NO_ERROR )
8223    return ;
8224 ADFI_unsigned_int_2_ASCII_Hex( file_header->sizeof_char_p, 0, 255, 2,
8225 		&disk_header[118], error_return ) ;
8226 if( *error_return != NO_ERROR )
8227    return ;
8228 ADFI_unsigned_int_2_ASCII_Hex( file_header->sizeof_short_p, 0, 255, 2,
8229 		&disk_header[120], error_return ) ;
8230 if( *error_return != NO_ERROR )
8231    return ;
8232 ADFI_unsigned_int_2_ASCII_Hex( file_header->sizeof_int_p, 0, 255, 2,
8233 		&disk_header[122], error_return ) ;
8234 if( *error_return != NO_ERROR )
8235    return ;
8236 ADFI_unsigned_int_2_ASCII_Hex( file_header->sizeof_long_p, 0, 255, 2,
8237 		&disk_header[124], error_return ) ;
8238 if( *error_return != NO_ERROR )
8239    return ;
8240 ADFI_unsigned_int_2_ASCII_Hex( file_header->sizeof_float_p, 0, 255, 2,
8241 		&disk_header[126], error_return ) ;
8242 if( *error_return != NO_ERROR )
8243    return ;
8244 ADFI_unsigned_int_2_ASCII_Hex( file_header->sizeof_double_p, 0, 255, 2,
8245 		&disk_header[128], error_return ) ;
8246 if( *error_return != NO_ERROR )
8247    return ;
8248 
8249 strncpy( &disk_header[130], file_header->tag4, TAG_SIZE ) ;
8250 
8251 #ifdef NEW_DISK_POINTER
8252 ADFI_write_disk_pointer( file_index, &file_header->root_node, &disk_header[134],
8253 		&disk_header[142], error_return ) ;
8254 #else
8255 ADFI_disk_pointer_2_ASCII_Hex( &file_header->root_node, &disk_header[134],
8256 		&disk_header[142], error_return ) ;
8257 #endif
8258 if( *error_return != NO_ERROR )
8259    return ;
8260 
8261 #ifdef NEW_DISK_POINTER
8262 ADFI_write_disk_pointer( file_index, &file_header->end_of_file, &disk_header[146],
8263 		&disk_header[154], error_return ) ;
8264 #else
8265 ADFI_disk_pointer_2_ASCII_Hex( &file_header->end_of_file, &disk_header[146],
8266 		&disk_header[154], error_return ) ;
8267 #endif
8268 if( *error_return != NO_ERROR )
8269    return ;
8270 
8271 #ifdef NEW_DISK_POINTER
8272 ADFI_write_disk_pointer( file_index, &file_header->free_chunks, &disk_header[158],
8273 		&disk_header[166], error_return ) ;
8274 #else
8275 ADFI_disk_pointer_2_ASCII_Hex( &file_header->free_chunks, &disk_header[158],
8276 		&disk_header[166], error_return ) ;
8277 #endif
8278 if( *error_return != NO_ERROR )
8279    return ;
8280 
8281 #ifdef NEW_DISK_POINTER
8282 ADFI_write_disk_pointer( file_index, &file_header->extra, &disk_header[170],
8283 		&disk_header[178], error_return ) ;
8284 #else
8285 ADFI_disk_pointer_2_ASCII_Hex( &file_header->extra, &disk_header[170],
8286 		&disk_header[178], error_return ) ;
8287 #endif
8288 if( *error_return != NO_ERROR )
8289    return ;
8290 
8291 strncpy( &disk_header[182], file_header->tag5, TAG_SIZE ) ;
8292 
8293    /** Now write the disk header out... **/
8294 ADFI_write_file( file_index, 0, 0, FILE_HEADER_SIZE, disk_header,
8295 		error_return ) ;
8296    /** Set the header onto the stack **/
8297 ADFI_stack_control(file_index, 0, 0, SET_STK, FILE_STK,
8298 		   FILE_HEADER_SIZE, disk_header );
8299 } /* end of ADFI_write_file_header */
8300 /* end of file ADFI_write_file_header.c */
8301 /* file ADFI_write_free_chunk.c */
8302 /***********************************************************************
8303 ADFI write free chunk:
8304 
8305 input:  const unsigned int file_index	The file index.
8306 input:  const struct DISK_POINTER *block_offset  Block & offset in the file.
8307 input:  const struct FREE_CHUNK *free_chunk Pointer to free-chunk.
8308 output:	int *error_return		Error return.
8309 
8310    Possible errors:
8311 NO_ERROR
8312 NULL_POINTER
8313 ADF_FILE_NOT_OPENED
8314 ADF_MEMORY_TAG_ERROR
8315 ***********************************************************************/
8316 void    ADFI_write_free_chunk(
8317 		const int file_index,
8318 		const struct DISK_POINTER *block_offset,
8319 		const struct FREE_CHUNK *free_chunk,
8320 		int *error_return )
8321 {
8322 unsigned int		i ;
8323 struct	DISK_POINTER	current_location ;
8324 
8325 if( (block_offset == NULL) || (free_chunk == NULL) ) {
8326    *error_return = NULL_POINTER ;
8327    return ;
8328    } /* end if */
8329 
8330 if( file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
8331    *error_return = ADF_FILE_NOT_OPENED ;
8332    return ;
8333    } /* end if */
8334 
8335 *error_return = NO_ERROR ;
8336 
8337 	/** Initialize the block of 'X's **/
8338 if( block_of_XX_initialized == FALSE ) {
8339    for( i=0; i<DISK_BLOCK_SIZE; i++ )
8340       block_of_XX[ i ] = 'x' ;
8341    block_of_XX_initialized = TRUE ;
8342    } /* end if */
8343 
8344 	/** Check memory tags for proper data **/
8345 if( strncmp( free_chunk->start_tag, free_chunk_start_tag, TAG_SIZE )!= 0 ) {
8346    *error_return = ADF_MEMORY_TAG_ERROR ;
8347    return ;
8348    } /* end if */
8349 
8350 if( strncmp( free_chunk->end_tag, free_chunk_end_tag, TAG_SIZE )!= 0 ) {
8351    *error_return = ADF_MEMORY_TAG_ERROR ;
8352    return ;
8353    } /* end if */
8354 
8355 	/** Write start TAG **/
8356 ADFI_write_file( file_index, block_offset->block, block_offset->offset,
8357 		 TAG_SIZE, free_chunk->start_tag, error_return ) ;
8358 if( *error_return != NO_ERROR )
8359    return ;
8360 
8361 	/** Write disk pointers **/
8362 current_location.block = block_offset->block ;
8363 current_location.offset = block_offset->offset + TAG_SIZE ;
8364 ADFI_adjust_disk_pointer( &current_location, error_return ) ;
8365 if( *error_return != NO_ERROR )
8366    return ;
8367 
8368 ADFI_write_disk_pointer_2_disk( file_index, current_location.block,
8369 				current_location.offset,
8370 				&free_chunk->end_of_chunk_tag,
8371 				error_return ) ;
8372 if( *error_return != NO_ERROR )
8373    return ;
8374 
8375 current_location.offset += DISK_POINTER_SIZE ;
8376 ADFI_adjust_disk_pointer( &current_location, error_return ) ;
8377 if( *error_return != NO_ERROR )
8378    return ;
8379 
8380 ADFI_write_disk_pointer_2_disk( file_index, current_location.block,
8381 				current_location.offset,
8382 				&free_chunk->next_chunk,
8383 				error_return ) ;
8384 if( *error_return != NO_ERROR )
8385    return ;
8386 
8387         /** Write out a bunch of 'x's in the free chunk's empty space **/
8388 current_location.offset += DISK_POINTER_SIZE ;
8389 ADFI_adjust_disk_pointer( &current_location, error_return ) ;
8390 if( *error_return != NO_ERROR )
8391    return ;
8392 
8393 	/** Fill in partial end of a block **/
8394 if( (current_location.block != free_chunk->end_of_chunk_tag.block) &&
8395 	(current_location.offset != 0 ) ) {
8396 assert(current_location.offset < DISK_BLOCK_SIZE);
8397    ADFI_write_file( file_index, current_location.block,
8398 	current_location.offset, DISK_BLOCK_SIZE - current_location.offset,
8399 	block_of_XX, error_return ) ;
8400    if( *error_return != NO_ERROR )
8401       return ;
8402    current_location.block++ ;
8403    current_location.offset = 0 ;
8404    } /* end if */
8405 
8406 	/** Fill in intermediate whole blocks **/
8407 while( current_location.block < free_chunk->end_of_chunk_tag.block ) {
8408    ADFI_write_file( file_index, current_location.block,
8409 	0, DISK_BLOCK_SIZE, block_of_XX, error_return ) ;
8410    if( *error_return != NO_ERROR )
8411       return ;
8412    current_location.block++ ;
8413    } /* end if */
8414 
8415 	/** Fill in partial block to end-of-free-chunk **/
8416 if( current_location.offset < free_chunk->end_of_chunk_tag.offset ) {
8417    ADFI_write_file( file_index, current_location.block,
8418 	current_location.offset,
8419 	free_chunk->end_of_chunk_tag.offset - current_location.offset,
8420 	block_of_XX, error_return ) ;
8421    if( *error_return != NO_ERROR )
8422       return ;
8423    } /* end if */
8424 
8425    /** Now (finally) write out the free_chunk-end_tag **/
8426 ADFI_write_file( file_index, current_location.block,
8427 	free_chunk->end_of_chunk_tag.offset, TAG_SIZE, free_chunk->end_tag,
8428 	error_return ) ;
8429 if( *error_return != NO_ERROR )
8430    return ;
8431 
8432 } /* end of ADFI_write_free_chunk */
8433 /* end of file ADFI_write_free_chunk.c */
8434 /* file ADFI_write_free_chunk_table.c */
8435 /***********************************************************************
8436 ADFI write free chunk table:
8437 	To take information in the FREE_CHUNK_TABLE structure and format it
8438 	for disk, and write it out.
8439 input:  const int file_index		File index to write to.
8440 input:  const FREE_CHUNK_TABLE *free_chunk_table  The free_chunk header struct.
8441 output: int *error_return		Error return.
8442 
8443    Possible errors:
8444 NO_ERROR
8445 NULL_POINTER
8446 ADF_FILE_NOT_OPENED
8447 ADF_MEMORY_TAG_ERROR
8448 ***********************************************************************/
8449 void	ADFI_write_free_chunk_table(
8450 		const int file_index,
8451 		const struct FREE_CHUNK_TABLE *free_chunk_table,
8452 		int *error_return )
8453 {
8454 char	disk_free_chunk_data[ FREE_CHUNK_TABLE_SIZE ] ;
8455 
8456 if( free_chunk_table == NULL ) {
8457    *error_return = NULL_POINTER ;
8458    return ;
8459    } /* end if */
8460 
8461 if( file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
8462    *error_return = ADF_FILE_NOT_OPENED ;
8463    return ;
8464    } /* end if */
8465 
8466 *error_return = NO_ERROR ;
8467 
8468 	/** Check memory tags for proper data **/
8469 if( strncmp( free_chunk_table->start_tag, free_chunk_table_start_tag,
8470 							TAG_SIZE ) != 0 ) {
8471    *error_return = ADF_MEMORY_TAG_ERROR ;
8472    return ;
8473    } /* end if */
8474 
8475 if( strncmp( free_chunk_table->end_tag, free_chunk_table_end_tag,
8476 							TAG_SIZE ) != 0 ) {
8477    *error_return = ADF_MEMORY_TAG_ERROR ;
8478    return ;
8479    } /* end if */
8480 
8481 /** OK the memory tags look good, let's format the free_chunk header
8482     information into the disk format and write it out.
8483 **/
8484 strncpy( &disk_free_chunk_data[  0], (char *)free_chunk_table->start_tag,
8485 	TAG_SIZE ) ;
8486 
8487 #ifdef NEW_DISK_POINTER
8488 ADFI_write_disk_pointer( file_index, &free_chunk_table->small_first_block,
8489 	&disk_free_chunk_data[TAG_SIZE],
8490 	&disk_free_chunk_data[DISK_POINTER_SIZE], error_return ) ;
8491 #else
8492 ADFI_disk_pointer_2_ASCII_Hex( &free_chunk_table->small_first_block,
8493 	&disk_free_chunk_data[TAG_SIZE],
8494 	&disk_free_chunk_data[DISK_POINTER_SIZE], error_return ) ;
8495 #endif
8496 if( *error_return != NO_ERROR )
8497    return ;
8498 
8499 #ifdef NEW_DISK_POINTER
8500 ADFI_write_disk_pointer( file_index, &free_chunk_table->small_last_block,
8501 	&disk_free_chunk_data[16], &disk_free_chunk_data[24], error_return ) ;
8502 #else
8503 ADFI_disk_pointer_2_ASCII_Hex( &free_chunk_table->small_last_block,
8504 	&disk_free_chunk_data[16], &disk_free_chunk_data[24], error_return ) ;
8505 #endif
8506 if( *error_return != NO_ERROR )
8507    return ;
8508 
8509 #ifdef NEW_DISK_POINTER
8510 ADFI_write_disk_pointer( file_index, &free_chunk_table->medium_first_block,
8511 	&disk_free_chunk_data[28], &disk_free_chunk_data[36], error_return ) ;
8512 #else
8513 ADFI_disk_pointer_2_ASCII_Hex( &free_chunk_table->medium_first_block,
8514 	&disk_free_chunk_data[28], &disk_free_chunk_data[36], error_return ) ;
8515 #endif
8516 if( *error_return != NO_ERROR )
8517    return ;
8518 
8519 #ifdef NEW_DISK_POINTER
8520 ADFI_write_disk_pointer( file_index, &free_chunk_table->medium_last_block,
8521 	&disk_free_chunk_data[40], &disk_free_chunk_data[48], error_return ) ;
8522 #else
8523 ADFI_disk_pointer_2_ASCII_Hex( &free_chunk_table->medium_last_block,
8524 	&disk_free_chunk_data[40], &disk_free_chunk_data[48], error_return ) ;
8525 #endif
8526 if( *error_return != NO_ERROR )
8527    return ;
8528 
8529 #ifdef NEW_DISK_POINTER
8530 ADFI_write_disk_pointer( file_index, &free_chunk_table->large_first_block,
8531 	&disk_free_chunk_data[52], &disk_free_chunk_data[60], error_return ) ;
8532 #else
8533 ADFI_disk_pointer_2_ASCII_Hex( &free_chunk_table->large_first_block,
8534 	&disk_free_chunk_data[52], &disk_free_chunk_data[60], error_return ) ;
8535 #endif
8536 if( *error_return != NO_ERROR )
8537    return ;
8538 
8539 #ifdef NEW_DISK_POINTER
8540 ADFI_write_disk_pointer( file_index, &free_chunk_table->large_last_block,
8541 	&disk_free_chunk_data[64], &disk_free_chunk_data[72], error_return ) ;
8542 #else
8543 ADFI_disk_pointer_2_ASCII_Hex( &free_chunk_table->large_last_block,
8544 	&disk_free_chunk_data[64], &disk_free_chunk_data[72], error_return ) ;
8545 #endif
8546 if( *error_return != NO_ERROR )
8547    return ;
8548 
8549 strncpy( &disk_free_chunk_data[ 76], (char *)free_chunk_table->end_tag,
8550 	TAG_SIZE ) ;
8551 
8552    /** Now write the free_chunk header out to disk... **/
8553 ADFI_write_file( file_index, FREE_CHUNKS_BLOCK, FREE_CHUNKS_OFFSET,
8554 		FREE_CHUNK_TABLE_SIZE, disk_free_chunk_data, error_return ) ;
8555    /** Set the free chunk onto the stack **/
8556 ADFI_stack_control(file_index, FREE_CHUNKS_BLOCK, FREE_CHUNKS_OFFSET,
8557 		   SET_STK, FREE_CHUNK_STK, FREE_CHUNK_TABLE_SIZE,
8558 		   disk_free_chunk_data );
8559 } /* end of ADFI_write_free_chunk_table */
8560 /* end of file ADFI_write_free_chunk_table.c */
8561 /* file ADFI_write_modification_date.c */
8562 /***********************************************************************
8563 ADFI write modification date:
8564     Writes the current date/time into the modification date field of
8565     the file header.  Also updates the file version (what string)
8566     in the header if the file version global variable has been set -
8567     after writing, file version global variable is unset so that it is
8568     only written once.
8569 
8570 input:  const int  file_index    File index to write to.
8571 output:	int *error_return        Error return.
8572 
8573    Possible errors:
8574 NO_ERROR
8575 NULL_STRING_POINTER
8576 ADF_FILE_NOT_OPENED
8577 FWRITE_ERROR
8578 ***********************************************************************/
8579 void	ADFI_write_modification_date(
8580         const int  file_index,
8581         int *error_return )
8582 {
8583 int	    i_block_offset ;
8584 char    mod_date[DATE_TIME_SIZE] ;
8585 
8586 
8587 *error_return = NO_ERROR ;
8588 
8589 ADFI_get_current_date( mod_date ) ;
8590 
8591      /** block offset depends on the location the of modification date
8592          in the FILE_HEADER structure **/
8593 i_block_offset = WHAT_STRING_SIZE + TAG_SIZE + DATE_TIME_SIZE + TAG_SIZE ;
8594 ADFI_write_file( file_index, 0, i_block_offset, DATE_TIME_SIZE, mod_date,
8595                  error_return ) ;
8596 if( *error_return != NO_ERROR ) {
8597    return;
8598    } /* end if */
8599 
8600      /** Flush the write buffer to ensure the file is current!! **/
8601 ADFI_flush_buffers( file_index, FLUSH, error_return );
8602 if( *error_return != NO_ERROR ) {
8603    return;
8604    } /* end if */
8605 
8606 if( ADF_file[file_index].version_update[0] != '\0' )
8607 {
8608    i_block_offset = 0 ;   /* what-string is first field in header */
8609    ADFI_write_file( file_index, 0, i_block_offset, WHAT_STRING_SIZE,
8610                     ADF_file[file_index].version_update, error_return ) ;
8611 
8612 /** reset the version to default so that it only gets updated once **/
8613    ADF_file[file_index].version_update[0] = '\0' ;
8614    if( *error_return != NO_ERROR ) {
8615       return;
8616       } /* end if */
8617    } /* end if */
8618 
8619 } /* end of ADFI_write_modification_date */
8620 /* end of file ADFI_write_modification_date.c */
8621 /* file ADFI_write_node_header.c */
8622 /***********************************************************************
8623 ADFI write node header:
8624 	To take information in the NODE_HEADER structure and format it
8625 	for disk, and write it out.
8626 input:  const int file_index		File index to write to.
8627 input:  const struct DISK_POINTER *block_offset  Block & offset in the file.
8628 input:  const NODE_HEADER *node_header	The node header structure.
8629 output: int *error_return		Error return.
8630 
8631    Possible errors:
8632 NO_ERROR
8633 NULL_POINTER
8634 ADF_FILE_NOT_OPENED
8635 ADF_MEMORY_TAG_ERROR
8636 ***********************************************************************/
8637 void	ADFI_write_node_header(
8638 		const int file_index,
8639 		const struct DISK_POINTER *block_offset,
8640 		const struct NODE_HEADER *node_header,
8641 		int *error_return )
8642 {
8643 int	i ;
8644 char	disk_node_data[ NODE_HEADER_SIZE ] ;
8645 
8646 if( (block_offset == NULL) || (node_header == NULL) ) {
8647    *error_return = NULL_POINTER ;
8648    return ;
8649    } /* end if */
8650 
8651 if( file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
8652    *error_return = ADF_FILE_NOT_OPENED ;
8653    return ;
8654    } /* end if */
8655 
8656 *error_return = NO_ERROR ;
8657 
8658 /** Check memory tags for proper data **/
8659 if( strncmp( node_header->node_start_tag, node_start_tag, TAG_SIZE )!= 0 ) {
8660    *error_return = ADF_MEMORY_TAG_ERROR ;
8661    return ;
8662    } /* end if */
8663 
8664 if( strncmp( node_header->node_end_tag, node_end_tag, TAG_SIZE )!= 0 ) {
8665    *error_return = ADF_MEMORY_TAG_ERROR ;
8666    return ;
8667    } /* end if */
8668 
8669 /** OK the memory tags look good, let's format the node header information
8670     into the disk format and write it out.
8671 **/
8672 strncpy( &disk_node_data[  0], (char *)node_header->node_start_tag, TAG_SIZE ) ;
8673 strncpy( &disk_node_data[  TAG_SIZE], (char *)node_header->name,
8674 	ADF_NAME_LENGTH );
8675 strncpy( &disk_node_data[ 36], (char *)node_header->label, ADF_LABEL_LENGTH ) ;
8676 
8677 ADFI_unsigned_int_2_ASCII_Hex( node_header->num_sub_nodes, 0,
8678 		MAXIMUM_32_BITS, 8, &disk_node_data[ 68], error_return ) ;
8679 if( *error_return != NO_ERROR )
8680    return ;
8681 
8682 ADFI_unsigned_int_2_ASCII_Hex( node_header->entries_for_sub_nodes, 0,
8683 		MAXIMUM_32_BITS, 8, &disk_node_data[ 76], error_return ) ;
8684 if( *error_return != NO_ERROR )
8685    return ;
8686 
8687 #ifdef NEW_DISK_POINTER
8688 ADFI_write_disk_pointer(file_index, &node_header->sub_node_table,
8689 	&disk_node_data[84], &disk_node_data[92], error_return ) ;
8690 #else
8691 ADFI_disk_pointer_2_ASCII_Hex( &node_header->sub_node_table,
8692 	&disk_node_data[84], &disk_node_data[92], error_return ) ;
8693 #endif
8694 if( *error_return != NO_ERROR )
8695    return ;
8696 
8697 strncpy( &disk_node_data[ 96], (char *)node_header->data_type,
8698 			ADF_DATA_TYPE_LENGTH ) ;
8699 
8700 ADFI_unsigned_int_2_ASCII_Hex( node_header->number_of_dimensions, 0,
8701 		12, 2, &disk_node_data[128], error_return ) ;
8702 if( *error_return != NO_ERROR )
8703    return ;
8704 
8705 if (ADF_file[file_index].old_version) {
8706    for( i=0; i<ADF_MAX_DIMENSIONS; i++ ) {
8707       if (node_header->dimension_values[i] > MAXIMUM_32_BITS) {
8708          *error_return = NUMBER_GREATER_THAN_MAXIMUM ;
8709       } else {
8710          ADFI_unsigned_int_2_ASCII_Hex( (unsigned int)node_header->dimension_values[i], 0,
8711 		MAXIMUM_32_BITS, 8, &disk_node_data[130+(i*8)], error_return ) ;
8712       }
8713       if( *error_return != NO_ERROR )
8714          return ;
8715    } /* end for */
8716 } else {
8717    ADFI_convert_integers(8, 12, ADF_this_machine_format, ADF_file[file_index].format,
8718 	   (char *)node_header->dimension_values, &disk_node_data[130], error_return);
8719    if( *error_return != NO_ERROR ) return ;
8720 }
8721 
8722 ADFI_unsigned_int_2_ASCII_Hex( node_header->number_of_data_chunks, 0,
8723 		65535, 4, &disk_node_data[226], error_return ) ;
8724 if( *error_return != NO_ERROR )
8725    return ;
8726 
8727 #ifdef NEW_DISK_POINTER
8728 ADFI_write_disk_pointer(file_index, &node_header->data_chunks,
8729 	&disk_node_data[230], &disk_node_data[238], error_return ) ;
8730 #else
8731 ADFI_disk_pointer_2_ASCII_Hex( &node_header->data_chunks,
8732 	&disk_node_data[230], &disk_node_data[238], error_return ) ;
8733 #endif
8734 if( *error_return != NO_ERROR )
8735    return ;
8736 
8737 strncpy( &disk_node_data[242], (char *)node_header->node_end_tag, TAG_SIZE ) ;
8738 
8739    /** Now write the node-header out to disk... **/
8740 ADFI_write_file( file_index, block_offset->block, block_offset->offset,
8741 		NODE_HEADER_SIZE, disk_node_data, error_return ) ;
8742    /** Set the header onto the stack **/
8743 ADFI_stack_control(file_index, block_offset->block,
8744 		   (unsigned int)block_offset->offset,
8745 		   SET_STK, NODE_STK, NODE_HEADER_SIZE, disk_node_data );
8746 } /* end of ADFI_write_node_header */
8747 /* end of file ADFI_write_node_header.c */
8748 /* file ADFI_write_sub_node_table.c */
8749 /***********************************************************************
8750 ADFI write sub node table:
8751 
8752 input:  const unsigned int file_index	The file index.
8753 input:  const struct DISK_POINTER *block_offset  Block & offset in the file.
8754 input:  const int number_of_sub_nodes	Number of sub-node entries.
8755 input:  struct SUB_NODE_TABLE_ENTRY sub_node_table[] Array of sub-node entries.
8756 output:	int *error_return		Error return.
8757 
8758    Possible errors:
8759 NO_ERROR
8760 NULL_POINTER
8761 ADF_FILE_NOT_OPENED
8762 ***********************************************************************/
8763 void    ADFI_write_sub_node_table(
8764 		const unsigned int file_index,
8765 		const struct DISK_POINTER *block_offset,
8766 		const int number_of_sub_nodes,
8767 		struct SUB_NODE_TABLE_ENTRY sub_node_table[],
8768 		int *error_return )
8769 {
8770 int			i ;
8771 struct DISK_POINTER	end_of_chunk_tag, current_child ;
8772 
8773 if( (block_offset == NULL) || (sub_node_table == NULL) ) {
8774    *error_return = NULL_POINTER ;
8775    return ;
8776    } /* end if */
8777 
8778 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
8779    *error_return = ADF_FILE_NOT_OPENED ;
8780    return ;
8781    } /* end if */
8782 
8783 *error_return = NO_ERROR ;
8784 
8785 	/** calculate the end-of-chunk tag pointer **/
8786 end_of_chunk_tag.block = block_offset->block ;
8787 end_of_chunk_tag.offset = block_offset->offset + TAG_SIZE + DISK_POINTER_SIZE +
8788 	number_of_sub_nodes * (ADF_NAME_LENGTH + DISK_POINTER_SIZE) ;
8789 ADFI_adjust_disk_pointer( &end_of_chunk_tag, error_return ) ;
8790 if( *error_return != NO_ERROR )
8791    return ;
8792 
8793 	/** Write start TAG **/
8794 ADFI_write_file( file_index, block_offset->block, block_offset->offset,
8795 		 TAG_SIZE, sub_node_start_tag, error_return ) ;
8796 if( *error_return != NO_ERROR )
8797    return ;
8798 
8799 	/** Write disk pointer **/
8800 current_child.block = block_offset->block ;
8801 current_child.offset = block_offset->offset + TAG_SIZE ;
8802 ADFI_adjust_disk_pointer( &current_child, error_return ) ;
8803 if( *error_return != NO_ERROR )
8804    return ;
8805 
8806 ADFI_write_disk_pointer_2_disk( file_index, current_child.block,
8807 				current_child.offset, &end_of_chunk_tag,
8808 				error_return ) ;
8809 if( *error_return != NO_ERROR )
8810    return ;
8811 
8812 	/** Format and write out the table entries **/
8813 current_child.offset += DISK_POINTER_SIZE ;
8814 for( i=0; i<number_of_sub_nodes; i++ ) {
8815    ADFI_adjust_disk_pointer( &current_child, error_return ) ;
8816    if( *error_return != NO_ERROR )
8817       return ;
8818 
8819    ADFI_write_file( file_index, current_child.block, current_child.offset,
8820 	ADF_NAME_LENGTH, sub_node_table[i].child_name, error_return ) ;
8821    if( *error_return != NO_ERROR )
8822       return ;
8823 
8824    current_child.offset += ADF_NAME_LENGTH ;
8825    ADFI_adjust_disk_pointer( &current_child, error_return ) ;
8826    if( *error_return != NO_ERROR )
8827       return ;
8828 
8829    ADFI_write_disk_pointer_2_disk( file_index, current_child.block,
8830         current_child.offset, &sub_node_table[i].child_location,
8831         error_return ) ;
8832    if( *error_return != NO_ERROR )
8833       return ;
8834 
8835    current_child.offset += DISK_POINTER_SIZE ;
8836    } /* end for */
8837 
8838 	/** Write closing tag **/
8839 ADFI_write_file( file_index, end_of_chunk_tag.block, end_of_chunk_tag.offset,
8840 	TAG_SIZE, sub_node_end_tag, error_return ) ;
8841 if( *error_return != NO_ERROR )
8842    return ;
8843 
8844 } /* end of ADFI_write_sub_node_table */
8845 /* end of file ADFI_write_sub_node_table.c */
8846 /* file ADFI_write_sub_node_table_entry.c */
8847 /***********************************************************************
8848 ADFI write sub node table entry:
8849 
8850 input:  const unsigned int file_index	The file index.
8851 input:  const struct DISK_POINTER *block_offset  Block & offset in the file.
8852 input:  struct SUB_NODE_TABLE_ENTRY *sub_node_table_entry
8853 output:	int *error_return		Error return.
8854 
8855    Possible errors:
8856 NO_ERROR
8857 NULL_POINTER
8858 ADF_FILE_NOT_OPENED
8859 ***********************************************************************/
8860 void    ADFI_write_sub_node_table_entry(
8861 		const unsigned int file_index,
8862 		const struct DISK_POINTER *block_offset,
8863 		struct SUB_NODE_TABLE_ENTRY *sub_node_table_entry,
8864 		int *error_return )
8865 {
8866 char	sub_node_entry_disk_data[ ADF_NAME_LENGTH + DISK_POINTER_SIZE ] ;
8867 
8868 if( (block_offset == NULL) || (sub_node_table_entry == NULL) ) {
8869    *error_return = NULL_POINTER ;
8870    return ;
8871    } /* end if */
8872 
8873 if( (int)file_index >= maximum_files || ADF_file[file_index].in_use == 0 ) {
8874    *error_return = ADF_FILE_NOT_OPENED ;
8875    return ;
8876    } /* end if */
8877 
8878 *error_return = NO_ERROR ;
8879 
8880 	/** Format the tag and disk pointer in memory **/
8881 strncpy( &sub_node_entry_disk_data[0], sub_node_table_entry->child_name,
8882 		ADF_NAME_LENGTH ) ;
8883 #ifdef NEW_DISK_POINTER
8884 ADFI_write_disk_pointer( file_index, &sub_node_table_entry->child_location,
8885 	&sub_node_entry_disk_data[ ADF_NAME_LENGTH ],
8886 	&sub_node_entry_disk_data[ ADF_NAME_LENGTH + 8 ], error_return ) ;
8887 #else
8888 ADFI_disk_pointer_2_ASCII_Hex( &sub_node_table_entry->child_location,
8889 	&sub_node_entry_disk_data[ ADF_NAME_LENGTH ],
8890 	&sub_node_entry_disk_data[ ADF_NAME_LENGTH + 8 ], error_return ) ;
8891 #endif
8892 if( *error_return != NO_ERROR )
8893    return ;
8894 
8895 	/** Now write it out to disk **/
8896 ADFI_write_file( file_index, block_offset->block, block_offset->offset,
8897 	ADF_NAME_LENGTH + DISK_POINTER_SIZE,
8898 	sub_node_entry_disk_data, error_return ) ;
8899 if( *error_return != NO_ERROR )
8900    return ;
8901 
8902         /** Set the subnode onto the stack **/
8903 ADFI_stack_control(file_index, block_offset->block,
8904 		   (unsigned int)block_offset->offset,
8905 		   SET_STK, SUBNODE_STK, ADF_NAME_LENGTH + DISK_POINTER_SIZE,
8906 		   sub_node_entry_disk_data );
8907 
8908 } /* end of ADFI_write_sub_node_table_entry */
8909 /* end of file ADFI_write_sub_node_table_entry.c */
8910 /* file ADFI_strtok.c */
8911 /***********************************************************************
8912 ADFI get string token: This routine simulates strtok except it returns the
8913 current position in the string tobe used later. Thas avoids the problem of
8914 trying using strtok in a recursive subroutine call which does not work!
8915 
8916 input/output:  *string     - the string to parse tokens from.
8917                              returns string with token replaced by nil.
8918 input/output:  *string_pos - the string position to begin parsing should
8919                              be placed at the beginning of the string.
8920                              returns position after last token to continue
8921 			     string parsing. Token may change from last call.
8922 input:         *token      - The token to search for.
8923 function return:           - a pointer to the desired substring.
8924                              A NULL returns indicates the end of the string.
8925 
8926 ***********************************************************************/
8927 char   *ADFI_strtok(
8928 	        char *string,
8929 		char **string_pos,
8930 		char *token )
8931 {
8932   char	*tmp_ptr ;
8933   char	*sub_string ;
8934   int   string_len ;
8935 
8936   if ( string_pos == NULL ) return NULL ;
8937   if( token == NULL || string == NULL || *string_pos == NULL ) return NULL ;
8938 
8939   /* Get the length left in the string */
8940 
8941   string_len = (int)strlen ( *string_pos ) ;
8942   if ( string_len == 0 ) return NULL ;
8943 
8944   /* Find the first character in the string which does not match the token */
8945   tmp_ptr = *string_pos ;
8946   while ( string_len > 0 ) {
8947      if ( tmp_ptr[0] == token[0] ) {
8948         tmp_ptr++ ;
8949         string_len-- ;
8950         }
8951      else {
8952         break ;
8953         } /* end if */
8954      } /* end while */
8955   if ( string_len == 0 ) return NULL ;
8956 
8957   /* Set the beginning of the sub string */
8958   sub_string = tmp_ptr ;
8959 
8960   /* Find the next token or the end of the string */
8961 
8962   while ( string_len > 0 ) {
8963      if ( tmp_ptr[0] != token[0] ) {
8964         tmp_ptr++ ;
8965         string_len-- ;
8966         }
8967      else {
8968         tmp_ptr[0] = '\0' ;
8969 	break ;
8970         } /* end if */
8971      } /* end while */
8972 
8973   /* Set location for the next search */
8974 
8975   if ( string_len > 0 )
8976      *string_pos = &tmp_ptr[1] ;
8977   else
8978      *string_pos = NULL ;
8979 
8980   return sub_string ;
8981 
8982 } /* end of ADFI_strtok */
8983 /* end of file ADFI_strtok.c */
8984 /* end of combine 2.0 */
8985