00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifdef _MSC_VER
00014 # pragma warning(disable:4786) // >255 characters in debug information
00015 #endif
00016
00017 #include <iostream>
00018 #include <cstdlib>
00019
00020 #include "SIO_block.h"
00021 #include "SIO_blockManager.h"
00022 #include "SIO_definitions.h"
00023 #include "SIO_functions.h"
00024 #include "SIO_record.h"
00025 #include "SIO_stream.h"
00026
00027 static unsigned int
00028 SIO_mark_block = 0xdeadbeef;
00029
00030
00031
00032
00033 SIO_record::SIO_record
00034 (
00035 const char* i_name,
00036 SIO_verbosity i_verbosity
00037 )
00038 {
00039 options = 0;
00040 name = i_name;
00041 unpack = false;
00042 verbosity = i_verbosity;
00043 }
00044
00045
00046
00047
00048 SIO_record::~SIO_record() {}
00049
00050
00051
00052
00053 unsigned int SIO_record::connect
00054 (
00055 const char* i_name
00056 )
00057 {
00058
00059
00060
00061
00062 SIO_block
00063 *block;
00064
00065 std::string
00066 s_name = i_name;
00067
00068
00069
00070
00071 block = SIO_blockManager::get( i_name );
00072 if( block == NULL )
00073 {
00074 if( verbosity >= SIO_ERRORS )
00075 {
00076 std::cout << "SIO: [/" << name << "/" << i_name << "] "
00077 << "Block not connected (name not recognized)"
00078 << std::endl;
00079 }
00080 return( SIO_RECORD_BADARGUMENT );
00081 }
00082
00083
00084
00085
00086 return( connect( &s_name, block ) );
00087 }
00088
00089
00090
00091
00092 unsigned int SIO_record::connect
00093 (
00094 SIO_block* block
00095 )
00096 {
00097
00098
00099
00100
00101 std::string
00102 s_name;
00103
00104
00105
00106
00107 if( block == NULL )
00108 {
00109 if( verbosity >= SIO_ERRORS )
00110 {
00111 std::cout << "SIO: [/" << name << "/] "
00112 << "SIO: Block not connected (pointer is NULL)"
00113 << std::endl;
00114 }
00115 return( SIO_RECORD_BADARGUMENT );
00116 }
00117 s_name = *(block->getName());
00118
00119
00120
00121
00122 return( connect( &s_name, block ) );
00123 }
00124
00125
00126
00127
00128 unsigned int SIO_record::connect
00129 (
00130 std::string* s_name,
00131 SIO_block* block
00132 )
00133 {
00134
00135
00136
00137
00138 std::pair< connectMap_i, bool >
00139 status;
00140
00141
00142
00143
00144 std::pair< std::string const, SIO_block* >
00145 entry( *s_name, block );
00146
00147
00148
00149
00150
00151 status = connectMap.insert( entry );
00152 if( status.second )
00153 {
00154 if( verbosity >= SIO_ALL )
00155 {
00156 std::cout << "SIO: [/" << name << "/" << entry.first << "] "
00157 << "Connected"
00158 << std::endl;
00159 }
00160 }
00161 else
00162 {
00163
00164
00165 status.first->second = block ;
00166
00167 if( verbosity >= SIO_ALL )
00168 {
00169 std::cout << "SIO: [/" << name << "/" << entry.first << "] "
00170 << "connected new handler "
00171 << std::endl;
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 }
00183
00184
00185
00186
00187 return( SIO_RECORD_SUCCESS );
00188 }
00189
00190
00191
00192
00193
00194 unsigned int SIO_record::disconnectAll() {
00195
00196 connectMap_i iter;
00197
00198 if( verbosity >= SIO_ALL ) {
00199 for( iter = connectMap.begin() ; iter != connectMap.end() ; ++iter) {
00200
00201 std::cout << "SIO: [/" << name << "/" << iter->first << "] "
00202 << *(iter->second->getName())
00203 << " Disconnected"
00204 << std::endl;
00205 }
00206 }
00207 connectMap.erase(connectMap.begin(), connectMap.end());
00208
00209 return( SIO_RECORD_SUCCESS );
00210 }
00211
00212
00213
00214 unsigned int SIO_record::disconnect
00215 (
00216 const char* i_name
00217 )
00218 {
00219
00220
00221
00222
00223 SIO_block
00224 *block;
00225
00226 std::string
00227 s_name = i_name;
00228
00229
00230
00231
00232 block = SIO_blockManager::get( i_name );
00233 if( block == NULL )
00234 {
00235 if( verbosity >= SIO_ERRORS )
00236 {
00237 std::cout << "SIO: [/" << name << "/" << i_name << "] "
00238 << "Not disconnected (block name not recognized)"
00239 << std::endl;
00240 }
00241 return( SIO_RECORD_BADARGUMENT );
00242 }
00243
00244
00245
00246
00247 return( disconnect( &s_name, block ) );
00248 }
00249
00250
00251
00252
00253 unsigned int SIO_record::disconnect
00254 (
00255 SIO_block* block
00256 )
00257 {
00258
00259
00260
00261
00262 std::string
00263 s_name;
00264
00265
00266
00267
00268 if( block == NULL )
00269 {
00270 if( verbosity >= SIO_ERRORS )
00271 {
00272 std::cout << "SIO: [/" << name << "/] "
00273 << "Not disconnected (pointer is NULL)"
00274 << std::endl;
00275 }
00276 return( SIO_RECORD_BADARGUMENT );
00277 }
00278 s_name = *(block->getName());
00279
00280
00281
00282
00283 return( disconnect( &s_name, block ) );
00284 }
00285
00286
00287
00288
00289 unsigned int SIO_record::disconnect
00290 (
00291 std::string* s_name,
00292 SIO_block* block
00293 )
00294 {
00295
00296
00297
00298
00299 connectMap_i
00300 iter;
00301
00302
00303
00304
00305 if( (iter = connectMap.find( *s_name )) == connectMap.end() )
00306 {
00307 if( verbosity >= SIO_ERRORS )
00308 {
00309 std::cout << "SIO: [/" << name << "/" << *s_name << "] "
00310 << "Not disconnected (block is not connected)"
00311 << std::endl;
00312 }
00313 return( SIO_RECORD_NOTCONNECTED );
00314 }
00315
00316
00317
00318
00319 connectMap.erase( iter );
00320
00321 if( verbosity >= SIO_ALL )
00322 {
00323 std::cout << "SIO: [/" << name << "/" << *s_name << "] "
00324 << "Disconnected"
00325 << std::endl;
00326 }
00327
00328
00329
00330
00331 return( SIO_RECORD_SUCCESS );
00332 }
00333
00334
00335
00336
00337 SIO_block* SIO_record::getConnect
00338 (
00339 const char* i_name
00340 )
00341 {
00342
00343
00344
00345
00346 connectMap_i
00347 iter;
00348
00349 std::string
00350 s_name = i_name;
00351
00352
00353
00354
00355 if( (iter = connectMap.find( s_name )) == connectMap.end() )
00356 {
00357 if( verbosity >= SIO_ERRORS )
00358 {
00359 std::cout << "SIO: [/" << name << "/" << i_name << "] "
00360 << "Block is not connected"
00361 << std::endl;
00362 }
00363 return( NULL );
00364 }
00365
00366 if( verbosity >= SIO_ALL )
00367 {
00368 std::cout << "SIO: [/" << name << "/" << i_name << "] "
00369 << "Block is connected"
00370 << std::endl;
00371 }
00372
00373
00374
00375
00376 return( iter->second );
00377 }
00378
00379
00380
00381
00382 bool SIO_record::getCompress()
00383 {
00384 if( (options & SIO_OPT_COMPRESS) != 0 )
00385 return( true );
00386
00387 return( false );
00388 }
00389
00390
00391
00392
00393 std::string* SIO_record::getName() { return( &name ); }
00394
00395
00396
00397
00398 unsigned int SIO_record::getOptions() { return( options ); }
00399
00400
00401
00402
00403 bool SIO_record::getUnpack() { return( unpack ); }
00404
00405
00406
00407
00408 SIO_verbosity SIO_record::getVerbosity() { return( verbosity ); }
00409
00410
00411
00412
00413 unsigned int SIO_record::read
00414 (
00415 SIO_stream* stream,
00416 unsigned int i_options
00417 )
00418 {
00419
00420
00421
00422
00423 SIO_block
00424 *block;
00425
00426 pointedAtMap_i
00427 pati;
00428
00429 pointerToMap_i
00430 ptoh,
00431 ptoi,
00432 ptol;
00433
00434 SIO_POINTER_DECL
00435 *pointer;
00436
00437 unsigned int
00438 buflen,
00439 buftyp,
00440 status,
00441 tmplen,
00442 version;
00443
00444 char
00445 *tmploc;
00446
00447
00448
00449
00450 options = i_options;
00451
00452
00453
00454
00455 while( stream->buffer < stream->recmax )
00456 {
00457
00458
00459
00460
00461
00462 stream->blkmax = stream->recmax;
00463
00464
00465
00466
00467
00468 SIO_DATA( stream, &buflen, 1 );
00469 SIO_DATA( stream, &buftyp, 1 );
00470 if( buftyp != SIO_mark_block )
00471 {
00472 if( verbosity >= SIO_ERRORS )
00473 {
00474 std::cout << "SIO: [" << stream->name << "/" << name << "/] "
00475 << "Expected block marker not found"
00476 << std::endl;
00477 }
00478 return( SIO_RECORD_NOBLKMARKER );
00479 }
00480 stream->blkmax = stream->buffer + buflen - 8;
00481
00482
00483
00484
00485 SIO_DATA( stream, &version, 1 );
00486
00487
00488
00489
00490 SIO_DATA( stream, &tmplen, 1 );
00491
00492 tmploc = static_cast<char *>(malloc( tmplen + 1 ));
00493 if( tmploc == NULL )
00494 {
00495 if( verbosity >= SIO_ERRORS )
00496 {
00497 std::cout << "SIO: [" << stream->name << "/" << name << "/] "
00498 << "Buffer allocation failed"
00499 << std::endl;
00500 }
00501 return( SIO_STREAM_NOALLOC );
00502 }
00503
00504 SIO_DATA( stream, tmploc, tmplen );
00505 tmploc[tmplen] = '\0';
00506 block = SIO_blockManager::get( tmploc );
00507 stream->blk_name = tmploc;
00508 free( tmploc );
00509
00510
00511
00512
00513 if( block != NULL )
00514 {
00515 status = block->xfer( stream, SIO_OP_READ, version );
00516 if( !(status & 1) )
00517 return( status );
00518 }
00519
00520 else
00521 stream->buffer = stream->blkmax;
00522 }
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 ptol = stream->pointerTo->begin();
00535 while( ptol != stream->pointerTo->end() )
00536 {
00537 ptoh = stream->pointerTo->upper_bound( ptol->first );
00538 pati = stream->pointedAt->find( ptol->first );
00539
00540 if( pati != stream->pointedAt->end() )
00541 {
00542 for( ptoi = ptol; ptoi != ptoh; ptoi++ )
00543 {
00544 pointer = static_cast <SIO_POINTER_DECL *>(ptoi->second);
00545 *pointer = reinterpret_cast<SIO_POINTER_DECL >(pati->second);
00546 }
00547 }
00548 ptol = ptoh;
00549 }
00550
00551
00552
00553
00554 return( SIO_RECORD_SUCCESS );
00555 }
00556
00557
00558
00559
00560 bool SIO_record::setCompress
00561 (
00562 bool compress
00563 )
00564 {
00565 unsigned int
00566 o_options = (options & SIO_OPT_COMPRESS);
00567
00568 options &= ~SIO_OPT_COMPRESS;
00569 if( compress ) options |= SIO_OPT_COMPRESS;
00570
00571 if( o_options != 0 )
00572 return( true );
00573
00574 return( false );
00575 }
00576
00577
00578
00579
00580 bool SIO_record::setUnpack
00581 (
00582 bool i_unpack
00583 )
00584 {
00585 bool o_unpack = unpack;
00586 unpack = i_unpack;
00587
00588 if( verbosity >= SIO_ERRORS ){
00589 std::cout << "SIO: [/" << name << "] "
00590 << " setting unpack from " << o_unpack << " to " << unpack << std::endl ;
00591 }
00592
00593 return( o_unpack );
00594 }
00595
00596
00597
00598
00599 SIO_verbosity SIO_record::setVerbosity
00600 (
00601 SIO_verbosity i_verb
00602 )
00603 { SIO_verbosity o_verb = verbosity; verbosity = i_verb; return( o_verb ); }
00604
00605
00606
00607
00608 unsigned int SIO_record::write
00609 (
00610 SIO_stream* stream
00611 )
00612 {
00613
00614
00615
00616
00617 pointedAtMap_i
00618 pati;
00619
00620 pointerToMap_i
00621 ptoh,
00622 ptoi,
00623 ptol;
00624
00625
00626 connectMap_i
00627 iter;
00628
00629 unsigned int
00630 blkver,
00631 buflen,
00632 match,
00633 namlen,
00634 status;
00635
00636 unsigned char
00637 *pointer;
00638
00639 const char
00640 *nampnt;
00641
00642
00643
00644
00645 for( iter = connectMap.begin(); iter != connectMap.end(); iter++ )
00646 {
00647
00648
00649
00650
00651
00652
00653 stream->blkmax = stream->buffer;
00654
00655
00656
00657
00658
00659
00660
00661
00662 SIO_DATA( stream, &SIO_mark_block, 1 );
00663 SIO_DATA( stream, &SIO_mark_block, 1 );
00664
00665 blkver = iter->second->version();
00666 SIO_DATA( stream, &blkver, 1 );
00667
00668 namlen = iter->first.size();
00669 nampnt = iter->first.c_str();
00670
00671 SIO_DATA( stream, &namlen, 1 );
00672 SIO_DATA( stream, const_cast<char *>(nampnt), namlen );
00673
00674
00675
00676
00677 status = iter->second->xfer( stream, SIO_OP_WRITE, blkver );
00678 if( status != SIO_BLOCK_SUCCESS )
00679 {
00680 if( verbosity >= SIO_ERRORS )
00681 {
00682 std::cout << "SIO: ["
00683 << stream->name << "/"
00684 << name << "/"
00685 << iter->first << "] "
00686 << "Write error"
00687 << std::endl;
00688 }
00689 return( status );
00690 }
00691
00692
00693
00694
00695 buflen = stream->buffer - stream->blkmax;
00696 SIO_functions::copy( UCHR_CAST(&buflen),
00697 stream->blkmax, SIO_LEN_QB, 1 );
00698 }
00699
00700
00701
00702
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 match = 0x00000001;
00733 ptol = stream->pointerTo->begin();
00734 while( ptol != stream->pointerTo->end() )
00735 {
00736 ptoh = stream->pointerTo->upper_bound( ptol->first );
00737 pati = stream->pointedAt->find( ptol->first );
00738
00739 if( pati != stream->pointedAt->end() )
00740 {
00741 pointer = stream->bufloc +
00742 reinterpret_cast<SIO_POINTER_DECL>(pati->second);
00743
00744 SIO_functions::copy( UCHR_CAST( &match ), pointer, SIO_LEN_QB, 1 );
00745
00746 for( ptoi = ptol; ptoi != ptoh; ptoi++ )
00747 {
00748 pointer = stream->bufloc +
00749 reinterpret_cast<SIO_POINTER_DECL>(ptoi->second);
00750
00751 SIO_functions::copy( UCHR_CAST( &match ), pointer, SIO_LEN_QB, 1 );
00752 }
00753 }
00754
00755 match++;
00756 ptol = ptoh;
00757 }
00758
00759
00760
00761
00762 return( SIO_RECORD_SUCCESS );
00763 }