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 *) ⅆ
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( ¤t_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( ¤t_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( ¤t_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( ¤t_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( ¤t_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( ¤t_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( ¤t_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( ¤t_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( ¤t_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( ¤t_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( ¤t_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( ¤t_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