00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00044 static char ADF_L_identification[] = "\300\250\243\251ADF Library Version E01>" ;
00045
00046
00091
00092 static char ADF_D_identification[] = "\300\250\243\251ADF Database Version A02011>" ;
00093
00094
00095
00096
00097
00098 #include <stdio.h>
00099 #include <errno.h>
00100 #include <string.h>
00101 #if defined(_WIN32) && !defined(__NUTC__)
00102 #include <io.h>
00103 #else
00104 #include <unistd.h>
00105 #endif
00106 #include <stdlib.h>
00107 #include <ctype.h>
00108 #include "ADF.h"
00109 #include "ADF_internals.h"
00110 #if defined(_WIN32) && !defined(__NUTC__)
00111 #include <ctype.h>
00112 #ifndef F_OK
00113 #define R_OK 004
00114 #define W_OK 002
00115 #define X_OK 001
00116 #define F_OK 000
00117 #endif
00118 #endif
00119 #ifdef MEM_DEBUG
00120 #include "cg_malloc.h"
00121 #endif
00122
00123
00124
00125
00126
00127
00128 const char *ADF_error_string[] = {
00129 "ADF -1: No Error.",
00130 "ADF 1: Integer number is less than given minimum value.",
00131 "ADF 2: Integer number is greater than given maximum value.",
00132 "ADF 3: String length of zero or blank string detected.",
00133 "ADF 4: String length longer than maximum allowable length.",
00134 "ADF 5: String is not an ASCII-HEX string.",
00135 "ADF 6: Too many ADF files opened.",
00136 "ADF 7: ADF file status was not recognized.",
00137 "ADF 8: ADF file-open error.",
00138 "ADF 9: ADF file not currently opened.",
00139 "ADF 10: ADF file index out of legal range.",
00140 "ADF 11: Block/offset out of legal range.",
00141 "ADF 12: A string pointer is NULL.",
00142 "ADF 13: FSEEK error.",
00143 "ADF 14: FWRITE error.",
00144 "ADF 15: FREAD error.",
00145 "ADF 16: Internal error: Memory boundary tag bad.",
00146 "ADF 17: Internal error: Disk boundary tag bad.",
00147 "ADF 18: File Open Error: NEW - File already exists.",
00148 "ADF 19: ADF file format was not recognized.",
00149 "ADF 20: Attempt to free the RootNode disk information.",
00150 "ADF 21: Attempt to free the FreeChunkTable disk information.",
00151 "ADF 22: File Open Error: OLD - File does not exist.",
00152 "ADF 23: Entered area of Unimplemented Code...",
00153 "ADF 24: Sub-Node.entries is bad.",
00154 "ADF 25: Memory allocation failed.",
00155 "ADF 26: Duplicate child name under a parent node.",
00156 "ADF 27: Node has no dimensions.",
00157 "ADF 28: Node's number-of-dimensions is not in legal range.",
00158 "ADF 29: Specified child is NOT a child of the specified parent.",
00159 "ADF 30: Data-Type is too long.",
00160 "ADF 31: Invalid Data-Type.",
00161 "ADF 32: A pointer is NULL.",
00162 "ADF 33: Node has no data associated with it.",
00163 "ADF 34: Error zeroing out memory.",
00164 "ADF 35: Requested data exceeds actual data available.",
00165 "ADF 36: Bad end value.",
00166 "ADF 37: Bad stride value.",
00167 "ADF 38: Minimum values is greater than the maximum value.",
00168 "ADF 39: The format of this machine does not match a known signature.",
00169 "ADF 40: Cannot convert to or from an unknown Native format.",
00170 "ADF 41: The two conversion formats are equal, no conversion done.",
00171 "ADF 42: The data format is not support on a particular machine.",
00172 "ADF 43: File Close error.",
00173 "ADF 44: Numeric overflow/underflow in data conversion.",
00174 "ADF 45: Bad start value.",
00175 "ADF 46: A value of zero is not allowable.",
00176 "ADF 47: Bad dimension value.",
00177 "ADF 48: Error state must be either a 0 (zero) or a 1 (one).",
00178 "ADF 49: Dimensional specifications for disk and memory are unequal.",
00179 "ADF 50: Too many link level used. May be caused by a recursive link.",
00180 "ADF 51: The node is not a link. It was expected to be a link.",
00181 "ADF 52: The linked-to node does not exist.",
00182 "ADF 53: The ADF file of a linked-node is not accessable.",
00183 "ADF 54: A node-id of 0.0 is not valid.",
00184 "ADF 55: Incomplete Data when reading multiple data blocks.",
00185 "ADF 56: Node name contains invalid characters.",
00186 "ADF 57: ADF file version incompatible with this library version.",
00187 "ADF 58: Nodes are not from the same file.",
00188 "ADF 59: Priority Stack Error.",
00189 "ADF 60: Machine format and file format are incompatable.",
00190 "ADF 61: FFLUSH error",
00191 "ADF 62: The node ID pointer is NULL.",
00192 "ADF 63: The maximum size for a file exceeded.",
00193 "ADF x: Last error mesage"
00194 } ;
00195
00196
00197
00198
00199 int ADF_sys_err = 0;
00200 static int ADF_abort_on_error = FALSE ;
00201
00202 extern char data_chunk_start_tag[];
00203
00204 #define CHECK_ADF_ABORT( error_flag ) if( error_flag != NO_ERROR ) { \
00205 if( ADF_abort_on_error == TRUE ) { \
00206 ADF_Error_Message( error_flag, 0L );\
00207 ADFI_Abort( error_flag) ; } \
00208 else { return ; } }
00209
00210 #define CHECK_ADF_ABORT1( error_flag ) if( error_flag != NO_ERROR ) { \
00211 free (name_tmp); \
00212 if( ADF_abort_on_error == TRUE ) { \
00213 ADF_Error_Message( error_flag, 0L );\
00214 ADFI_Abort( error_flag) ; } \
00215 else { return ; } }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 void ADF_Children_Names(
00279 const double PID,
00280 const int istart,
00281 const int imax_num,
00282 const int imax_name_len,
00283 int *inum_ret,
00284 char *names,
00285 int *error_return )
00286 {
00287 int i ;
00288 unsigned int file_index ;
00289 struct DISK_POINTER block_offset ;
00290 struct NODE_HEADER node ;
00291 struct SUB_NODE_TABLE_ENTRY sub_node_table_entry ;
00292 double LID ;
00293
00294 *error_return = NO_ERROR ;
00295
00296 if( inum_ret == NULL ) {
00297 *error_return = NULL_POINTER ;
00298 CHECK_ADF_ABORT( *error_return ) ;
00299 }
00300 *inum_ret = 0 ;
00301
00302 if( names == NULL ) {
00303 *error_return = NULL_STRING_POINTER ;
00304 CHECK_ADF_ABORT( *error_return ) ;
00305 }
00306
00307 if( (istart <=0) || (imax_num <= 0) || (imax_name_len <= 0) ) {
00308 *error_return = NUMBER_LESS_THAN_MINIMUM ;
00309 CHECK_ADF_ABORT( *error_return ) ;
00310 }
00311
00312 ADFI_chase_link( PID, &LID, &file_index, &block_offset, &node, error_return ) ;
00313 CHECK_ADF_ABORT( *error_return ) ;
00314
00316 if( node.num_sub_nodes == 0 ) {
00317 return ;
00318 }
00319
00321 block_offset.block = node.sub_node_table.block ;
00322 block_offset.offset = node.sub_node_table.offset +
00323 (TAG_SIZE + DISK_POINTER_SIZE +
00324 (ADF_NAME_LENGTH + DISK_POINTER_SIZE) * (istart-1)) ;
00325
00327 for( i=(istart-1); i< MIN(istart-1+imax_num, (int) node.num_sub_nodes); i++ ) {
00328 ADFI_adjust_disk_pointer( &block_offset, error_return ) ;
00329 CHECK_ADF_ABORT( *error_return ) ;
00330
00332 ADFI_read_sub_node_table_entry( file_index, &block_offset,
00333 &sub_node_table_entry, error_return ) ;
00334 CHECK_ADF_ABORT( *error_return ) ;
00335
00337 ADFI_string_2_C_string( sub_node_table_entry.child_name,
00338 MIN(imax_name_len,ADF_NAME_LENGTH),
00339 &names[(i-(istart-1))*(imax_name_len+1)],
00340 error_return ) ;
00341 CHECK_ADF_ABORT( *error_return ) ;
00342
00344 block_offset.offset += (ADF_NAME_LENGTH + DISK_POINTER_SIZE) ;
00345 *inum_ret = *inum_ret + 1 ;
00346 }
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 void ADF_Children_IDs (
00371 const double PID,
00372 const int istart,
00373 const int imax_num,
00374 int *inum_ret,
00375 double *IDs,
00376 int *error_return )
00377 {
00378 int i ;
00379 unsigned int file_index ;
00380 struct DISK_POINTER block_offset ;
00381 struct NODE_HEADER node ;
00382 struct SUB_NODE_TABLE_ENTRY sub_node_table_entry ;
00383 double LID ;
00384
00385 *error_return = NO_ERROR ;
00386
00387 if( inum_ret == NULL ) {
00388 *error_return = NULL_POINTER ;
00389 CHECK_ADF_ABORT( *error_return ) ;
00390 }
00391 *inum_ret = 0 ;
00392
00393 if( IDs == NULL ) {
00394 *error_return = NULL_NODEID_POINTER ;
00395 CHECK_ADF_ABORT( *error_return ) ;
00396 }
00397
00398 if( (istart <=0) || (imax_num <= 0) ) {
00399 *error_return = NUMBER_LESS_THAN_MINIMUM ;
00400 CHECK_ADF_ABORT( *error_return ) ;
00401 }
00402
00403 ADFI_chase_link( PID, &LID, &file_index, &block_offset, &node, error_return ) ;
00404 CHECK_ADF_ABORT( *error_return ) ;
00405
00407 if( node.num_sub_nodes == 0 ) {
00408 return ;
00409 }
00410
00412 block_offset.block = node.sub_node_table.block ;
00413 block_offset.offset = node.sub_node_table.offset +
00414 (TAG_SIZE + DISK_POINTER_SIZE +
00415 (ADF_NAME_LENGTH + DISK_POINTER_SIZE) * (istart-1)) ;
00416
00418 for( i=(istart-1); i< MIN(istart-1+imax_num, (int) node.num_sub_nodes); i++ ) {
00419 ADFI_adjust_disk_pointer( &block_offset, error_return ) ;
00420 CHECK_ADF_ABORT( *error_return ) ;
00421
00423 ADFI_read_sub_node_table_entry( file_index, &block_offset,
00424 &sub_node_table_entry, error_return ) ;
00425 CHECK_ADF_ABORT( *error_return ) ;
00426
00428 ADFI_file_block_offset_2_ID( file_index,
00429 sub_node_table_entry.child_location.block,
00430 sub_node_table_entry.child_location.offset,
00431 &IDs[i-(istart-1)], error_return ) ;
00432 CHECK_ADF_ABORT( *error_return ) ;
00433
00435 block_offset.offset += (ADF_NAME_LENGTH + DISK_POINTER_SIZE) ;
00436 *inum_ret = *inum_ret + 1 ;
00437 }
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464 void ADF_Create(
00465 const double PID,
00466 const char *name,
00467 double *ID,
00468 int *error_return )
00469 {
00470 unsigned int file_index ;
00471 struct DISK_POINTER parent_block_offset, child_block_offset ;
00472 struct DISK_POINTER sub_node_entry_location ;
00473 struct NODE_HEADER parent_node, child_node ;
00474 struct SUB_NODE_TABLE_ENTRY sub_node_entry ;
00475 int i, name_length, name_start, found ;
00476 double LID ;
00477
00478 ADFI_check_string_length( name, ADF_NAME_LENGTH, error_return ) ;
00479 CHECK_ADF_ABORT( *error_return ) ;
00480
00481 if( ID == NULL ) {
00482 *error_return = NULL_POINTER ;
00483 CHECK_ADF_ABORT( *error_return ) ;
00484 }
00485
00486 *error_return = NO_ERROR ;
00487
00488 ADFI_chase_link( PID, &LID, &file_index, &parent_block_offset,
00489 &parent_node, error_return ) ;
00490 CHECK_ADF_ABORT( *error_return ) ;
00491
00492
00494 ADFI_fill_initial_node_header( &child_node, error_return ) ;
00495 CHECK_ADF_ABORT( *error_return ) ;
00496
00498 name_start = 0 ;
00499 while( name[ name_start ] == ' ' ) {
00500 name_start++ ;
00501 }
00502 name_length = strlen( &name[ name_start ] ) ;
00503 if( name_length > ADF_NAME_LENGTH ) {
00504 *error_return = STRING_LENGTH_TOO_BIG ;
00505 CHECK_ADF_ABORT( *error_return ) ;
00506 }
00507
00509 ADFI_check_4_child_name( file_index, &parent_block_offset,
00510 &name[ name_start ], &found, &sub_node_entry_location,
00511 &sub_node_entry, error_return ) ;
00512 CHECK_ADF_ABORT( *error_return ) ;
00513 if( found == 1 ) {
00514 *error_return = DUPLICATE_CHILD_NAME ;
00515 CHECK_ADF_ABORT( *error_return ) ;
00516 }
00517 for ( i=0; i < name_length; i++ ) {
00518 if ( ! isprint ( name[ name_start + i ] ) ||
00519 name[ name_start + i ] == '/' ) {
00520 *error_return = INVALID_NODE_NAME;
00521 CHECK_ADF_ABORT( *error_return ) ;
00522 }
00523 }
00524
00526 strncpy( child_node.name, &name[ name_start ], name_length ) ;
00527
00529 ADFI_file_malloc( file_index, NODE_HEADER_SIZE, &child_block_offset,
00530 error_return ) ;
00531 CHECK_ADF_ABORT( *error_return ) ;
00532
00534 ADFI_write_node_header( file_index, &child_block_offset, &child_node,
00535 error_return ) ;
00536 CHECK_ADF_ABORT( *error_return ) ;
00537
00541 ADFI_add_2_sub_node_table( file_index, &parent_block_offset,
00542 &child_block_offset, error_return ) ;
00543 CHECK_ADF_ABORT( *error_return ) ;
00544
00546 ADFI_file_block_offset_2_ID( file_index, child_block_offset.block,
00547 child_block_offset.offset, ID, error_return ) ;
00548 CHECK_ADF_ABORT( *error_return ) ;
00549
00551 ADFI_write_modification_date( file_index, error_return ) ;
00552 CHECK_ADF_ABORT( *error_return ) ;
00553
00554 }
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 void ADF_Database_Close(
00571 const double Root_ID,
00572 int *error_return )
00573 {
00574 unsigned int file_index ;
00575 struct DISK_POINTER block_offset ;
00576
00577 *error_return = NO_ERROR ;
00578
00580 ADFI_ID_2_file_block_offset( Root_ID, &file_index, &block_offset.block,
00581 &block_offset.offset, error_return ) ;
00582 CHECK_ADF_ABORT( *error_return ) ;
00583
00585 ADFI_close_file( file_index, error_return ) ;
00586 CHECK_ADF_ABORT( *error_return ) ;
00587 }
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 void ADF_Database_Delete(
00601 const char *filename,
00602 int *error_return )
00603 {
00604 ADFI_check_string_length( filename, ADF_FILENAME_LENGTH, error_return ) ;
00605 CHECK_ADF_ABORT( *error_return ) ;
00606
00607 fprintf(stderr,"Subroutine ADF_Database_Delete is not yet implemented...\n" ) ;
00608 *error_return = UNIMPLEMENTED_CODE ;
00609 CHECK_ADF_ABORT( *error_return ) ;
00610 }
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 void ADF_Database_Garbage_Collection(
00625 const double ID,
00626 int *error_return )
00627 {
00628 fprintf(stderr,
00629 "Subroutine ADF_Database_Garbage_Collection is not yet implemented...\n" ) ;
00630 *error_return = UNIMPLEMENTED_CODE ;
00631 CHECK_ADF_ABORT( *error_return ) ;
00632 }
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647 void ADF_Database_Get_Format(
00648 const double Root_ID,
00649 char *format,
00650 int *error_return )
00651 {
00652 unsigned int file_index ;
00653 struct DISK_POINTER block_offset ;
00654 struct FILE_HEADER file_header ;
00655
00656 if( format == NULL ) {
00657 *error_return = NULL_STRING_POINTER ;
00658 CHECK_ADF_ABORT( *error_return ) ;
00659 }
00660
00662 ADFI_ID_2_file_block_offset( Root_ID, &file_index, &block_offset.block,
00663 &block_offset.offset, error_return ) ;
00664 CHECK_ADF_ABORT( *error_return ) ;
00665
00667 ADFI_read_file_header( file_index, &file_header, error_return ) ;
00668 CHECK_ADF_ABORT( *error_return ) ;
00669
00670 #define EVAL_2_BYTES( C0, C1 ) (((C0)<<8)+((C1)))
00671
00672 switch( EVAL_2_BYTES( file_header.numeric_format, file_header.os_size ) ) {
00673 case EVAL_2_BYTES( 'B', 'L' ) :
00674 strcpy( format, IEEE_BIG_32_FORMAT_STRING ) ;
00675
00676 break ;
00677
00678 case EVAL_2_BYTES( 'L', 'L' ) :
00679 strcpy( format, IEEE_LITTLE_32_FORMAT_STRING ) ;
00680 break ;
00681
00682 case EVAL_2_BYTES( 'B', 'B' ) :
00683 strcpy( format, IEEE_BIG_64_FORMAT_STRING ) ;
00684
00685 break ;
00686
00687 case EVAL_2_BYTES( 'L', 'B' ) :
00688 strcpy( format, IEEE_LITTLE_64_FORMAT_STRING ) ;
00689 break ;
00690
00691 case EVAL_2_BYTES( 'C', 'B' ) :
00692 strcpy( format, CRAY_FORMAT_STRING ) ;
00693 break ;
00694
00695 case EVAL_2_BYTES( 'N', 'L' ) :
00696 case EVAL_2_BYTES( 'N', 'B' ) :
00697 strcpy( format, NATIVE_FORMAT_STRING ) ;
00698 break ;
00699
00700 default:
00701 *error_return = ADF_FILE_FORMAT_NOT_RECOGNIZED ;
00702 return ;
00703
00704 }
00705
00706 }
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 void ADF_Database_Open(
00752 const char *filename,
00753 const char *status_in,
00754 const char *format,
00755 double *Root_ID,
00756 int *error_return )
00757 {
00758 int iret ;
00759 int error_dummy ;
00760 char machine_format, format_to_use, os_to_use ;
00761 char *status ;
00762 int formats_compare ;
00763 unsigned int file_index ;
00764 unsigned int file_minor_version, lib_minor_version ;
00765 struct FILE_HEADER file_header ;
00766 struct NODE_HEADER node_header ;
00767 struct FREE_CHUNK_TABLE free_chunk_table ;
00768
00769 file_header.tag0[0] = '\0' ;
00770
00771 status = (char *)status_in ;
00772 if( status == NULL ) {
00773 *error_return = NULL_STRING_POINTER ;
00774 CHECK_ADF_ABORT( *error_return ) ;
00775 }
00776
00777 if( Root_ID == NULL ) {
00778 *error_return = NULL_POINTER ;
00779 CHECK_ADF_ABORT( *error_return ) ;
00780 }
00781
00784 *error_return = NO_ERROR ;
00785
00787 ADFI_figure_machine_format( format, &machine_format, &format_to_use,
00788 &os_to_use, error_return ) ;
00789
00790 if( ADFI_stridx_c( status, "SCRATCH" ) != 0 ) {
00791 ADFI_check_string_length( filename, ADF_FILENAME_LENGTH, error_return ) ;
00792 CHECK_ADF_ABORT( *error_return ) ;
00793 }
00794 ADFI_check_string_length( status, ADF_STATUS_LENGTH, error_return ) ;
00795 CHECK_ADF_ABORT( *error_return ) ;
00796
00798 if( ADFI_stridx_c( status, "UNKNOWN" ) == 0 ) {
00800 iret = access( filename, F_OK ) ;
00801 if( iret != 0 )
00802 status = "NEW" ;
00803 else
00804 status = "OLD" ;
00805 }
00806
00807 if( (ADFI_stridx_c( status, "READ_ONLY" ) == 0) ||
00808 (ADFI_stridx_c( status, "OLD" ) == 0) ) {
00810 iret = access( filename, F_OK ) ;
00811 if( iret != 0 ) {
00812 *error_return = REQUESTED_OLD_FILE_NOT_FOUND ;
00813 CHECK_ADF_ABORT( *error_return ) ;
00814 }
00815
00817 ADFI_open_file( filename, status, &file_index, error_return ) ;
00818 CHECK_ADF_ABORT( *error_return ) ;
00819 }
00820
00821 else if( (ADFI_stridx_c( status, "NEW" ) == 0) ||
00822 (ADFI_stridx_c( status, "SCRATCH" ) == 0) ) {
00824 if( ADFI_stridx_c( status, "NEW" ) == 0 ) {
00825 iret = access( filename, F_OK ) ;
00826 if( iret == 0 ) {
00827 *error_return = REQUESTED_NEW_FILE_EXISTS ;
00828 CHECK_ADF_ABORT( *error_return ) ;
00829 }
00830 if( errno != ENOENT ) {
00831 *error_return = FILE_OPEN_ERROR ;
00832 CHECK_ADF_ABORT( *error_return ) ;
00833 }
00834 }
00835
00837 ADFI_fill_initial_file_header( format_to_use, os_to_use,
00838 ADF_D_identification,
00839 &file_header, error_return ) ;
00840 CHECK_ADF_ABORT( *error_return ) ;
00841
00843 ADFI_open_file( filename, status, &file_index, error_return ) ;
00844 CHECK_ADF_ABORT( *error_return ) ;
00845
00847 ADFI_write_file_header( file_index, &file_header, error_return ) ;
00848 CHECK_ADF_ABORT( *error_return ) ;
00849
00851 ADFI_fill_initial_node_header( &node_header, error_return ) ;
00852 CHECK_ADF_ABORT( *error_return ) ;
00853
00854 strncpy( node_header.name, ROOT_NODE_NAME, strlen( ROOT_NODE_NAME )) ;
00855 strncpy( node_header.label, ROOT_NODE_LABEL, strlen( ROOT_NODE_LABEL ) ) ;
00856
00858 ADFI_write_node_header( file_index, &file_header.root_node,
00859 &node_header, error_return ) ;
00860 CHECK_ADF_ABORT( *error_return ) ;
00861
00863 ADFI_fill_initial_free_chunk_table( &free_chunk_table, error_return ) ;
00864 CHECK_ADF_ABORT( *error_return ) ;
00865
00867 ADFI_write_free_chunk_table( file_index, &free_chunk_table, error_return ) ;
00868 CHECK_ADF_ABORT( *error_return ) ;
00869 }
00870
00871 else {
00872 *error_return = ADF_FILE_STATUS_NOT_RECOGNIZED ;
00873 CHECK_ADF_ABORT( *error_return ) ;
00874 }
00875
00877 if( file_header.tag0[0] == '\0' ) {
00878 ADFI_read_file_header( file_index, &file_header, error_return ) ;
00879 if ( *error_return != NO_ERROR ) goto Open_Error ;
00880
00882 if( file_header.what[25] != ADF_D_identification[25] ) {
00883
00884
00885
00886
00887 *error_return = INVALID_VERSION ;
00888 if ( *error_return != NO_ERROR ) goto Open_Error ;
00889 }
00890
00891 if( file_header.what[28] == '>' )
00892 {
00893
00894
00895 *error_return = INVALID_VERSION ;
00896 if ( *error_return != NO_ERROR ) goto Open_Error ;
00897 }
00898 else
00899 {
00900
00901
00902
00903 ADFI_ASCII_Hex_2_unsigned_int( 0, 255, 2, &file_header.what[26],
00904 &file_minor_version, error_return) ;
00905 if ( *error_return != NO_ERROR ) goto Open_Error ;
00906
00907 ADFI_ASCII_Hex_2_unsigned_int( 0, 255, 2, &ADF_D_identification[26],
00908 &lib_minor_version, error_return) ;
00909 if ( *error_return != NO_ERROR ) goto Open_Error ;
00910 if( file_minor_version > lib_minor_version ) {
00911 *error_return = INVALID_VERSION ;
00912 if ( *error_return != NO_ERROR ) goto Open_Error ;
00913 }
00914
00915 if( file_minor_version < lib_minor_version ) {
00923 if ( ADF_D_identification[25] == 'A' && file_minor_version > 1 ) {
00924 ADFI_remember_version_update( file_index, ADF_D_identification,
00925 error_return ) ;
00926
00927 if ( *error_return != NO_ERROR ) goto Open_Error ;
00928 }
00929
00933 if ( ADF_D_identification[25] == 'A' && file_minor_version < 2 ) {
00934 ADF_file[file_index].link_separator = ' ' ;
00935 }
00936 }
00937 }
00938 }
00939
00941 ADFI_file_block_offset_2_ID( file_index, file_header.root_node.block,
00942 file_header.root_node.offset, Root_ID, error_return ) ;
00943 if ( *error_return != NO_ERROR ) goto Open_Error ;
00944
00946 ADFI_remember_file_format( file_index, file_header.numeric_format,
00947 file_header.os_size, error_return ) ;
00948 if ( *error_return != NO_ERROR ) goto Open_Error ;
00949
00951 ADFI_file_and_machine_compare( file_index, NULL, &formats_compare,
00952 error_return ) ;
00953 if ( *error_return != NO_ERROR ) goto Open_Error ;
00954
00955 return ;
00956
00957 Open_Error:
00959 ADFI_close_file( file_index, &error_dummy ) ;
00960 CHECK_ADF_ABORT( *error_return ) ;
00961
00962 }
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984 void ADF_Database_Valid(
00985 const char *filename,
00986 int *error_return )
00987 {
00988 FILE *fp;
00989 char header[33];
00990
00991 if (NULL == filename || 0 == *filename) {
00992 *error_return = NULL_STRING_POINTER;
00993 return;
00994 }
00995
00996 if (access(filename, F_OK)) {
00997 *error_return = REQUESTED_OLD_FILE_NOT_FOUND;
00998 return;
00999 }
01000 if ((fp = fopen(filename, "r+b")) == NULL) {
01001 if (errno == EMFILE)
01002 *error_return = TOO_MANY_ADF_FILES_OPENED;
01003 else
01004 *error_return = FILE_OPEN_ERROR;
01005 return;
01006 }
01007 fread (header, sizeof(char), 32, fp);
01008 fclose (fp);
01009 header[32] = 0;
01010 if (strncmp (&header[4], "ADF Database Version", 20))
01011 *error_return = ADF_FILE_FORMAT_NOT_RECOGNIZED;
01012 else
01013 *error_return = NO_ERROR;
01014 }
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029 void ADF_Database_Set_Format(
01030 const double Root_ID,
01031 const char *format,
01032 int *error_return )
01033 {
01034 unsigned int file_index ;
01035 struct DISK_POINTER block_offset ;
01036 struct FILE_HEADER file_header ;
01037 char machine_format, format_to_use, os_to_use ;
01038
01039 ADFI_check_string_length( format, ADF_FORMAT_LENGTH, error_return ) ;
01040 CHECK_ADF_ABORT( *error_return ) ;
01041
01043 ADFI_ID_2_file_block_offset( Root_ID, &file_index, &block_offset.block,
01044 &block_offset.offset, error_return ) ;
01045 CHECK_ADF_ABORT( *error_return ) ;
01046
01048 ADFI_read_file_header( file_index, &file_header, error_return ) ;
01049 CHECK_ADF_ABORT( *error_return ) ;
01050
01051 ADFI_figure_machine_format( format, &machine_format, &format_to_use,
01052 &os_to_use, error_return ) ;
01053 CHECK_ADF_ABORT( *error_return ) ;
01054
01055 file_header.numeric_format = format_to_use ;
01056 file_header.os_size = os_to_use ;
01057
01059 ADFI_get_current_date ( file_header.modification_date );
01060
01062 ADFI_write_file_header( file_index, &file_header, error_return ) ;
01063 CHECK_ADF_ABORT( *error_return ) ;
01064
01065 ADFI_remember_file_format( file_index, format_to_use, os_to_use,
01066 error_return ) ;
01067 CHECK_ADF_ABORT( *error_return ) ;
01068
01069 }
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092 void ADF_Database_Version(
01093 const double Root_ID,
01094 char *version,
01095 char *creation_date,
01096 char *modification_date,
01097 int *error_return )
01098 {
01099 unsigned int file_index ;
01100 struct DISK_POINTER block_offset ;
01101 struct FILE_HEADER file_header ;
01102
01103 if( (version == NULL) || (creation_date == NULL) ||
01104 (modification_date == NULL) ) {
01105 *error_return = NULL_STRING_POINTER ;
01106 CHECK_ADF_ABORT( *error_return ) ;
01107 }
01108
01110 ADFI_ID_2_file_block_offset( Root_ID, &file_index, &block_offset.block,
01111 &block_offset.offset, error_return ) ;
01112 CHECK_ADF_ABORT( *error_return ) ;
01113
01115 ADFI_read_file_header( file_index, &file_header, error_return ) ;
01116 CHECK_ADF_ABORT( *error_return ) ;
01117
01118 *error_return = NO_ERROR ;
01120 ADFI_string_2_C_string( &file_header.what[4], strcspn ( file_header.what, ">" ) - 4,
01121 version, error_return ) ;
01122 CHECK_ADF_ABORT( *error_return ) ;
01123
01125 ADFI_string_2_C_string( file_header.creation_date, 28,
01126 creation_date, error_return ) ;
01127 CHECK_ADF_ABORT( *error_return ) ;
01128
01130 ADFI_string_2_C_string( file_header.modification_date, 28,
01131 modification_date, error_return ) ;
01132 CHECK_ADF_ABORT( *error_return ) ;
01133
01134 }
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153 void ADF_Delete(
01154 const double PID,
01155 const double ID,
01156 int *error_return )
01157 {
01158 int num_ids , i, link_path_length ;
01159 double *ids ;
01160 unsigned int file_index ;
01161 struct DISK_POINTER parent ;
01162 struct DISK_POINTER child ;
01163 struct NODE_HEADER node_header ;
01164
01168 ADFI_ID_2_file_block_offset( ID, &file_index, &child.block, &child.offset,
01169 error_return ) ;
01170
01171 CHECK_ADF_ABORT( *error_return ) ;
01172
01173 ADF_Is_Link( ID, &link_path_length, error_return ) ;
01174 CHECK_ADF_ABORT( *error_return ) ;
01175
01176 ADFI_read_node_header( file_index, &child, &node_header, error_return ) ;
01177 CHECK_ADF_ABORT( *error_return ) ;
01178
01181 if( link_path_length > 0 ) {
01183 ADFI_delete_data( file_index, &node_header, error_return ) ;
01184 }
01185 else {
01188 ADFI_get_direct_children_ids( file_index, &child, &num_ids, &ids,
01189 error_return ) ;
01190 CHECK_ADF_ABORT( *error_return ) ;
01191
01192 for( i=0; i<num_ids; i++ ) {
01193 ADF_Delete( ID, ids[i], error_return ) ;
01194 CHECK_ADF_ABORT( *error_return ) ;
01195 }
01196
01197 if( num_ids > 0 ) {
01198 free( ids ) ;
01199 }
01200
01203 ADF_Put_Dimension_Information( ID, "MT", 0, (int *)0, error_return ) ;
01204 CHECK_ADF_ABORT( *error_return ) ;
01205 }
01206
01207
01209 ADFI_ID_2_file_block_offset( PID, &file_index,
01210 &parent.block, &parent.offset, error_return ) ;
01211
01212
01213 CHECK_ADF_ABORT( *error_return ) ;
01214
01215 ADFI_delete_from_sub_node_table( file_index, &parent, &child, error_return ) ;
01216 CHECK_ADF_ABORT( *error_return ) ;
01217
01219 if( node_header.entries_for_sub_nodes > 0 ) {
01220 ADFI_delete_sub_node_table( file_index, &node_header.sub_node_table,
01221 node_header.entries_for_sub_nodes, error_return ) ;
01222 CHECK_ADF_ABORT( *error_return ) ;
01223 }
01224
01226 ADFI_file_free( file_index, &child, 0, error_return ) ;
01227 CHECK_ADF_ABORT( *error_return ) ;
01228
01230 ADFI_write_modification_date( file_index, error_return ) ;
01231 CHECK_ADF_ABORT( *error_return ) ;
01232
01233 }
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247 void ADF_Error_Message(
01248 const int error_return_input,
01249 char *error_string )
01250 {
01251 char err_msg_str[ADF_MAX_ERROR_STR_LENGTH+1] ;
01252
01254 if( error_string == NULL ) {
01255 ADF_Error_Message( error_return_input, err_msg_str ) ;
01256 fprintf(stderr,"%s\n", err_msg_str ) ;
01257 return ;
01258 }
01259
01261 if( error_return_input == NO_ERROR ) {
01262 strcpy( error_string, ADF_error_string[ 0 ] ) ;
01263 }
01265 else if( (error_return_input <= 0) ||
01266 (error_return_input >= sizeof( ADF_error_string )/sizeof(char *) - 1 ) ) {
01267 sprintf( error_string, "ADF: Unrecognized error number %d.",
01268 error_return_input ) ;
01269 }
01271 else if (ADF_sys_err &&
01272 (FILE_OPEN_ERROR == error_return_input ||
01273 FILE_CLOSE_ERROR == error_return_input ||
01274 FSEEK_ERROR == error_return_input ||
01275 FREAD_ERROR == error_return_input ||
01276 FWRITE_ERROR == error_return_input ||
01277 FFLUSH_ERROR == error_return_input)) {
01278 char *p;
01279 strncpy (err_msg_str, strerror(ADF_sys_err), ADF_MAX_ERROR_STR_LENGTH-8);
01280 err_msg_str[ADF_MAX_ERROR_STR_LENGTH-8] = 0;
01281 p = err_msg_str + strlen(err_msg_str) - 1;
01282 if (*p == '\n') *p = 0;
01283 sprintf (error_string, "ADF %d: %s", error_return_input, err_msg_str);
01284 }
01285 else {
01286 strcpy( error_string, ADF_error_string[error_return_input] ) ;
01287 }
01288 }
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304 void ADF_Flush_to_Disk(
01305 const double ID,
01306 int *error_return )
01307 {
01308 double LID ;
01309 unsigned int file_index ;
01310 struct DISK_POINTER block_offset ;
01311 struct NODE_HEADER node ;
01312
01313 ADFI_chase_link( ID, &LID, &file_index, &block_offset, &node,
01314 error_return ) ;
01315 CHECK_ADF_ABORT( *error_return ) ;
01316
01317 ADFI_fflush_file( file_index, error_return ) ;
01318 CHECK_ADF_ABORT( *error_return ) ;
01319 }
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334 void ADF_Get_Data_Type(
01335 const double ID,
01336 char *data_type,
01337 int *error_return )
01338 {
01339 unsigned int file_index ;
01340 struct DISK_POINTER block_offset ;
01341 struct NODE_HEADER node ;
01342 double LID ;
01343
01344 if( data_type == NULL ) {
01345 *error_return = NULL_STRING_POINTER ;
01346 CHECK_ADF_ABORT( *error_return ) ;
01347 }
01348
01349 *error_return = NO_ERROR ;
01350
01351 ADFI_chase_link( ID, &LID, &file_index, &block_offset, &node, error_return ) ;
01352 CHECK_ADF_ABORT( *error_return ) ;
01353
01355 ADFI_string_2_C_string( node.data_type, ADF_DATA_TYPE_LENGTH, data_type,
01356 error_return ) ;
01357 CHECK_ADF_ABORT( *error_return ) ;
01358
01359 }
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375 void ADF_Get_Dimension_Values(
01376 const double ID,
01377 int dim_vals[],
01378 int *error_return )
01379 {
01380 unsigned int file_index ;
01381 struct DISK_POINTER block_offset ;
01382 struct NODE_HEADER node ;
01383 int i ;
01384 double LID ;
01385
01386 if( dim_vals == NULL ) {
01387 *error_return = NULL_POINTER ;
01388 CHECK_ADF_ABORT( *error_return ) ;
01389 }
01390
01391 *error_return = NO_ERROR ;
01392
01393 ADFI_chase_link( ID, &LID, &file_index, &block_offset, &node, error_return ) ;
01394 CHECK_ADF_ABORT( *error_return ) ;
01395
01397 if( node.number_of_dimensions == 0 ) {
01398 *error_return = ZERO_DIMENSIONS ;
01399 CHECK_ADF_ABORT( *error_return ) ;
01400 }
01401
01403 if( node.number_of_dimensions > ADF_MAX_DIMENSIONS ) {
01404 *error_return = BAD_NUMBER_OF_DIMENSIONS ;
01405 CHECK_ADF_ABORT( *error_return ) ;
01406 }
01407
01409 for( i=0; i<(int)node.number_of_dimensions; i++ )
01410 dim_vals[i] = node.dimension_values[i] ;
01411
01412 }
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425 void ADF_Get_Error_State(
01426 int *error_state,
01427 int *error_return )
01428 {
01429 if( error_state == 0L ) {
01430 *error_return = NULL_POINTER ;
01431 CHECK_ADF_ABORT( *error_return ) ;
01432 }
01433
01434 *error_return = NO_ERROR ;
01435
01436 if( ADF_abort_on_error == TRUE )
01437 *error_state = 1 ;
01438 else
01439 *error_state = 0 ;
01440
01441 }
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454 void ADF_Get_Label(
01455 const double ID,
01456 char *label,
01457 int *error_return )
01458 {
01459 unsigned int file_index ;
01460 struct DISK_POINTER block_offset ;
01461 struct NODE_HEADER node ;
01462 double LID ;
01463
01464 if( label == NULL ) {
01465 *error_return = NULL_STRING_POINTER ;
01466 CHECK_ADF_ABORT( *error_return ) ;
01467 }
01468
01469 *error_return = NO_ERROR ;
01470
01471 ADFI_chase_link( ID, &LID, &file_index, &block_offset, &node, error_return ) ;
01472 CHECK_ADF_ABORT( *error_return ) ;
01473
01475 ADFI_string_2_C_string( node.label, ADF_LABEL_LENGTH, label,
01476 error_return ) ;
01477 CHECK_ADF_ABORT( *error_return ) ;
01478
01479 }
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495 void ADF_Get_Link_Path(
01496 const double ID,
01497 char *file,
01498 char *name_in_file,
01499 int *error_return )
01500 {
01501 unsigned int file_index ;
01502 int file_bytes, machine_bytes, total_bytes ;
01503 char file_format, machine_format ;
01504 struct DISK_POINTER block_offset ;
01505 struct NODE_HEADER node_header ;
01506 struct TOKENIZED_DATA_TYPE tokenized_data_type[ 2 ] ;
01507 char link_data[ADF_FILENAME_LENGTH + ADF_MAX_LINK_DATA_SIZE + 1 + 1] ;
01508 size_t lenfilename ;
01509 char *separator;
01510
01511 if( file == NULL ) {
01512 *error_return = NULL_STRING_POINTER ;
01513 CHECK_ADF_ABORT( *error_return ) ;
01514 }
01515
01516 if( name_in_file == NULL ) {
01517 *error_return = NULL_STRING_POINTER ;
01518 CHECK_ADF_ABORT( *error_return ) ;
01519 }
01521 ADFI_ID_2_file_block_offset( ID, &file_index, &block_offset.block,
01522 &block_offset.offset, error_return ) ;
01523 CHECK_ADF_ABORT( *error_return ) ;
01524
01526 ADFI_read_node_header( file_index, &block_offset, &node_header, error_return ) ;
01527 CHECK_ADF_ABORT( *error_return ) ;
01528
01529 if( (node_header.data_type[0] != 'L') || (node_header.data_type[1] != 'K')) {
01530 *error_return = NODE_IS_NOT_A_LINK ;
01531 CHECK_ADF_ABORT( *error_return ) ;
01532 }
01533
01535 ADFI_evaluate_datatype( file_index, node_header.data_type,
01536 &file_bytes, &machine_bytes, tokenized_data_type,
01537 &file_format, &machine_format, error_return ) ;
01538 CHECK_ADF_ABORT( *error_return ) ;
01539
01540 total_bytes = file_bytes * node_header.dimension_values[0] ;
01541 ADFI_read_data_chunk( file_index, &node_header.data_chunks,
01542 tokenized_data_type, file_bytes, total_bytes,
01543 0, total_bytes, link_data, error_return ) ;
01544 CHECK_ADF_ABORT( *error_return ) ;
01545
01546
01547 link_data[ node_header.dimension_values[0] ] = '\0' ;
01548
01549 file[0] = '\0' ;
01550 name_in_file[0] = '\0' ;
01551
01553 separator = strchr (link_data, ADF_file[file_index].link_separator);
01554 if (separator == NULL) {
01555 lenfilename = 0;
01556 } else {
01557 lenfilename = (size_t)(separator - link_data);
01558 }
01559
01560 if ( lenfilename == 0 )
01561 {
01562 strcpy( name_in_file, &link_data[1] );
01563 }
01564 else if ( lenfilename > 0 && lenfilename == strlen( link_data ) )
01565 {
01566 strcpy( file, link_data) ;
01567 }
01568 else
01569 {
01570 strncpy( file, link_data, lenfilename) ;
01571 file[lenfilename] = '\0';
01572 strcpy( name_in_file, &link_data[lenfilename+1] );
01573 }
01574
01575 }
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590 void ADF_Link_Size(
01591 const double ID,
01592 int *len_file,
01593 int *len_name,
01594 int *error_return )
01595 {
01596 unsigned int file_index ;
01597 int file_bytes, machine_bytes, total_bytes ;
01598 char file_format, machine_format ;
01599 struct DISK_POINTER block_offset ;
01600 struct NODE_HEADER node_header ;
01601 struct TOKENIZED_DATA_TYPE tokenized_data_type[ 2 ] ;
01602 char link_data[ADF_FILENAME_LENGTH + ADF_MAX_LINK_DATA_SIZE + 1 + 1] ;
01603 size_t lenfilename ;
01604 char *separator;
01605
01606 if( len_name == NULL ) {
01607 *error_return = NULL_POINTER ;
01608 CHECK_ADF_ABORT( *error_return ) ;
01609 }
01610
01611 if( len_file == NULL ) {
01612 *error_return = NULL_POINTER ;
01613 CHECK_ADF_ABORT( *error_return ) ;
01614 }
01616 ADFI_ID_2_file_block_offset( ID, &file_index, &block_offset.block,
01617 &block_offset.offset, error_return ) ;
01618 CHECK_ADF_ABORT( *error_return ) ;
01619
01621 ADFI_read_node_header( file_index, &block_offset, &node_header, error_return ) ;
01622 CHECK_ADF_ABORT( *error_return ) ;
01623
01624 *len_name = *len_file = 0;
01625 if( (node_header.data_type[0] != 'L') || (node_header.data_type[1] != 'K')) {
01626 return ;
01627 }
01628
01630 ADFI_evaluate_datatype( file_index, node_header.data_type,
01631 &file_bytes, &machine_bytes, tokenized_data_type,
01632 &file_format, &machine_format, error_return ) ;
01633 CHECK_ADF_ABORT( *error_return ) ;
01634
01635 total_bytes = file_bytes * node_header.dimension_values[0] ;
01636 ADFI_read_data_chunk( file_index, &node_header.data_chunks,
01637 tokenized_data_type, file_bytes, total_bytes,
01638 0, total_bytes, link_data, error_return ) ;
01639 CHECK_ADF_ABORT( *error_return ) ;
01640
01641
01642 link_data[ node_header.dimension_values[0] ] = '\0' ;
01643
01645 separator = strchr (link_data, ADF_file[file_index].link_separator);
01646 if (separator == NULL) {
01647 lenfilename = 0;
01648 } else {
01649 lenfilename = (size_t)(separator - link_data);
01650 }
01651
01652 if ( lenfilename == 0 )
01653 {
01654 *len_name = strlen(link_data) - 1;
01655 }
01656 else if ( lenfilename > 0 && lenfilename == strlen( link_data ) )
01657 {
01658 *len_file = lenfilename;
01659 }
01660 else
01661 {
01662 *len_file = lenfilename;
01663 *len_name = strlen(link_data) - lenfilename - 1;
01664 }
01665
01666 }
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679 void ADF_Get_Name(
01680 const double ID,
01681 char *name,
01682 int *error_return )
01683 {
01684 unsigned int file_index ;
01685 struct DISK_POINTER block_offset ;
01686 struct NODE_HEADER node ;
01687
01688 if( name == NULL ) {
01689 *error_return = NULL_STRING_POINTER ;
01690 CHECK_ADF_ABORT( *error_return ) ;
01691 }
01692
01693 *error_return = NO_ERROR ;
01694
01696 ADFI_ID_2_file_block_offset( ID, &file_index, &block_offset.block,
01697 &block_offset.offset, error_return ) ;
01698 CHECK_ADF_ABORT( *error_return ) ;
01699
01701 ADFI_read_node_header( file_index, &block_offset, &node, error_return ) ;
01702 CHECK_ADF_ABORT( *error_return ) ;
01703
01705 ADFI_string_2_C_string( node.name, ADF_NAME_LENGTH, name,
01706 error_return ) ;
01707 CHECK_ADF_ABORT( *error_return ) ;
01708
01709 }
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747 void ADF_Get_Node_ID(
01748 const double PID,
01749 const char *name,
01750 double *ID,
01751 int *error_return )
01752 {
01753 double LID ;
01754 int found ;
01755 int name_length ;
01756 unsigned int file_index ;
01757 struct DISK_POINTER parent_block_offset, sub_node_entry_location ;
01758 struct SUB_NODE_TABLE_ENTRY sub_node_entry ;
01759 struct NODE_HEADER node_header ;
01760 char *name_tmp, *name_ptr, *name_pos ;
01761
01762 if( name == NULL ) {
01763 *error_return = NULL_STRING_POINTER ;
01764 return ;
01765 }
01766
01767 name_length = strlen( name ) ;
01768 if( name_length == 0 ) {
01769 *error_return = STRING_LENGTH_ZERO ;
01770 return ;
01771 }
01772
01773 if( ID == NULL ) {
01774 *error_return = NULL_POINTER ;
01775 CHECK_ADF_ABORT( *error_return ) ;
01776 }
01777
01778 *error_return = NO_ERROR ;
01779
01780 *ID = PID ;
01782 if( name[0] == '/' ) {
01787 ADF_Get_Root_ID( PID, ID, error_return ) ;
01788 CHECK_ADF_ABORT( *error_return ) ;
01789
01791 if( name[ 1 ] == '\0' ) {
01792 return ;
01793 }
01794 }
01795
01796 name_tmp = (char *) malloc( (name_length + 1) * sizeof( char ) ) ;
01797 if( name_tmp == NULL ) {
01798 *error_return = MEMORY_ALLOCATION_FAILED ;
01799 CHECK_ADF_ABORT( *error_return ) ;
01800 }
01801
01802 strcpy( name_tmp, name ) ;
01803
01805 name_pos = name_tmp ;
01806 name_ptr = ADFI_strtok( name_tmp, &name_pos, "/" ) ;
01807 if( name_ptr == NULL ) {
01808 *error_return = INVALID_NODE_NAME ;
01809 CHECK_ADF_ABORT1( *error_return ) ;
01810 }
01811
01813 ADFI_chase_link( *ID, &LID, &file_index,
01814 &parent_block_offset, &node_header, error_return ) ;
01815 CHECK_ADF_ABORT1( *error_return ) ;
01816 *ID = LID ;
01817
01819 while( name_ptr ) {
01820
01822 ADFI_check_4_child_name( file_index, &parent_block_offset, name_ptr, &found,
01823 &sub_node_entry_location, &sub_node_entry, error_return ) ;
01824 CHECK_ADF_ABORT1( *error_return ) ;
01825
01826 if( found == 0 ) {
01827 *error_return = CHILD_NOT_OF_GIVEN_PARENT ;
01828 CHECK_ADF_ABORT1( *error_return ) ;
01829 }
01830
01832 ADFI_file_block_offset_2_ID( file_index,
01833 sub_node_entry.child_location.block,
01834 sub_node_entry.child_location.offset, ID, error_return ) ;
01835
01840 name_ptr = ADFI_strtok( name_tmp, &name_pos, "/" ) ;
01841
01845 if( name_ptr != NULL ) {
01846
01847 ADFI_chase_link( *ID, &LID, &file_index, &parent_block_offset,
01848 &node_header, error_return ) ;
01849 CHECK_ADF_ABORT1( *error_return ) ;
01850 *ID = LID ;
01851
01853 ADFI_ID_2_file_block_offset( *ID, &file_index,
01854 &parent_block_offset.block,
01855 &parent_block_offset.offset,
01856 error_return ) ;
01857 CHECK_ADF_ABORT1( *error_return ) ;
01858 }
01859
01860 }
01861
01862 free( name_tmp ) ;
01863
01864 }
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878 void ADF_Get_Number_of_Dimensions(
01879 const double ID,
01880 int *num_dims,
01881 int *error_return )
01882 {
01883 unsigned int file_index ;
01884 struct DISK_POINTER block_offset ;
01885 struct NODE_HEADER node ;
01886 double LID ;
01887
01888 if( num_dims == NULL ) {
01889 *error_return = NULL_POINTER ;
01890 CHECK_ADF_ABORT( *error_return ) ;
01891 }
01892
01893 *error_return = NO_ERROR ;
01894
01895 ADFI_chase_link( ID, &LID, &file_index, &block_offset,
01896 &node, error_return ) ;
01897 CHECK_ADF_ABORT( *error_return ) ;
01898
01900 *num_dims = node.number_of_dimensions ;
01901
01902 }
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913 void ADF_Get_Root_ID(
01914 const double ID,
01915 double *Root_ID,
01916 int *error_return )
01917 {
01918 unsigned int file_index ;
01919 struct DISK_POINTER block_offset ;
01920 struct FILE_HEADER file_header ;
01921
01922 if( Root_ID == NULL ) {
01923 *error_return = NULL_POINTER ;
01924 CHECK_ADF_ABORT( *error_return ) ;
01925 }
01926
01927 *error_return = NO_ERROR ;
01928
01930 ADFI_ID_2_file_block_offset( ID, &file_index, &block_offset.block,
01931 &block_offset.offset, error_return ) ;
01932 CHECK_ADF_ABORT( *error_return ) ;
01933
01935 ADFI_read_file_header( file_index, &file_header, error_return ) ;
01936 CHECK_ADF_ABORT( *error_return ) ;
01937
01939 ADFI_file_block_offset_2_ID( file_index, file_header.root_node.block,
01940 file_header.root_node.offset, Root_ID, error_return ) ;
01941 CHECK_ADF_ABORT( *error_return ) ;
01942
01943 }
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959 void ADF_Is_Link(
01960 const double ID,
01961 int *link_path_length,
01962 int *error_return )
01963 {
01964 unsigned int file_index ;
01965 struct DISK_POINTER block_offset ;
01966 struct NODE_HEADER node_header ;
01967
01968 if( link_path_length == NULL ) {
01969 *error_return = NULL_POINTER ;
01970 CHECK_ADF_ABORT( *error_return ) ;
01971 }
01972
01974 ADFI_ID_2_file_block_offset( ID, &file_index, &block_offset.block,
01975 &block_offset.offset, error_return ) ;
01976 CHECK_ADF_ABORT( *error_return ) ;
01977
01979 ADFI_read_node_header( file_index, &block_offset, &node_header, error_return ) ;
01980 CHECK_ADF_ABORT( *error_return ) ;
01981
01982 if( (node_header.data_type[0] == 'L') && (node_header.data_type[1] == 'K'))
01983 *link_path_length = node_header.dimension_values[0] ;
01984 else
01985 *link_path_length = 0 ;
01986
01987 }
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002 void ADF_Library_Version(
02003 char *version,
02004 int *error_return )
02005 {
02006
02007 int lversion;
02008
02009 if( version == NULL ) {
02010 *error_return = NULL_STRING_POINTER ;
02011 CHECK_ADF_ABORT( *error_return ) ;
02012 }
02013
02014 *error_return = NO_ERROR ;
02015
02017 strcpy ( version, &ADF_L_identification[4] ) ;
02018 lversion = strlen ( version ) ;
02019 version[lversion-1] = '\0' ;
02020 }
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044 void ADF_Link(
02045 const double PID,
02046 const char *name,
02047 const char *file_name,
02048 const char *name_in_file,
02049 double *ID,
02050 int *error_return )
02051 {
02052 char link_data[ADF_FILENAME_LENGTH +
02053 ADF_MAX_LINK_DATA_SIZE + 2] ;
02054 int null_filename = FALSE ;
02055 int filename_length, linked_to_length, data_length ;
02056 int dim_vals[1] ;
02057 unsigned int file_index ;
02058 struct DISK_POINTER block_offset ;
02059 struct NODE_HEADER node_header ;
02060
02063 ADFI_check_string_length( name, ADF_NAME_LENGTH, error_return ) ;
02064 CHECK_ADF_ABORT( *error_return ) ;
02065
02066 ADFI_check_string_length( name_in_file, ADF_MAX_LINK_DATA_SIZE, error_return );
02067 CHECK_ADF_ABORT( *error_return ) ;
02068
02069 ADF_Is_Link( PID, &linked_to_length, error_return ) ;
02070 CHECK_ADF_ABORT( *error_return ) ;
02071 if ( linked_to_length > 0 ) {
02072 *error_return = LINKS_TOO_DEEP ;
02073 CHECK_ADF_ABORT( *error_return ) ;
02074 }
02075
02077 ADF_Create( PID, name, ID, error_return ) ;
02078 CHECK_ADF_ABORT( *error_return ) ;
02079
02081 ADFI_ID_2_file_block_offset( *ID, &file_index, &block_offset.block,
02082 &block_offset.offset, error_return ) ;
02083 CHECK_ADF_ABORT( *error_return ) ;
02084
02086 ADFI_check_string_length( file_name, ADF_FILENAME_LENGTH, error_return ) ;
02087 if( *error_return != NO_ERROR ) {
02088 null_filename = TRUE ;
02089 filename_length = 0 ;
02090 }
02091 else {
02092 filename_length = strlen( file_name) ;
02093 }
02094 linked_to_length = strlen( name_in_file ) ;
02095
02096 data_length = filename_length + linked_to_length + 1 ;
02097 if( data_length > ADF_FILENAME_LENGTH + ADF_MAX_LINK_DATA_SIZE + 1 ) {
02098 *error_return = STRING_LENGTH_TOO_BIG ;
02099 CHECK_ADF_ABORT( *error_return ) ;
02100 }
02101
02102 if( null_filename == TRUE ) {
02103 sprintf( link_data, "%c%s", ADF_file[file_index].link_separator,
02104 name_in_file ) ;
02105 }
02106 else {
02107 sprintf( link_data, "%s%c%s", file_name,
02108 ADF_file[file_index].link_separator, name_in_file ) ;
02109 }
02110
02116 dim_vals[0] = data_length ;
02117 ADF_Put_Dimension_Information( *ID, "C1", 1, dim_vals, error_return ) ;
02118 CHECK_ADF_ABORT( *error_return ) ;
02119
02120 ADF_Write_All_Data( *ID, link_data, error_return ) ;
02121 CHECK_ADF_ABORT( *error_return ) ;
02122
02128 ADFI_read_node_header( file_index, &block_offset, &node_header, error_return );
02129 CHECK_ADF_ABORT( *error_return ) ;
02130
02131 if( (node_header.data_type[0] != 'C') || (node_header.data_type[1] != '1') ||
02132 (node_header.data_type[2] != ' ') ) {
02133 *error_return = INVALID_DATA_TYPE ;
02134 CHECK_ADF_ABORT( *error_return ) ;
02135 }
02136
02137 node_header.data_type[0] = 'L' ;
02138 node_header.data_type[1] = 'K' ;
02139 ADFI_write_node_header( file_index, &block_offset, &node_header, error_return );
02140 CHECK_ADF_ABORT( *error_return ) ;
02141
02143 ADFI_write_modification_date( file_index, error_return ) ;
02144 CHECK_ADF_ABORT( *error_return ) ;
02145
02146 }
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162 void ADF_Move_Child(
02163 const double PID,
02164 const double ID,
02165 const double NPID,
02166 int *error_return )
02167 {
02168
02169 unsigned int parent_file_index, child_file_index,
02170 new_parent_file_index, file_index ;
02171 char child_name[ ADF_NAME_LENGTH ] ;
02172 int found ;
02173 struct DISK_POINTER parent, child, new_parent, sub_node_entry_location ;
02174 struct SUB_NODE_TABLE_ENTRY sub_node_entry ;
02175
02176 *error_return = NO_ERROR ;
02177
02178 ADFI_ID_2_file_block_offset( PID, &parent_file_index, &parent.block,
02179 &parent.offset, error_return ) ;
02180 CHECK_ADF_ABORT( *error_return ) ;
02181
02182 ADFI_ID_2_file_block_offset( ID, &child_file_index, &child.block,
02183 &child.offset, error_return ) ;
02184 CHECK_ADF_ABORT( *error_return ) ;
02185
02186 if( child_file_index != parent_file_index ) {
02187 *error_return = NODES_NOT_IN_SAME_FILE ;
02188 CHECK_ADF_ABORT( *error_return ) ;
02189 }
02190
02191 ADFI_ID_2_file_block_offset( NPID, &new_parent_file_index, &new_parent.block,
02192 &new_parent.offset, error_return ) ;
02193 CHECK_ADF_ABORT( *error_return ) ;
02194
02195 if( new_parent_file_index != parent_file_index ) {
02196 *error_return = NODES_NOT_IN_SAME_FILE ;
02197 CHECK_ADF_ABORT( *error_return ) ;
02198 }
02199
02200 file_index = parent_file_index ;
02201
02202
02203
02205 ADF_Get_Name( ID, child_name, error_return ) ;
02206 CHECK_ADF_ABORT( *error_return ) ;
02207
02208 ADFI_check_4_child_name( file_index, &parent, child_name, &found,
02209 &sub_node_entry_location, &sub_node_entry, error_return ) ;
02210 CHECK_ADF_ABORT( *error_return ) ;
02211
02212 if( found == 0 ) {
02213 *error_return = CHILD_NOT_OF_GIVEN_PARENT ;
02214 CHECK_ADF_ABORT( *error_return ) ;
02215 }
02216
02218 ADFI_add_2_sub_node_table( file_index, &new_parent, &child, error_return ) ;
02219 CHECK_ADF_ABORT( *error_return ) ;
02220
02222 ADFI_delete_from_sub_node_table( file_index, &parent, &child, error_return ) ;
02223 CHECK_ADF_ABORT( *error_return ) ;
02224
02225 }
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240 void ADF_Number_of_Children(
02241 const double ID,
02242 int *num_children,
02243 int *error_return )
02244 {
02245 unsigned int file_index ;
02246 struct DISK_POINTER block_offset ;
02247 struct NODE_HEADER node ;
02248 double LID ;
02249
02250 if( num_children == NULL ) {
02251 *error_return = NULL_POINTER ;
02252 CHECK_ADF_ABORT( *error_return ) ;
02253 }
02254
02255 *error_return = NO_ERROR ;
02256
02257 ADFI_chase_link( ID, &LID, &file_index, &block_offset, &node, error_return ) ;
02258 CHECK_ADF_ABORT( *error_return ) ;
02259
02261 *num_children = node.num_sub_nodes ;
02262 }
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305 void ADF_Put_Dimension_Information(
02306 const double ID,
02307 const char *data_type,
02308 const int dims,
02309 const int dim_vals[],
02310 int *error_return )
02311 {
02312 unsigned int file_index ;
02313 struct DISK_POINTER block_offset ;
02314 struct NODE_HEADER node ;
02315 struct TOKENIZED_DATA_TYPE
02316 tokenized_data_type[ 1 + (ADF_DATA_TYPE_LENGTH + 1)/3 ] ;
02317 char file_format, machine_format ;
02318 int file_bytes[2], machine_bytes[2] ;
02319 int data_bytes, old_data_bytes ;
02320 int i, datatype_length ;
02321 int preserve_data = FALSE ;
02322 double LID ;
02323
02324 ADFI_check_string_length( data_type, ADF_DATA_TYPE_LENGTH, error_return ) ;
02325 CHECK_ADF_ABORT( *error_return ) ;
02326
02327 if( dim_vals == NULL && dims > 0 ) {
02328 *error_return = NULL_POINTER ;
02329 CHECK_ADF_ABORT( *error_return ) ;
02330 }
02331
02332 *error_return = NO_ERROR ;
02333
02334 ADFI_chase_link( ID, &LID, &file_index, &block_offset, &node, error_return ) ;
02335 CHECK_ADF_ABORT( *error_return ) ;
02336
02338 ADFI_evaluate_datatype( file_index, data_type,
02339 &file_bytes[0], &machine_bytes[0],
02340 tokenized_data_type, &file_format, &machine_format, error_return ) ;
02341 CHECK_ADF_ABORT( *error_return ) ;
02342
02344 ADFI_evaluate_datatype( file_index, node.data_type,
02345 &file_bytes[1], &machine_bytes[1],
02346 tokenized_data_type, &file_format, &machine_format, error_return ) ;
02347 CHECK_ADF_ABORT( *error_return ) ;
02348
02350 if( dims < 0 ) {
02351 *error_return = NUMBER_LESS_THAN_MINIMUM ;
02352 CHECK_ADF_ABORT( *error_return ) ;
02353 }
02354 if( dims > ADF_MAX_DIMENSIONS) {
02355 *error_return = BAD_NUMBER_OF_DIMENSIONS ;
02356 CHECK_ADF_ABORT( *error_return ) ;
02357 }
02358
02360 if( dims == 0 )
02361 data_bytes = 0 ;
02362 else {
02363 for( data_bytes=file_bytes[0], i=0; i<dims; i++ ) {
02364 if( dim_vals[i] <=0 ) {
02365 *error_return = BAD_DIMENSION_VALUE ;
02366 CHECK_ADF_ABORT( *error_return ) ;
02367 }
02368 data_bytes *= dim_vals[i] ;
02369 }
02370 }
02371
02373 if( node.number_of_dimensions == 0 )
02374 old_data_bytes = 0 ;
02375 else {
02376 for( old_data_bytes=file_bytes[1], i=0;
02377 i<(int)node.number_of_dimensions; i++ )
02378 old_data_bytes *= node.dimension_values[i] ;
02379 }
02380
02381
02383 if( ADFI_stridx_c( node.data_type, data_type ) == 0 ) {
02384 if( dims == (int) node.number_of_dimensions )
02385 preserve_data = TRUE ;
02386 }
02388 else {
02389 datatype_length = strlen( data_type ) ;
02391 for( i=0; i<MIN(datatype_length, ADF_DATA_TYPE_LENGTH); i++ ) {
02392 node.data_type[i] = data_type[i] ;
02393 }
02395 for( ; i<ADF_DATA_TYPE_LENGTH; i++ ) {
02396 node.data_type[i] = ' ' ;
02397 }
02398 }
02399
02401 node.number_of_dimensions = dims ;
02402 for( i=0; i<dims; i++ )
02403 node.dimension_values[i] = dim_vals[i] ;
02404 for( ; i<ADF_MAX_DIMENSIONS; i++ )
02405 node.dimension_values[i] = 0 ;
02406
02407 if( preserve_data != TRUE ) {
02408 ADFI_delete_data( file_index, &node, error_return ) ;
02409 CHECK_ADF_ABORT( *error_return ) ;
02410
02411 node.number_of_data_chunks = 0 ;
02412 ADFI_set_blank_disk_pointer( &node.data_chunks ) ;
02413 }
02414
02416 ADFI_write_node_header( file_index, &block_offset, &node, error_return ) ;
02417 CHECK_ADF_ABORT( *error_return ) ;
02418
02420 ADFI_write_modification_date( file_index, error_return ) ;
02421 CHECK_ADF_ABORT( *error_return ) ;
02422
02423 }
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438 void ADF_Put_Name(
02439 const double PID,
02440 const double ID,
02441 const char *name,
02442 int *error_return )
02443 {
02444 unsigned int file_index ;
02445 struct DISK_POINTER parent_block_offset, child_block_offset ;
02446 struct DISK_POINTER sub_node_entry_location ;
02447 struct NODE_HEADER parent_node, child_node ;
02448 struct SUB_NODE_TABLE_ENTRY sub_node_entry ;
02449 int i, name_start, name_length, found ;
02450
02451 ADFI_check_string_length( name, ADF_NAME_LENGTH, error_return ) ;
02452 CHECK_ADF_ABORT( *error_return ) ;
02453
02454 *error_return = NO_ERROR ;
02455
02457 ADFI_ID_2_file_block_offset( PID, &file_index, &parent_block_offset.block,
02458 &parent_block_offset.offset, error_return ) ;
02459 CHECK_ADF_ABORT( *error_return ) ;
02460
02462 ADFI_ID_2_file_block_offset( ID, &file_index, &child_block_offset.block,
02463 &child_block_offset.offset, error_return ) ;
02464 CHECK_ADF_ABORT( *error_return ) ;
02465
02467 ADFI_read_node_header( file_index, &parent_block_offset,
02468 &parent_node, error_return ) ;
02469 CHECK_ADF_ABORT( *error_return ) ;
02470
02472 ADFI_read_node_header( file_index, &child_block_offset,
02473 &child_node, error_return ) ;
02474 CHECK_ADF_ABORT( *error_return ) ;
02475
02477 name_start = 0 ;
02478 while( name[ name_start ] == ' ' )
02479 name_start++ ;
02480 name_length = strlen( &name[ name_start ] ) ;
02481 if( name_length > ADF_NAME_LENGTH ) {
02482 *error_return = STRING_LENGTH_TOO_BIG ;
02483 CHECK_ADF_ABORT( *error_return ) ;
02484 }
02485
02486 if( name_length == 0 ) {
02487 *error_return = STRING_LENGTH_ZERO ;
02488 CHECK_ADF_ABORT( *error_return ) ;
02489 }
02490
02492 ADFI_check_4_child_name( file_index, &parent_block_offset,
02493 &name[ name_start ], &found, &sub_node_entry_location,
02494 &sub_node_entry, error_return ) ;
02495 CHECK_ADF_ABORT( *error_return ) ;
02496
02497 if( found == 1 ) {
02498 *error_return = DUPLICATE_CHILD_NAME ;
02499 CHECK_ADF_ABORT( *error_return ) ;
02500 }
02501
02502 for ( i=0; i < name_length; i++ ) {
02503 if ( ! isprint ( name[ name_start + i ] ) ||
02504 name[ name_start + i ] == '/' ) {
02505 *error_return = INVALID_NODE_NAME;
02506 CHECK_ADF_ABORT( *error_return ) ;
02507 }
02508 }
02509
02511 ADFI_check_4_child_name( file_index, &parent_block_offset,
02512 child_node.name, &found, &sub_node_entry_location,
02513 &sub_node_entry, error_return ) ;
02514 CHECK_ADF_ABORT( *error_return ) ;
02515
02516 if( found == 0 ) {
02517 *error_return = CHILD_NOT_OF_GIVEN_PARENT ;
02518 CHECK_ADF_ABORT( *error_return ) ;
02519 }
02520
02521 if( (child_block_offset.block != sub_node_entry.child_location.block) ||
02522 (child_block_offset.offset != sub_node_entry.child_location.offset) ) {
02523 *error_return = CHILD_NOT_OF_GIVEN_PARENT ;
02524 CHECK_ADF_ABORT( *error_return ) ;
02525 }
02526
02528 name_length = strlen( name ) ;
02529 for( i=0; i<MIN(name_length, ADF_NAME_LENGTH); i++ ) {
02530 child_node.name[i] = name[i] ;
02531 sub_node_entry.child_name[i] = name[i] ;
02532 }
02534 for( ; i<ADF_NAME_LENGTH; i++ ) {
02535 child_node.name[i] = ' ' ;
02536 sub_node_entry.child_name[i] = ' ' ;
02537 }
02538
02540 ADFI_write_node_header( file_index, &child_block_offset,
02541 &child_node, error_return ) ;
02542 CHECK_ADF_ABORT( *error_return ) ;
02543
02545 ADFI_write_sub_node_table_entry( file_index, &sub_node_entry_location,
02546 &sub_node_entry, error_return ) ;
02547 CHECK_ADF_ABORT( *error_return ) ;
02548
02550 ADFI_write_modification_date( file_index, error_return ) ;
02551 CHECK_ADF_ABORT( *error_return ) ;
02552
02553 }
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567 void ADF_Read_All_Data(
02568 const double ID,
02569 char *data,
02570 int *error_return )
02571 {
02572 unsigned int file_index ;
02573 struct DISK_POINTER block_offset ;
02574 struct NODE_HEADER node ;
02575 struct TOKENIZED_DATA_TYPE
02576 tokenized_data_type[ 1 + (ADF_DATA_TYPE_LENGTH + 1)/3 ] ;
02577 struct DATA_CHUNK_TABLE_ENTRY *data_chunk_table ;
02578 char *data_pointer ;
02579
02580 char file_format, machine_format ;
02581 int file_bytes, memory_bytes, bytes_to_read ;
02582 long total_bytes, bytes_read ;
02583 int i, j ;
02584 double LID ;
02585
02586 if( data == NULL ) {
02587 *error_return = NULL_POINTER ;
02588 CHECK_ADF_ABORT( *error_return ) ;
02589 }
02590
02591 *error_return = NO_ERROR ;
02592
02593 ADFI_chase_link( ID, &LID, &file_index, &block_offset, &node, error_return ) ;
02594 CHECK_ADF_ABORT( *error_return ) ;
02595
02597 ADFI_evaluate_datatype( file_index, node.data_type, &file_bytes, &memory_bytes,
02598 tokenized_data_type, &file_format, &machine_format, error_return ) ;
02599 CHECK_ADF_ABORT( *error_return ) ;
02600
02601 if( (file_bytes == 0) || (node.number_of_dimensions == 0) ) {
02602 *error_return = NO_DATA ;
02603 CHECK_ADF_ABORT( *error_return ) ;
02604 }
02605
02607 total_bytes = file_bytes ;
02608 for( j=0; j<(int)node.number_of_dimensions; j++ )
02609 total_bytes *= node.dimension_values[j] ;
02610
02612 if( node.number_of_data_chunks == 0 ) {
02613 memset( data, 0, total_bytes*memory_bytes/file_bytes ) ;
02614 *error_return = NO_DATA ;
02615 return ;
02616 }
02617
02619 else if( node.number_of_data_chunks == 1 ) {
02620 ADFI_read_data_chunk( file_index, &node.data_chunks, tokenized_data_type,
02621 file_bytes, total_bytes, 0, total_bytes, data,
02622 error_return ) ;
02623 CHECK_ADF_ABORT( *error_return ) ;
02624 }
02625 else {
02627 data_chunk_table = (struct DATA_CHUNK_TABLE_ENTRY *)
02628 malloc( node.number_of_data_chunks * sizeof( *data_chunk_table ) ) ;
02629 if( data_chunk_table == NULL ) {
02630 *error_return = MEMORY_ALLOCATION_FAILED ;
02631 CHECK_ADF_ABORT( *error_return ) ;
02632 }
02633
02635 ADFI_read_data_chunk_table( file_index, &node.data_chunks,
02636 data_chunk_table, error_return ) ;
02637 CHECK_ADF_ABORT( *error_return ) ;
02638
02640 bytes_read = 0 ;
02641 data_pointer = data ;
02642 for( i=0; i<(int)node.number_of_data_chunks; i++ ) {
02643 bytes_to_read =
02644 (data_chunk_table[i].end.block - data_chunk_table[i].start.block) *
02645 DISK_BLOCK_SIZE +
02646 (data_chunk_table[i].end.offset - data_chunk_table[i].start.offset) -
02647 (TAG_SIZE + DISK_POINTER_SIZE) ;
02648
02652 if( bytes_read + bytes_to_read > total_bytes ) {
02653 bytes_to_read = total_bytes - bytes_read ;
02654 }
02655 if( bytes_to_read == 0 )
02656 break ;
02657 ADFI_read_data_chunk( file_index, &data_chunk_table[i].start,
02658 tokenized_data_type, file_bytes, bytes_to_read, 0,
02659 bytes_to_read, data_pointer, error_return ) ;
02660 CHECK_ADF_ABORT( *error_return ) ;
02661
02665 data_pointer += (bytes_to_read * memory_bytes) / file_bytes ;
02666 bytes_read += bytes_to_read ;
02667 }
02668 free( data_chunk_table ) ;
02669 if( bytes_read < total_bytes ) {
02670 *error_return = INCOMPLETE_DATA ;
02671 memset( data_pointer, 0, total_bytes - bytes_read ) ;
02672 }
02673 }
02674
02675 }
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691 void ADF_Read_Block_Data(
02692 const double ID,
02693 const long b_start,
02694 const long b_end,
02695 char *data,
02696 int *error_return )
02697 {
02698 unsigned int file_index ;
02699 struct DISK_POINTER block_offset ;
02700 struct NODE_HEADER node ;
02701 struct TOKENIZED_DATA_TYPE
02702 tokenized_data_type[ 1 + (ADF_DATA_TYPE_LENGTH + 1)/3 ] ;
02703 struct DATA_CHUNK_TABLE_ENTRY *data_chunk_table ;
02704 char *data_pointer ;
02705
02706 char file_format, machine_format ;
02707 int file_bytes, memory_bytes, bytes_to_read ;
02708 long total_bytes, bytes_read, start_offset ;
02709 long chunk_size, chunk_end_byte ;
02710 long start_byte, end_byte, block_bytes ;
02711 int i, j ;
02712 double LID ;
02713
02714 if( data == NULL ) {
02715 *error_return = NULL_POINTER ;
02716 CHECK_ADF_ABORT( *error_return ) ;
02717 }
02718
02719 *error_return = NO_ERROR ;
02720
02721 ADFI_chase_link( ID, &LID, &file_index, &block_offset, &node, error_return ) ;
02722 CHECK_ADF_ABORT( *error_return ) ;
02723
02725 ADFI_evaluate_datatype( file_index, node.data_type, &file_bytes, &memory_bytes,
02726 tokenized_data_type, &file_format, &machine_format, error_return ) ;
02727 CHECK_ADF_ABORT( *error_return ) ;
02728
02729 if( (file_bytes == 0) || (node.number_of_dimensions == 0) ) {
02730 *error_return = NO_DATA ;
02731 CHECK_ADF_ABORT( *error_return ) ;
02732 }
02733
02735 total_bytes = file_bytes ;
02736 for( j=0; j<(int)node.number_of_dimensions; j++ )
02737 total_bytes *= node.dimension_values[j] ;
02738 if( total_bytes == 0 ) {
02739 *error_return = ZERO_DIMENSIONS ;
02740 CHECK_ADF_ABORT( *error_return ) ;
02741 }
02742
02744 start_byte = file_bytes * (b_start-1) ;
02745 end_byte = file_bytes * b_end ;
02746 if ( start_byte < 0 || start_byte > end_byte || end_byte > total_bytes ) {
02747 *error_return = START_OUT_OF_DEFINED_RANGE ;
02748 CHECK_ADF_ABORT( *error_return ) ;
02749 }
02750 block_bytes = end_byte - start_byte ;
02751
02753 if( node.number_of_data_chunks == 0 ) {
02754 memset( data, 0, block_bytes*memory_bytes/file_bytes ) ;
02755 *error_return = NO_DATA ;
02756 return ;
02757 }
02758
02760 else if( node.number_of_data_chunks == 1 ) {
02761 ADFI_read_data_chunk( file_index, &node.data_chunks, tokenized_data_type,
02762 file_bytes, total_bytes, start_byte, block_bytes,
02763 data, error_return ) ;
02764 CHECK_ADF_ABORT( *error_return ) ;
02765 }
02766 else {
02768 data_chunk_table = (struct DATA_CHUNK_TABLE_ENTRY *)
02769 malloc( node.number_of_data_chunks * sizeof( *data_chunk_table ) ) ;
02770 if( data_chunk_table == NULL ) {
02771 *error_return = MEMORY_ALLOCATION_FAILED ;
02772 CHECK_ADF_ABORT( *error_return ) ;
02773 }
02774
02776 ADFI_read_data_chunk_table( file_index, &node.data_chunks,
02777 data_chunk_table, error_return ) ;
02778 CHECK_ADF_ABORT( *error_return ) ;
02779
02781 bytes_read = 0 ;
02782 chunk_end_byte = 0 ;
02783 data_pointer = data ;
02784 for( i=0; i<(int)node.number_of_data_chunks; i++ ) {
02785 chunk_size =
02786 (data_chunk_table[i].end.block - data_chunk_table[i].start.block) *
02787 DISK_BLOCK_SIZE +
02788 (data_chunk_table[i].end.offset - data_chunk_table[i].start.offset) -
02789 (TAG_SIZE + DISK_POINTER_SIZE) ;
02790
02794 if( chunk_end_byte + chunk_size > total_bytes ) {
02795 chunk_size = total_bytes - chunk_end_byte ;
02796 }
02797 if( chunk_size == 0 )
02798 break ;
02799
02800 chunk_end_byte += chunk_size ;
02801
02803 if ( start_byte >= chunk_end_byte )
02804 continue ;
02805
02807 if ( start_byte > (chunk_end_byte - chunk_size) )
02810 start_offset = ( start_byte - (chunk_end_byte-chunk_size) ) ;
02811 else
02812 start_offset = 0 ;
02813
02815 bytes_to_read = chunk_size - start_offset ;
02816 if( bytes_read + bytes_to_read > block_bytes ) {
02817 bytes_to_read = block_bytes - bytes_read ;
02818 }
02819 if( bytes_to_read == 0 || (chunk_end_byte-chunk_size) > end_byte )
02820 break ;
02821
02822 ADFI_read_data_chunk( file_index, &data_chunk_table[i].start,
02823 tokenized_data_type, file_bytes, chunk_size, start_offset,
02824 bytes_to_read, data_pointer, error_return ) ;
02825 CHECK_ADF_ABORT( *error_return ) ;
02826
02830 data_pointer += (bytes_to_read * memory_bytes) / file_bytes ;
02831 bytes_read += bytes_to_read ;
02832 }
02833 free( data_chunk_table ) ;
02834 if( bytes_read < block_bytes ) {
02835 *error_return = INCOMPLETE_DATA ;
02836 memset( data_pointer, 0, total_bytes - bytes_read ) ;
02837 }
02838 }
02839
02840 }
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872 void ADF_Read_Data(
02873 const double ID,
02874 const int s_start[],
02875 const int s_end[],
02876 const int s_stride[],
02877 const int m_num_dims,
02878 const int m_dims[],
02879 const int m_start[],
02880 const int m_end[],
02881 const int m_stride[],
02882 char *data,
02883 int *error_return )
02884 {
02885 unsigned int file_index ;
02886 struct DISK_POINTER block_offset, relative_block ;
02887 struct NODE_HEADER node ;
02888 struct TOKENIZED_DATA_TYPE
02889 tokenized_data_type[ 1 + (ADF_DATA_TYPE_LENGTH + 1)/3 ] ;
02890 int current_disk[ADF_MAX_DIMENSIONS] ;
02891 int current_memory[ADF_MAX_DIMENSIONS] ;
02892 unsigned long total_disk_elements, total_memory_elements ;
02893 unsigned long disk_offset, memory_offset ;
02894 char disk_format, machine_format ;
02895 int formats_compare ;
02896 int i ;
02897 int file_bytes = 0 ;
02898 int memory_bytes = 0 ;
02899 int no_data = FALSE ;
02900 double LID ;
02901 unsigned long relative_offset = 0, current_chunk_size = 0,
02902 past_chunk_sizes, current_chunk ;
02903 struct DATA_CHUNK_TABLE_ENTRY *data_chunk_table = NULL;
02904
02905 if( (s_start == NULL) || (s_end == NULL) || (s_stride == NULL) ||
02906 (m_dims == NULL) || (m_start == NULL) || (m_end == NULL) ||
02907 (m_stride == NULL) || (data == NULL) ) {
02908 *error_return = NULL_POINTER ;
02909 CHECK_ADF_ABORT( *error_return ) ;
02910 }
02911
02912 *error_return = NO_ERROR ;
02913
02914 ADFI_chase_link( ID, &LID, &file_index, &block_offset, &node, error_return ) ;
02915 CHECK_ADF_ABORT( *error_return ) ;
02916
02918 ADFI_evaluate_datatype( file_index, node.data_type, &file_bytes, &memory_bytes,
02919 tokenized_data_type, &disk_format, &machine_format, error_return ) ;
02920 CHECK_ADF_ABORT( *error_return ) ;
02921
02922 if( (file_bytes == 0) || (node.number_of_dimensions == 0) ) {
02923 *error_return = NO_DATA ;
02924 CHECK_ADF_ABORT( *error_return ) ;
02925 }
02926
02927 ADFI_count_total_array_points( node.number_of_dimensions,
02928 node.dimension_values,
02929 s_start, s_end, s_stride,
02930 &total_disk_elements, &disk_offset,
02931 error_return ) ;
02932 CHECK_ADF_ABORT( *error_return ) ;
02933
02934 ADFI_count_total_array_points( (unsigned int)m_num_dims,
02935 (unsigned int *)m_dims,
02936 m_start, m_end, m_stride,
02937 &total_memory_elements, &memory_offset,
02938 error_return ) ;
02939 CHECK_ADF_ABORT( *error_return ) ;
02940
02941 if( total_disk_elements != total_memory_elements ) {
02942 *error_return = UNEQUAL_MEMORY_AND_DISK_DIMS ;
02943 CHECK_ADF_ABORT( *error_return ) ;
02944 }
02945
02946 ADFI_file_and_machine_compare( file_index, tokenized_data_type,
02947 &formats_compare, error_return ) ;
02948 CHECK_ADF_ABORT( *error_return ) ;
02949
02951 if( node.number_of_data_chunks == 0 ) {
02952 no_data = TRUE ;
02953 }
02955 else if( node.number_of_data_chunks == 1 ) {
02957 block_offset.block = node.data_chunks.block ;
02958 block_offset.offset = node.data_chunks.offset + TAG_SIZE +
02959 DISK_POINTER_SIZE + disk_offset * file_bytes ;
02960 ADFI_adjust_disk_pointer( &block_offset, error_return ) ;
02961 CHECK_ADF_ABORT( *error_return ) ;
02962 }
02963 else if( node.number_of_data_chunks > 1 ) {
02964 current_chunk = 0 ;
02965 past_chunk_sizes = 0 ;
02966 relative_offset = disk_offset * file_bytes ;
02968 data_chunk_table = (struct DATA_CHUNK_TABLE_ENTRY *)
02969 malloc( node.number_of_data_chunks * sizeof( *data_chunk_table ) ) ;
02970 if( data_chunk_table == NULL ) {
02971 *error_return = MEMORY_ALLOCATION_FAILED ;
02972 CHECK_ADF_ABORT( *error_return ) ;
02973 }
02974
02976 ADFI_read_data_chunk_table( file_index, &node.data_chunks,
02977 data_chunk_table, error_return ) ;
02978 CHECK_ADF_ABORT( *error_return ) ;
02979
02980 current_chunk_size = (data_chunk_table[ current_chunk ].end.block -
02981 data_chunk_table[ current_chunk ].start.block) * DISK_BLOCK_SIZE +
02982 (data_chunk_table[ current_chunk ].end.offset -
02983 data_chunk_table[ current_chunk ].start.offset) -
02984 (TAG_SIZE + DISK_POINTER_SIZE) ;
02985
02986 }
02987
02989 for( i=0; i<(int)node.number_of_dimensions; i++ )
02990 current_disk[i] = s_start[i] ;
02991 for( i=0; i<m_num_dims; i++ )
02992 current_memory[i] = m_start[i] ;
02993
02995 if( memory_offset != 0 )
02996 data += memory_offset * memory_bytes ;
02997 for( i=0; i<total_disk_elements; i++ ) {
02999 if( no_data == TRUE ) {
03000 memset( data, 0, memory_bytes ) ;
03001 }
03002 else if( node.number_of_data_chunks == 1 ) {
03004 if ( block_offset.offset > DISK_BLOCK_SIZE ) {
03005 ADFI_adjust_disk_pointer( &block_offset, error_return ) ;
03006 CHECK_ADF_ABORT( *error_return ) ;
03007 }
03008
03009 if( formats_compare ) {
03011 ADFI_read_file( file_index, block_offset.block, block_offset.offset,
03012 file_bytes, (char *)data, error_return ) ;
03013 CHECK_ADF_ABORT( *error_return ) ;
03014 }
03015 else {
03016 ADFI_read_data_translated( file_index, block_offset.block,
03017 block_offset.offset, tokenized_data_type, file_bytes,
03018 file_bytes, data, error_return ) ;
03019 CHECK_ADF_ABORT( *error_return ) ;
03020 }
03021
03026 if( i < total_disk_elements - 1 ) {
03027 if ( node.number_of_dimensions == 1 ) {
03028 disk_offset = s_stride[0];
03029 current_disk[0] += disk_offset;
03030 if ( current_disk[0] > s_end[0] ) current_disk[0] = s_end[0] ;
03031 }
03032 else {
03033 ADFI_increment_array(
03034 node.number_of_dimensions, node.dimension_values,
03035 s_start, s_end, s_stride, current_disk, &disk_offset,
03036 error_return ) ;
03037 CHECK_ADF_ABORT( *error_return ) ;
03038 }
03039
03040 block_offset.offset += disk_offset * file_bytes ;
03041 if ( block_offset.offset > DISK_BLOCK_SIZE ) {
03042 ADFI_adjust_disk_pointer( &block_offset, error_return ) ;
03043 CHECK_ADF_ABORT( *error_return ) ;
03044 }
03045 }
03046 }
03047 else if( node.number_of_data_chunks > 1 ) {
03048 while( relative_offset >= past_chunk_sizes + current_chunk_size ) {
03049 if( ++current_chunk >= node.number_of_data_chunks ) {
03050 *error_return = INCOMPLETE_DATA ;
03051 CHECK_ADF_ABORT( *error_return ) ;
03052 }
03053 else {
03054 past_chunk_sizes += current_chunk_size ;
03055 current_chunk_size = (data_chunk_table[ current_chunk ].end.block -
03056 data_chunk_table[ current_chunk ].start.block) * DISK_BLOCK_SIZE +
03057 (data_chunk_table[ current_chunk ].end.offset -
03058 data_chunk_table[ current_chunk ].start.offset) -
03059 (TAG_SIZE + DISK_POINTER_SIZE) ;
03060 }
03061 }
03062
03064 relative_block.block = data_chunk_table[ current_chunk ].start.block ;
03065 relative_block.offset = data_chunk_table[ current_chunk ].start.offset +
03066 (TAG_SIZE + DISK_POINTER_SIZE) +
03067 (relative_offset - past_chunk_sizes) ;
03068 if ( relative_block.offset > DISK_BLOCK_SIZE ) {
03069 ADFI_adjust_disk_pointer( &relative_block, error_return ) ;
03070 CHECK_ADF_ABORT( *error_return ) ;
03071 }
03072
03073 if( formats_compare ) {
03075 ADFI_read_file( file_index, relative_block.block, relative_block.offset,
03076 file_bytes, (char *)data, error_return ) ;
03077 CHECK_ADF_ABORT( *error_return ) ;
03078 }
03079 else {
03080 ADFI_read_data_translated( file_index, relative_block.block,
03081 relative_block.offset, tokenized_data_type, file_bytes,
03082 file_bytes, data, error_return ) ;
03083 CHECK_ADF_ABORT( *error_return ) ;
03084 }
03085
03087 if( i < total_disk_elements - 1 ) {
03088 if ( node.number_of_dimensions == 1 ) {
03089 disk_offset = s_stride[0];
03090 current_disk[0] += disk_offset;
03091 if ( current_disk[0] > s_end[0] ) current_disk[0] = s_end[0] ;
03092 }
03093 else {
03094 ADFI_increment_array(
03095 node.number_of_dimensions, node.dimension_values,
03096 s_start, s_end, s_stride, current_disk, &disk_offset,
03097 error_return ) ;
03098 CHECK_ADF_ABORT( *error_return ) ;
03099 }
03100
03101 relative_offset += disk_offset * file_bytes ;
03102 }
03103 }
03104
03105 if( i < total_disk_elements - 1 ) {
03107 if ( m_num_dims == 1 ) {
03108 memory_offset = m_stride[0];
03109 current_memory[0] += disk_offset;
03110 if ( current_memory[0] > m_end[0] ) current_memory[0] = m_end[0] ;
03111 }
03112 else {
03113 ADFI_increment_array(
03114 (unsigned int)m_num_dims, (unsigned int* )m_dims,
03115 m_start, m_end, m_stride,
03116 current_memory, &memory_offset, error_return ) ;
03117 CHECK_ADF_ABORT( *error_return ) ;
03118 }
03119
03121 data += memory_offset * memory_bytes ;
03122 }
03123 }
03124
03125 if( node.number_of_data_chunks > 1 )
03126 free( data_chunk_table ) ;
03127
03128 }
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143 void ADF_Set_Error_State(
03144 const int error_state,
03145 int *error_return )
03146 {
03147 *error_return = NO_ERROR ;
03148 if( error_state == 0 )
03149 ADF_abort_on_error = FALSE ;
03150 else if( error_state == 1 )
03151 ADF_abort_on_error = TRUE ;
03152 else {
03153 *error_return = BAD_ERROR_STATE ;
03154 CHECK_ADF_ABORT( *error_return ) ;
03155 }
03156
03157 }
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170 void ADF_Set_Label(
03171 const double ID,
03172 const char *label,
03173 int *error_return )
03174 {
03175 unsigned int file_index ;
03176 struct DISK_POINTER block_offset ;
03177 struct NODE_HEADER node ;
03178 int i, label_length ;
03179 double LID ;
03180
03182 *error_return = NO_ERROR ;
03183
03184 ADFI_chase_link( ID, &LID, &file_index, &block_offset, &node, error_return ) ;
03185 CHECK_ADF_ABORT( *error_return ) ;
03186
03188 if( label == NULL )
03189 label_length = 0 ;
03190 else
03191 label_length = strlen( label ) ;
03192 if( label_length > ADF_LABEL_LENGTH ) {
03193 *error_return = STRING_LENGTH_TOO_BIG ;
03194 CHECK_ADF_ABORT( *error_return ) ;
03195 }
03196 for( i=0; i<MIN(label_length, ADF_LABEL_LENGTH); i++ )
03197 node.label[i] = label[i] ;
03199 for( ; i<ADF_LABEL_LENGTH; i++ )
03200 node.label[i] = ' ' ;
03201
03203 ADFI_write_node_header( file_index, &block_offset, &node, error_return ) ;
03204 CHECK_ADF_ABORT( *error_return ) ;
03205
03207 ADFI_write_modification_date( file_index, error_return ) ;
03208 CHECK_ADF_ABORT( *error_return ) ;
03209
03210 }
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225 void ADF_Write_All_Data(
03226 const double ID,
03227 const char *data,
03228 int *error_return )
03229 {
03230 unsigned int file_index ;
03231 struct DISK_POINTER block_offset, new_block_offset, dct_block_offset ;
03232 struct NODE_HEADER node ;
03233 struct TOKENIZED_DATA_TYPE
03234 tokenized_data_type[ 1 + (ADF_DATA_TYPE_LENGTH + 1)/3 ] ;
03235 struct DATA_CHUNK_TABLE_ENTRY data_chunk_entry_table[2], *data_chunk_table ;
03236 int file_bytes, memory_bytes ;
03237 long total_bytes, current_bytes ;
03238 int i, j ;
03239 char tag[TAG_SIZE+1] ;
03240 struct DISK_POINTER data_start, chunk_start, end_of_chunk_tag ;
03241 long chunk_total_bytes ;
03242 char file_format, machine_format ;
03243 double LID ;
03244
03245 if( data == NULL ) {
03246 *error_return = NULL_POINTER ;
03247 CHECK_ADF_ABORT( *error_return ) ;
03248 }
03249
03250 *error_return = NO_ERROR ;
03251
03252 ADFI_chase_link( ID, &LID, &file_index, &block_offset, &node, error_return ) ;
03253 CHECK_ADF_ABORT( *error_return ) ;
03254
03256 ADFI_evaluate_datatype( file_index, node.data_type, &file_bytes, &memory_bytes,
03257 tokenized_data_type, &file_format, &machine_format, error_return ) ;
03258 CHECK_ADF_ABORT( *error_return ) ;
03259
03261 total_bytes = file_bytes ;
03262 for( j=0; j<(int)node.number_of_dimensions; j++ )
03263 total_bytes *= node.dimension_values[j] ;
03264 if( total_bytes == 0 ) {
03265 *error_return = ZERO_DIMENSIONS ;
03266 CHECK_ADF_ABORT( *error_return ) ;
03267 }
03268
03270 if( node.number_of_data_chunks == 0 ) {
03271 ADFI_file_malloc( file_index,
03272 total_bytes + TAG_SIZE + TAG_SIZE + DISK_POINTER_SIZE,
03273 &node.data_chunks, error_return ) ;
03274 CHECK_ADF_ABORT( *error_return ) ;
03275
03277 ADFI_write_data_chunk( file_index, &node.data_chunks, tokenized_data_type,
03278 file_bytes, total_bytes, 0, total_bytes, data,
03279 error_return ) ;
03280 CHECK_ADF_ABORT( *error_return ) ;
03281
03283 node.number_of_data_chunks = 1 ;
03284 ADFI_write_node_header( file_index, &block_offset, &node, error_return ) ;
03285 CHECK_ADF_ABORT( *error_return ) ;
03286 }
03287 else if( node.number_of_data_chunks == 1 ) {
03289 ADFI_read_chunk_length( file_index, &node.data_chunks, tag,
03290 &end_of_chunk_tag, error_return ) ;
03291 CHECK_ADF_ABORT( *error_return ) ;
03292 tag[TAG_SIZE] = '\0' ;
03293
03295 if( ADFI_stridx_c( tag, data_chunk_start_tag ) != 0 ) {
03296 *error_return = ADF_DISK_TAG_ERROR ;
03297 CHECK_ADF_ABORT( *error_return ) ;
03298 }
03299
03301 data_start.block = node.data_chunks.block ;
03302 data_start.offset = node.data_chunks.offset + TAG_SIZE + DISK_POINTER_SIZE ;
03303 ADFI_adjust_disk_pointer( &data_start, error_return ) ;
03304 CHECK_ADF_ABORT( *error_return ) ;
03305
03307 chunk_total_bytes = end_of_chunk_tag.offset - data_start.offset +
03308 (end_of_chunk_tag.block - data_start.block) * DISK_BLOCK_SIZE ;
03309
03310
03313 if( total_bytes > chunk_total_bytes ) {
03315 ADFI_write_data_chunk( file_index, &node.data_chunks,
03316 tokenized_data_type, file_bytes, chunk_total_bytes, 0,
03317 chunk_total_bytes, data, error_return ) ;
03318 CHECK_ADF_ABORT( *error_return ) ;
03319
03321 total_bytes -= chunk_total_bytes ;
03322 ADFI_file_malloc( file_index,
03323 total_bytes + TAG_SIZE + TAG_SIZE + DISK_POINTER_SIZE,
03324 &new_block_offset, error_return ) ;
03325 CHECK_ADF_ABORT( *error_return ) ;
03326
03331 data += (chunk_total_bytes * memory_bytes ) / file_bytes ;
03332
03333 ADFI_write_data_chunk( file_index, &new_block_offset,
03334 tokenized_data_type, file_bytes, total_bytes, 0,
03335 total_bytes, data, error_return ) ;
03336 CHECK_ADF_ABORT( *error_return ) ;
03337
03339 ADFI_file_malloc( file_index, 2 * TAG_SIZE + 5 * DISK_POINTER_SIZE,
03340 &dct_block_offset, error_return ) ;
03341 CHECK_ADF_ABORT( *error_return ) ;
03342
03344 data_chunk_entry_table[0].start.block = node.data_chunks.block ;
03345 data_chunk_entry_table[0].start.offset = node.data_chunks.offset ;
03346 chunk_start.block = node.data_chunks.block ;
03347 chunk_start.offset = node.data_chunks.offset + TAG_SIZE ;
03348 ADFI_adjust_disk_pointer( &chunk_start, error_return ) ;
03349 CHECK_ADF_ABORT( *error_return ) ;
03351 ADFI_read_disk_pointer_from_disk( file_index,
03352 chunk_start.block, chunk_start.offset,
03353 &data_chunk_entry_table[0].end, error_return ) ;
03354 CHECK_ADF_ABORT( *error_return ) ;
03355 data_chunk_entry_table[1].start.block = new_block_offset.block ;
03356 data_chunk_entry_table[1].start.offset = new_block_offset.offset ;
03357 chunk_start.block = new_block_offset.block ;
03358 chunk_start.offset = new_block_offset.offset + TAG_SIZE ;
03359 ADFI_adjust_disk_pointer( &chunk_start, error_return ) ;
03360 CHECK_ADF_ABORT( *error_return ) ;
03362 ADFI_read_disk_pointer_from_disk( file_index,
03363 chunk_start.block, chunk_start.offset,
03364 &data_chunk_entry_table[1].end, error_return ) ;
03365 CHECK_ADF_ABORT( *error_return ) ;
03366 ADFI_write_data_chunk_table( file_index, &dct_block_offset,
03367 2, data_chunk_entry_table, error_return ) ;
03368
03371 node.data_chunks.block = dct_block_offset.block ;
03372 node.data_chunks.offset = dct_block_offset.offset ;
03373 node.number_of_data_chunks = 2 ;
03374 ADFI_write_node_header( file_index, &block_offset, &node, error_return ) ;
03375 CHECK_ADF_ABORT( *error_return ) ;
03376 }
03377 else {
03379 ADFI_write_data_chunk( file_index, &node.data_chunks,
03380 tokenized_data_type, file_bytes, total_bytes, 0,
03381 total_bytes, data, error_return ) ;
03382 CHECK_ADF_ABORT( *error_return ) ;
03383 }
03384 }
03385 else {
03389 data_chunk_table = (struct DATA_CHUNK_TABLE_ENTRY *)
03390 malloc( (node.number_of_data_chunks + 1 ) *
03391 sizeof( *data_chunk_table ) ) ;
03392 if( data_chunk_table == NULL ) {
03393 *error_return = MEMORY_ALLOCATION_FAILED ;
03394 CHECK_ADF_ABORT( *error_return ) ;
03395 }
03396
03398 ADFI_read_data_chunk_table( file_index, &node.data_chunks,
03399 data_chunk_table, error_return ) ;
03400 CHECK_ADF_ABORT( *error_return ) ;
03401
03403 for( i=0; i<(int)node.number_of_data_chunks; i++ ) {
03404 current_bytes = (data_chunk_table[i].end.block -
03405 data_chunk_table[i].start.block) * DISK_BLOCK_SIZE +
03406 (data_chunk_table[i].end.offset -
03407 data_chunk_table[i].start.offset) -
03408 (TAG_SIZE + DISK_POINTER_SIZE) ;
03410 current_bytes = MIN( current_bytes, total_bytes ) ;
03411 ADFI_write_data_chunk( file_index, &data_chunk_table[i].start,
03412 tokenized_data_type, file_bytes, current_bytes, 0,
03413 current_bytes, data, error_return ) ;
03414 CHECK_ADF_ABORT( *error_return ) ;
03415
03419 data += (current_bytes * memory_bytes ) / file_bytes ;
03420
03421 total_bytes -= current_bytes ;
03422 if( total_bytes <= 0 )
03423 break ;
03424 }
03425
03429 if( total_bytes > 0 ) {
03433 ADFI_file_malloc( file_index, 2 * TAG_SIZE + DISK_POINTER_SIZE +
03434 total_bytes,
03435 &data_chunk_table[ node.number_of_data_chunks ].start,
03436 error_return ) ;
03437 CHECK_ADF_ABORT( *error_return ) ;
03438
03439 data_chunk_table[ node.number_of_data_chunks ].end.block =
03440 data_chunk_table[ node.number_of_data_chunks ].start.block ;
03441 data_chunk_table[ node.number_of_data_chunks ].end.offset =
03442 data_chunk_table[ node.number_of_data_chunks ].start.offset +
03443 TAG_SIZE + DISK_POINTER_SIZE + total_bytes ;
03444 ADFI_adjust_disk_pointer(
03445 &data_chunk_table[ node.number_of_data_chunks ].end,
03446 error_return ) ;
03447 CHECK_ADF_ABORT( *error_return ) ;
03448
03450 ADFI_file_malloc( file_index, 2 * TAG_SIZE +
03451 (2 * (node.number_of_data_chunks + 1) + 1) * DISK_POINTER_SIZE,
03452 &dct_block_offset, error_return ) ;
03453 CHECK_ADF_ABORT( *error_return ) ;
03454
03455 ADFI_write_data_chunk_table( file_index, &dct_block_offset,
03456 node.number_of_data_chunks+1, data_chunk_table, error_return ) ;
03457 CHECK_ADF_ABORT( *error_return ) ;
03458
03459 ADFI_write_data_chunk( file_index,
03460 &data_chunk_table[node.number_of_data_chunks ].start,
03461 tokenized_data_type, file_bytes, total_bytes, 0,
03462 total_bytes, data, error_return ) ;
03463 CHECK_ADF_ABORT( *error_return ) ;
03464
03466 ADFI_file_free( file_index, &node.data_chunks, 0, error_return ) ;
03467 CHECK_ADF_ABORT( *error_return ) ;
03468
03471 node.number_of_data_chunks++ ;
03472 node.data_chunks.block = dct_block_offset.block ;
03473 node.data_chunks.offset = dct_block_offset.offset ;
03474 ADFI_write_node_header( file_index, &block_offset, &node,
03475 error_return ) ;
03476 CHECK_ADF_ABORT( *error_return ) ;
03477 }
03478 free( data_chunk_table ) ;
03479 }
03480
03482 ADFI_write_modification_date( file_index, error_return ) ;
03483 CHECK_ADF_ABORT( *error_return ) ;
03484
03485 }
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502 void ADF_Write_Block_Data(
03503 const double ID,
03504 const long b_start,
03505 const long b_end,
03506 char *data,
03507 int *error_return )
03508 {
03509 unsigned int file_index ;
03510 struct DISK_POINTER block_offset, new_block_offset, dct_block_offset ;
03511 struct NODE_HEADER node ;
03512 struct TOKENIZED_DATA_TYPE
03513 tokenized_data_type[ 1 + (ADF_DATA_TYPE_LENGTH + 1)/3 ] ;
03514 struct DATA_CHUNK_TABLE_ENTRY data_chunk_entry_table[2], *data_chunk_table ;
03515
03516 char file_format, machine_format ;
03517 int file_bytes, memory_bytes ;
03518 long total_bytes, bytes_written, bytes_to_write = 0;
03519 int i, j ;
03520 char tag[TAG_SIZE+1] ;
03521 struct DISK_POINTER data_start, chunk_start, end_of_chunk_tag ;
03522 long start_offset ;
03523 long chunk_size, chunk_end_byte ;
03524 long start_byte, end_byte, block_bytes ;
03525 double LID ;
03526
03527 if( data == NULL ) {
03528 *error_return = NULL_POINTER ;
03529 CHECK_ADF_ABORT( *error_return ) ;
03530 }
03531
03532 *error_return = NO_ERROR ;
03533
03534 ADFI_chase_link( ID, &LID, &file_index, &block_offset, &node, error_return ) ;
03535 CHECK_ADF_ABORT( *error_return ) ;
03536
03538 ADFI_evaluate_datatype( file_index, node.data_type, &file_bytes, &memory_bytes,
03539 tokenized_data_type, &file_format, &machine_format, error_return ) ;
03540 CHECK_ADF_ABORT( *error_return ) ;
03541
03543 total_bytes = file_bytes ;
03544 for( j=0; j<(int)node.number_of_dimensions; j++ )
03545 total_bytes *= node.dimension_values[j] ;
03546 if( total_bytes == 0 ) {
03547 *error_return = ZERO_DIMENSIONS ;
03548 CHECK_ADF_ABORT( *error_return ) ;
03549 }
03550
03552 start_byte = file_bytes * (b_start-1) ;
03553 end_byte = file_bytes * b_end ;
03554 if ( start_byte < 0 || start_byte > end_byte || end_byte > total_bytes ) {
03555 *error_return = START_OUT_OF_DEFINED_RANGE ;
03556 CHECK_ADF_ABORT( *error_return ) ;
03557 }
03558 block_bytes = end_byte - start_byte ;
03559
03561 if( node.number_of_data_chunks == 0 ) {
03562 ADFI_file_malloc( file_index,
03563 total_bytes + TAG_SIZE + TAG_SIZE + DISK_POINTER_SIZE,
03564 &node.data_chunks, error_return ) ;
03565 CHECK_ADF_ABORT( *error_return ) ;
03566
03568 ADFI_write_data_chunk( file_index, &node.data_chunks, tokenized_data_type,
03569 file_bytes, total_bytes, start_byte, block_bytes, data,
03570 error_return ) ;
03571 CHECK_ADF_ABORT( *error_return ) ;
03572
03574 node.number_of_data_chunks = 1 ;
03575 ADFI_write_node_header( file_index, &block_offset, &node, error_return ) ;
03576 CHECK_ADF_ABORT( *error_return ) ;
03577 }
03578 else if( node.number_of_data_chunks == 1 ) {
03580 ADFI_read_chunk_length( file_index, &node.data_chunks, tag,
03581 &end_of_chunk_tag, error_return ) ;
03582 CHECK_ADF_ABORT( *error_return ) ;
03583 tag[TAG_SIZE] = '\0' ;
03584
03586 if( ADFI_stridx_c( tag, data_chunk_start_tag ) != 0 ) {
03587 *error_return = ADF_DISK_TAG_ERROR ;
03588 CHECK_ADF_ABORT( *error_return ) ;
03589 }
03590
03592 data_start.block = node.data_chunks.block ;
03593 data_start.offset = node.data_chunks.offset + TAG_SIZE + DISK_POINTER_SIZE ;
03594 ADFI_adjust_disk_pointer( &data_start, error_return ) ;
03595 CHECK_ADF_ABORT( *error_return ) ;
03596
03598 chunk_size = end_of_chunk_tag.offset - data_start.offset +
03599 (end_of_chunk_tag.block - data_start.block) * DISK_BLOCK_SIZE ;
03600
03601
03604 if( total_bytes > chunk_size ) {
03606 bytes_written = 0 ;
03607 if ( start_byte <= chunk_size ) {
03608 bytes_to_write = MIN ( block_bytes, (chunk_size-start_byte) ) ;
03609 ADFI_write_data_chunk( file_index, &node.data_chunks,
03610 tokenized_data_type, file_bytes, chunk_size, start_byte,
03611 bytes_to_write, data, error_return ) ;
03612 CHECK_ADF_ABORT( *error_return ) ;
03613 bytes_written += bytes_to_write ;
03614 }
03615
03617 total_bytes -= chunk_size ;
03618 ADFI_file_malloc( file_index,
03619 total_bytes + TAG_SIZE + TAG_SIZE + DISK_POINTER_SIZE,
03620 &new_block_offset, error_return ) ;
03621 CHECK_ADF_ABORT( *error_return ) ;
03622
03627 data += (bytes_to_write * memory_bytes ) / file_bytes ;
03628
03629 if ( bytes_written < block_bytes ) {
03630 bytes_to_write = block_bytes - bytes_written ;
03631 start_offset = MAX ( 0L, (start_byte - chunk_size) ) ;
03632 ADFI_write_data_chunk( file_index, &new_block_offset,
03633 tokenized_data_type, file_bytes, total_bytes, start_offset,
03634 bytes_to_write, data, error_return ) ;
03635 CHECK_ADF_ABORT( *error_return ) ;
03636 }
03637 else {
03638 ADFI_write_data_chunk( file_index, &new_block_offset,
03639 tokenized_data_type, file_bytes, total_bytes, 0,
03640 total_bytes, NULL, error_return ) ;
03641 CHECK_ADF_ABORT( *error_return ) ;
03642 }
03643
03645 ADFI_file_malloc( file_index, 2 * TAG_SIZE + 5 * DISK_POINTER_SIZE,
03646 &dct_block_offset, error_return ) ;
03647 CHECK_ADF_ABORT( *error_return ) ;
03648
03650 data_chunk_entry_table[0].start.block = node.data_chunks.block ;
03651 data_chunk_entry_table[0].start.offset = node.data_chunks.offset ;
03653 chunk_start.block = node.data_chunks.block ;
03654 chunk_start.offset = node.data_chunks.offset + TAG_SIZE ;
03655 ADFI_adjust_disk_pointer( &chunk_start, error_return ) ;
03656 CHECK_ADF_ABORT( *error_return ) ;
03657 ADFI_read_disk_pointer_from_disk( file_index,
03658 chunk_start.block, chunk_start.offset,
03659 &data_chunk_entry_table[0].end, error_return ) ;
03660 CHECK_ADF_ABORT( *error_return ) ;
03661 data_chunk_entry_table[1].start.block = new_block_offset.block ;
03662 data_chunk_entry_table[1].start.offset = new_block_offset.offset ;
03663 chunk_start.block = new_block_offset.block ;
03664 chunk_start.offset = new_block_offset.offset + TAG_SIZE ;
03665 ADFI_adjust_disk_pointer( &chunk_start, error_return ) ;
03666 CHECK_ADF_ABORT( *error_return ) ;
03668 ADFI_read_disk_pointer_from_disk( file_index,
03669 chunk_start.block, chunk_start.offset,
03670 &data_chunk_entry_table[1].end, error_return ) ;
03671 CHECK_ADF_ABORT( *error_return ) ;
03672 ADFI_write_data_chunk_table( file_index, &dct_block_offset,
03673 2, data_chunk_entry_table, error_return ) ;
03674
03677 node.data_chunks.block = dct_block_offset.block ;
03678 node.data_chunks.offset = dct_block_offset.offset ;
03679 node.number_of_data_chunks = 2 ;
03680 ADFI_write_node_header( file_index, &block_offset, &node, error_return );
03681 CHECK_ADF_ABORT( *error_return ) ;
03682 }
03683 else {
03685 ADFI_write_data_chunk( file_index, &node.data_chunks,
03686 tokenized_data_type, file_bytes, chunk_size, start_byte,
03687 block_bytes, data, error_return ) ;
03688 CHECK_ADF_ABORT( *error_return ) ;
03689 }
03690 }
03691 else {
03695 data_chunk_table = (struct DATA_CHUNK_TABLE_ENTRY *)
03696 malloc( (node.number_of_data_chunks + 1 ) *
03697 sizeof( *data_chunk_table ) ) ;
03698 if( data_chunk_table == NULL ) {
03699 *error_return = MEMORY_ALLOCATION_FAILED ;
03700 CHECK_ADF_ABORT( *error_return ) ;
03701 }
03702
03704 ADFI_read_data_chunk_table( file_index, &node.data_chunks,
03705 data_chunk_table, error_return ) ;
03706 CHECK_ADF_ABORT( *error_return ) ;
03707
03709 chunk_end_byte = 0 ;
03710 bytes_written = 0 ;
03711 for( i=0; i<(int)node.number_of_data_chunks; i++ ) {
03712 chunk_size = (data_chunk_table[i].end.block -
03713 data_chunk_table[i].start.block) * DISK_BLOCK_SIZE +
03714 (data_chunk_table[i].end.offset -
03715 data_chunk_table[i].start.offset) -
03716 (TAG_SIZE + DISK_POINTER_SIZE) ;
03717 chunk_end_byte += chunk_size ;
03718
03720 if ( start_byte >= chunk_end_byte )
03721 continue ;
03722
03724 if ( start_byte > (chunk_end_byte - chunk_size) )
03727 start_offset = ( start_byte - (chunk_end_byte-chunk_size) ) ;
03728 else
03729 start_offset = 0 ;
03730
03732 bytes_to_write = chunk_size - start_offset ;
03733 if( bytes_written + bytes_to_write > block_bytes ) {
03734 bytes_to_write = block_bytes - bytes_written ;
03735 }
03736 if( bytes_to_write == 0 || (chunk_end_byte-chunk_size) > end_byte )
03737 continue ;
03738
03740 ADFI_write_data_chunk( file_index, &data_chunk_table[i].start,
03741 tokenized_data_type, file_bytes, chunk_size, start_offset,
03742 bytes_to_write, data, error_return ) ;
03743 CHECK_ADF_ABORT( *error_return ) ;
03744
03748 data += (bytes_to_write * memory_bytes ) / file_bytes ;
03749
03750 bytes_written += bytes_to_write ;
03751 }
03752
03755 total_bytes -= chunk_end_byte ;
03756 if( total_bytes > 0 ) {
03760 ADFI_file_malloc( file_index, 2 * TAG_SIZE + DISK_POINTER_SIZE +
03761 total_bytes,
03762 &data_chunk_table[ node.number_of_data_chunks ].start,
03763 error_return ) ;
03764 CHECK_ADF_ABORT( *error_return ) ;
03765
03766 data_chunk_table[ node.number_of_data_chunks ].end.block =
03767 data_chunk_table[ node.number_of_data_chunks ].start.block ;
03768 data_chunk_table[ node.number_of_data_chunks ].end.offset =
03769 data_chunk_table[ node.number_of_data_chunks ].start.offset +
03770 TAG_SIZE + DISK_POINTER_SIZE + total_bytes ;
03771 ADFI_adjust_disk_pointer(
03772 &data_chunk_table[ node.number_of_data_chunks ].end,
03773 error_return ) ;
03774 CHECK_ADF_ABORT( *error_return ) ;
03775
03777 ADFI_file_malloc( file_index, 2 * TAG_SIZE +
03778 (2 * (node.number_of_data_chunks + 1) + 1) * DISK_POINTER_SIZE,
03779 &dct_block_offset, error_return ) ;
03780 CHECK_ADF_ABORT( *error_return ) ;
03781
03782 ADFI_write_data_chunk_table( file_index, &dct_block_offset,
03783 node.number_of_data_chunks+1, data_chunk_table, error_return ) ;
03784 CHECK_ADF_ABORT( *error_return ) ;
03785
03786 if ( bytes_written < block_bytes ) {
03787 bytes_to_write = block_bytes - bytes_written ;
03788 start_offset = MAX ( 0L, (start_byte - total_bytes) ) ;
03789 ADFI_write_data_chunk( file_index,
03790 &data_chunk_table[node.number_of_data_chunks ].start,
03791 tokenized_data_type, file_bytes,
03792 total_bytes, start_offset, bytes_to_write,
03793 data, error_return ) ;
03794 CHECK_ADF_ABORT( *error_return ) ;
03795 }
03796 else {
03797 ADFI_write_data_chunk( file_index,
03798 &data_chunk_table[node.number_of_data_chunks ].start,
03799 tokenized_data_type, file_bytes, total_bytes, 0,
03800 total_bytes, NULL, error_return ) ;
03801 CHECK_ADF_ABORT( *error_return ) ;
03802 }
03803
03805 ADFI_file_free( file_index, &node.data_chunks, 0, error_return ) ;
03806 CHECK_ADF_ABORT( *error_return ) ;
03807
03810 node.number_of_data_chunks++ ;
03811 node.data_chunks.block = dct_block_offset.block ;
03812 node.data_chunks.offset = dct_block_offset.offset ;
03813 ADFI_write_node_header( file_index, &block_offset, &node,
03814 error_return ) ;
03815 CHECK_ADF_ABORT( *error_return ) ;
03816 }
03817 free( data_chunk_table ) ;
03818 }
03819
03821 ADFI_write_modification_date( file_index, error_return ) ;
03822 CHECK_ADF_ABORT( *error_return ) ;
03823
03824 }
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849 void ADF_Write_Data(
03850 const double ID,
03851 const int s_start[],
03852 const int s_end[],
03853 const int s_stride[],
03854 const int m_num_dims,
03855 const int m_dims[],
03856 const int m_start[],
03857 const int m_end[],
03858 const int m_stride[],
03859 const char *data,
03860 int *error_return )
03861 {
03862 unsigned int file_index ;
03863 struct DISK_POINTER block_offset, dct_block_offset, relative_block ;
03864 struct DISK_POINTER data_start, new_block_offset ;
03865 struct DISK_POINTER chunk_start, end_of_chunk_tag ;
03866 struct NODE_HEADER node ;
03867 struct DATA_CHUNK_TABLE_ENTRY *data_chunk_table ;
03868 struct TOKENIZED_DATA_TYPE
03869 tokenized_data_type[ 1 + (ADF_DATA_TYPE_LENGTH + 1)/3 ] ;
03870 int current_disk[ADF_MAX_DIMENSIONS] ;
03871 int current_memory[ADF_MAX_DIMENSIONS] ;
03872 unsigned long total_disk_elements, total_memory_elements ;
03873 unsigned long disk_offset, memory_offset ;
03874 int formats_compare ;
03875 char disk_format, machine_format ;
03876 int i ;
03877 int file_bytes = 0 ;
03878 int memory_bytes = 0 ;
03879 char tag[TAG_SIZE+1] ;
03880 unsigned long total_bytes ;
03881 long current_bytes, chunk_total_bytes ;
03882 double LID ;
03883 unsigned long relative_offset, current_chunk, current_chunk_size,
03884 past_chunk_sizes ;
03885
03886 if( (s_start == NULL) || (s_end == NULL) || (s_stride == NULL) ||
03887 (m_dims == NULL) || (m_start == NULL) || (m_end == NULL) ||
03888 (m_stride == NULL) || (data == NULL) ) {
03889 *error_return = NULL_POINTER ;
03890 CHECK_ADF_ABORT( *error_return ) ;
03891 }
03892
03893 *error_return = NO_ERROR ;
03894 data_chunk_table = 0L ;
03895
03896 ADFI_chase_link( ID, &LID, &file_index, &block_offset, &node, error_return ) ;
03897 CHECK_ADF_ABORT( *error_return ) ;
03898
03900 ADFI_evaluate_datatype( file_index, node.data_type, &file_bytes, &memory_bytes,
03901 tokenized_data_type, &disk_format, &machine_format, error_return ) ;
03902 CHECK_ADF_ABORT( *error_return ) ;
03903
03904 if( (file_bytes == 0) || (node.number_of_dimensions == 0) ) {
03905 *error_return = NO_DATA ;
03906 CHECK_ADF_ABORT( *error_return ) ;
03907 }
03908
03909 ADFI_count_total_array_points( node.number_of_dimensions,
03910 node.dimension_values,
03911 s_start, s_end, s_stride,
03912 &total_disk_elements, &disk_offset,
03913 error_return ) ;
03914 CHECK_ADF_ABORT( *error_return ) ;
03915
03916 ADFI_count_total_array_points( (unsigned int)m_num_dims,
03917 (unsigned int *)m_dims,
03918 m_start, m_end, m_stride,
03919 &total_memory_elements, &memory_offset,
03920 error_return ) ;
03921 CHECK_ADF_ABORT( *error_return ) ;
03922
03923 if( total_disk_elements != total_memory_elements ) {
03924 *error_return = UNEQUAL_MEMORY_AND_DISK_DIMS ;
03925 CHECK_ADF_ABORT( *error_return ) ;
03926 }
03927
03929 total_bytes = file_bytes ;
03930 for( i=0; i<(int)node.number_of_dimensions; i++ )
03931 total_bytes *= node.dimension_values[i] ;
03932 if( total_bytes == 0 ) {
03933 *error_return = ZERO_DIMENSIONS ;
03934 CHECK_ADF_ABORT( *error_return ) ;
03935 }
03936
03938 ADFI_file_and_machine_compare( file_index, tokenized_data_type,
03939 &formats_compare, error_return ) ;
03940 CHECK_ADF_ABORT( *error_return ) ;
03941
03943 if( node.number_of_data_chunks == 0 ) {
03944 ADFI_file_malloc( file_index,
03945 total_bytes + TAG_SIZE + TAG_SIZE + DISK_POINTER_SIZE,
03946 &node.data_chunks, error_return ) ;
03947 CHECK_ADF_ABORT( *error_return ) ;
03948
03951 ADFI_write_data_chunk( file_index, &node.data_chunks, tokenized_data_type,
03952 file_bytes, total_bytes, 0, total_bytes, 0L,
03953 error_return ) ;
03954 CHECK_ADF_ABORT( *error_return ) ;
03955
03957 node.number_of_data_chunks = 1 ;
03958 ADFI_write_node_header( file_index, &block_offset, &node, error_return ) ;
03959 CHECK_ADF_ABORT( *error_return ) ;
03960 }
03962 else if( node.number_of_data_chunks == 1 ) {
03964 ADFI_read_chunk_length( file_index, &node.data_chunks, tag,
03965 &end_of_chunk_tag, error_return ) ;
03966 CHECK_ADF_ABORT( *error_return ) ;
03967 tag[TAG_SIZE] = '\0' ;
03968
03970 if( ADFI_stridx_c( tag, data_chunk_start_tag ) != 0 ) {
03971 *error_return = ADF_DISK_TAG_ERROR ;
03972 CHECK_ADF_ABORT( *error_return ) ;
03973 }
03974
03976 data_start.block = node.data_chunks.block ;
03977 data_start.offset = node.data_chunks.offset + TAG_SIZE + DISK_POINTER_SIZE ;
03978 ADFI_adjust_disk_pointer( &data_start, error_return ) ;
03979 CHECK_ADF_ABORT( *error_return ) ;
03980
03982 chunk_total_bytes = end_of_chunk_tag.offset - data_start.offset +
03983 (end_of_chunk_tag.block - data_start.block) * DISK_BLOCK_SIZE ;
03984
03986 if( (long int) total_bytes > chunk_total_bytes ) {
03989 data_chunk_table = (struct DATA_CHUNK_TABLE_ENTRY *)
03990 malloc( (node.number_of_data_chunks + 1 ) *
03991 sizeof( *data_chunk_table ) ) ;
03992 if( data_chunk_table == NULL ) {
03993 *error_return = MEMORY_ALLOCATION_FAILED ;
03994 CHECK_ADF_ABORT( *error_return ) ;
03995 }
03996
03998 total_bytes -= chunk_total_bytes ;
03999 ADFI_file_malloc( file_index,
04000 total_bytes + TAG_SIZE + TAG_SIZE + DISK_POINTER_SIZE,
04001 &new_block_offset, error_return ) ;
04002 CHECK_ADF_ABORT( *error_return ) ;
04003
04005 ADFI_write_data_chunk( file_index, &new_block_offset,
04006 tokenized_data_type, file_bytes, total_bytes, 0,
04007 total_bytes, 0L, error_return ) ;
04008 CHECK_ADF_ABORT( *error_return ) ;
04009
04011 ADFI_file_malloc( file_index, 2 * TAG_SIZE + 5 * DISK_POINTER_SIZE,
04012 &dct_block_offset, error_return ) ;
04013 CHECK_ADF_ABORT( *error_return ) ;
04014
04016 data_chunk_table[0].start.block = node.data_chunks.block ;
04017 data_chunk_table[0].start.offset = node.data_chunks.offset ;
04018 chunk_start.block = node.data_chunks.block ;
04019 chunk_start.offset = node.data_chunks.offset + TAG_SIZE ;
04020 ADFI_adjust_disk_pointer( &chunk_start, error_return ) ;
04021 CHECK_ADF_ABORT( *error_return ) ;
04023 ADFI_read_disk_pointer_from_disk( file_index,
04024 chunk_start.block, chunk_start.offset,
04025 &data_chunk_table[0].end, error_return ) ;
04026 CHECK_ADF_ABORT( *error_return ) ;
04027 data_chunk_table[1].start.block = new_block_offset.block ;
04028 data_chunk_table[1].start.offset = new_block_offset.offset ;
04029 chunk_start.block = new_block_offset.block ;
04030 chunk_start.offset = new_block_offset.offset + TAG_SIZE ;
04031 ADFI_adjust_disk_pointer( &chunk_start, error_return ) ;
04032 CHECK_ADF_ABORT( *error_return ) ;
04034 ADFI_read_disk_pointer_from_disk( file_index,
04035 chunk_start.block, chunk_start.offset,
04036 &data_chunk_table[1].end, error_return ) ;
04037 CHECK_ADF_ABORT( *error_return ) ;
04038 ADFI_write_data_chunk_table( file_index, &dct_block_offset,
04039 2, data_chunk_table, error_return ) ;
04040
04043 node.data_chunks.block = dct_block_offset.block ;
04044 node.data_chunks.offset = dct_block_offset.offset ;
04045 node.number_of_data_chunks = 2 ;
04046 ADFI_write_node_header( file_index, &block_offset, &node, error_return ) ;
04047 CHECK_ADF_ABORT( *error_return ) ;
04048 }
04049 }
04050 else {
04053 data_chunk_table = (struct DATA_CHUNK_TABLE_ENTRY *)
04054 malloc( (node.number_of_data_chunks + 1 ) *
04055 sizeof( *data_chunk_table ) ) ;
04056 if( data_chunk_table == NULL ) {
04057 *error_return = MEMORY_ALLOCATION_FAILED ;
04058 CHECK_ADF_ABORT( *error_return ) ;
04059 }
04060
04062 ADFI_read_data_chunk_table( file_index, &node.data_chunks,
04063 data_chunk_table, error_return ) ;
04064 CHECK_ADF_ABORT( *error_return ) ;
04065
04067 for( i=0; i<(int)node.number_of_data_chunks; i++ ) {
04068 current_bytes = (data_chunk_table[i].end.block -
04069 data_chunk_table[i].start.block) * DISK_BLOCK_SIZE +
04070 (data_chunk_table[i].end.offset -
04071 data_chunk_table[i].start.offset) -
04072 (TAG_SIZE + DISK_POINTER_SIZE) ;
04073 total_bytes -= current_bytes ;
04074 if( total_bytes <= 0 )
04075 break ;
04076 }
04077
04080 if( total_bytes > 0 ) {
04084 ADFI_file_malloc( file_index, 2 * TAG_SIZE + DISK_POINTER_SIZE +
04085 total_bytes, &data_chunk_table[ node.number_of_data_chunks ].start,
04086 error_return ) ;
04087 CHECK_ADF_ABORT( *error_return ) ;
04088
04089 data_chunk_table[ node.number_of_data_chunks ].end.block =
04090 data_chunk_table[ node.number_of_data_chunks ].start.block ;
04091 data_chunk_table[ node.number_of_data_chunks ].end.offset =
04092 data_chunk_table[ node.number_of_data_chunks ].start.offset +
04093 TAG_SIZE + DISK_POINTER_SIZE + total_bytes ;
04094 ADFI_adjust_disk_pointer(
04095 &data_chunk_table[ node.number_of_data_chunks ].end, error_return ) ;
04096 CHECK_ADF_ABORT( *error_return ) ;
04097
04099 ADFI_file_malloc( file_index, 2 * TAG_SIZE +
04100 (2 * (node.number_of_data_chunks + 1) + 1) * DISK_POINTER_SIZE,
04101 &dct_block_offset, error_return ) ;
04102 CHECK_ADF_ABORT( *error_return ) ;
04103
04104 ADFI_write_data_chunk_table( file_index, &dct_block_offset,
04105 node.number_of_data_chunks+1, data_chunk_table, error_return ) ;
04106 CHECK_ADF_ABORT( *error_return ) ;
04107
04109 ADFI_write_data_chunk( file_index,
04110 &data_chunk_table[node.number_of_data_chunks ].start,
04111 tokenized_data_type, file_bytes, total_bytes, 0,
04112 total_bytes, 0L, error_return ) ;
04113 CHECK_ADF_ABORT( *error_return ) ;
04115 ADFI_file_free( file_index, &node.data_chunks, 0, error_return ) ;
04116 CHECK_ADF_ABORT( *error_return ) ;
04117
04120 node.number_of_data_chunks++ ;
04121 node.data_chunks.block = dct_block_offset.block ;
04122 node.data_chunks.offset = dct_block_offset.offset ;
04123 ADFI_write_node_header( file_index, &block_offset, &node,
04124 error_return ) ;
04125 CHECK_ADF_ABORT( *error_return ) ;
04126 }
04127 }
04128
04130 if( node.number_of_data_chunks == 1 ) {
04132 block_offset.block = node.data_chunks.block ;
04133 block_offset.offset = node.data_chunks.offset + TAG_SIZE +
04134 DISK_POINTER_SIZE + disk_offset * file_bytes ;
04135 ADFI_adjust_disk_pointer( &block_offset, error_return ) ;
04136 CHECK_ADF_ABORT( *error_return ) ;
04137
04139 for( i=0; i<(int)node.number_of_dimensions; i++ )
04140 current_disk[i] = s_start[i] ;
04141 for( i=0; i<m_num_dims; i++ )
04142 current_memory[i] = m_start[i] ;
04143
04145 if( memory_offset != 0 )
04146 data += memory_offset * memory_bytes ;
04147
04148 for( i=0; i<total_disk_elements; i++ ) {
04150 if ( block_offset.offset > DISK_BLOCK_SIZE ) {
04151 ADFI_adjust_disk_pointer( &block_offset, error_return ) ;
04152 CHECK_ADF_ABORT( *error_return ) ;
04153 }
04154
04158 if( formats_compare ) {
04159 ADFI_write_file( file_index, block_offset.block, block_offset.offset,
04160 file_bytes, (char *)data, error_return ) ;
04161 CHECK_ADF_ABORT( *error_return ) ;
04162 }
04163 else {
04164 ADFI_write_data_translated( file_index, block_offset.block,
04165 block_offset.offset, tokenized_data_type, file_bytes,
04166 file_bytes, (char *)data, error_return ) ;
04167 CHECK_ADF_ABORT( *error_return ) ;
04168 }
04169
04174 if( i < total_disk_elements - 1 ) {
04175 if ( node.number_of_dimensions == 1 ) {
04176 disk_offset = s_stride[0];
04177 current_disk[0] += disk_offset;
04178 if ( current_disk[0] > s_end[0] ) current_disk[0] = s_end[0] ;
04179 }
04180 else {
04181 ADFI_increment_array(
04182 node.number_of_dimensions, node.dimension_values,
04183 s_start, s_end, s_stride, current_disk, &disk_offset,
04184 error_return ) ;
04185 CHECK_ADF_ABORT( *error_return ) ;
04186 }
04187
04188 if ( m_num_dims == 1 ) {
04189 memory_offset = m_stride[0];
04190 current_memory[0] += disk_offset;
04191 if ( current_memory[0] > m_end[0] ) current_memory[0] = m_end[0] ;
04192 }
04193 else {
04194 ADFI_increment_array(
04195 (unsigned int)m_num_dims, (unsigned int* )m_dims,
04196 m_start, m_end, m_stride,
04197 current_memory, &memory_offset, error_return ) ;
04198 CHECK_ADF_ABORT( *error_return ) ;
04199 }
04200
04201 block_offset.offset += disk_offset * file_bytes ;
04202 if ( block_offset.offset > DISK_BLOCK_SIZE ) {
04203 ADFI_adjust_disk_pointer( &block_offset, error_return ) ;
04204 CHECK_ADF_ABORT( *error_return ) ;
04205 }
04206
04208 data += memory_offset * memory_bytes ;
04209 }
04210 }
04211 }
04212 else {
04214 current_chunk = 0 ;
04215 past_chunk_sizes = 0 ;
04216 relative_offset = disk_offset * file_bytes ;
04217 current_chunk_size = (data_chunk_table[ current_chunk ].end.block -
04218 data_chunk_table[ current_chunk ].start.block) * DISK_BLOCK_SIZE +
04219 (data_chunk_table[ current_chunk ].end.offset -
04220 data_chunk_table[ current_chunk ].start.offset) -
04221 (TAG_SIZE + DISK_POINTER_SIZE) ;
04222
04224 for( i=0; i<(int)node.number_of_dimensions; i++ )
04225 current_disk[i] = s_start[i] ;
04226 for( i=0; i<m_num_dims; i++ )
04227 current_memory[i] = m_start[i] ;
04228
04230 if( memory_offset != 0 )
04231 data += memory_offset * memory_bytes ;
04232
04233 for( i=0; i<total_disk_elements; i++ ) {
04234 while( relative_offset >= past_chunk_sizes + current_chunk_size ) {
04235 if( ++current_chunk >= node.number_of_data_chunks ) {
04236 *error_return = INCOMPLETE_DATA ;
04237 CHECK_ADF_ABORT( *error_return ) ;
04238 }
04239 else {
04240 past_chunk_sizes += current_chunk_size ;
04241 current_chunk_size = (data_chunk_table[ current_chunk ].end.block -
04242 data_chunk_table[ current_chunk ].start.block) * DISK_BLOCK_SIZE +
04243 (data_chunk_table[ current_chunk ].end.offset -
04244 data_chunk_table[ current_chunk ].start.offset) -
04245 (TAG_SIZE + DISK_POINTER_SIZE) ;
04246 }
04247 }
04248
04250 relative_block.block = data_chunk_table[ current_chunk ].start.block ;
04251 relative_block.offset = data_chunk_table[ current_chunk ].start.offset +
04252 (TAG_SIZE + DISK_POINTER_SIZE) +
04253 (relative_offset - past_chunk_sizes) ;
04254 if ( relative_block.offset > DISK_BLOCK_SIZE ) {
04255 ADFI_adjust_disk_pointer( &relative_block, error_return ) ;
04256 CHECK_ADF_ABORT( *error_return ) ;
04257 }
04258
04260 if( formats_compare ) {
04261 ADFI_write_file( file_index,
04262 relative_block.block, relative_block.offset,
04263 file_bytes, (char *)data, error_return ) ;
04264 CHECK_ADF_ABORT( *error_return ) ;
04265 }
04266 else {
04267 ADFI_write_data_translated( file_index, relative_block.block,
04268 relative_block.offset, tokenized_data_type, file_bytes,
04269 file_bytes, (char *)data, error_return ) ;
04270 CHECK_ADF_ABORT( *error_return ) ;
04271 }
04272
04274 if( i < total_disk_elements - 1 ) {
04275 if ( node.number_of_dimensions == 1 ) {
04276 disk_offset = s_stride[0];
04277 current_disk[0] += disk_offset;
04278 if ( current_disk[0] > s_end[0] ) current_disk[0] = s_end[0] ;
04279 }
04280 else {
04281 ADFI_increment_array(
04282 node.number_of_dimensions, node.dimension_values,
04283 s_start, s_end, s_stride, current_disk, &disk_offset,
04284 error_return ) ;
04285 CHECK_ADF_ABORT( *error_return ) ;
04286 }
04287
04288 relative_offset += disk_offset * file_bytes ;
04289
04290 if ( m_num_dims == 1 ) {
04291 memory_offset = m_stride[0];
04292 current_memory[0] += disk_offset;
04293 if ( current_memory[0] > m_end[0] ) current_memory[0] = m_end[0] ;
04294 }
04295 else {
04296 ADFI_increment_array(
04297 (unsigned int)m_num_dims, (unsigned int* )m_dims,
04298 m_start, m_end, m_stride,
04299 current_memory, &memory_offset, error_return ) ;
04300 CHECK_ADF_ABORT( *error_return ) ;
04301 }
04302
04304 data += memory_offset * memory_bytes ;
04305 }
04306 }
04307 }
04308
04309 if( data_chunk_table != 0L )
04310 free( data_chunk_table ) ;
04311
04313 ADFI_write_modification_date( file_index, error_return ) ;
04314 CHECK_ADF_ABORT( *error_return ) ;
04315
04316 }
04317
04318