core/vsl/vsl_binary_io.cxx

Go to the documentation of this file.
00001 // This is core/vsl/vsl_binary_io.cxx
00002 #include "vsl_binary_io.h"
00003 //:
00004 // \file
00005 // \brief Functions to perform consistent binary IO within vsl
00006 // \author Tim Cootes and Ian Scott
00007 
00008 #include <vcl_cstddef.h>
00009 #include <vcl_cassert.h>
00010 #include <vcl_map.txx>
00011 #include <vcl_cstdlib.h> // abort()
00012 #include <vsl/vsl_binary_explicit_io.h>
00013 
00014 void vsl_b_write(vsl_b_ostream& os, char n )
00015 {
00016   os.os().write( ( char* )&n, sizeof( n ) );
00017 }
00018 
00019 void vsl_b_read(vsl_b_istream &is, char& n )
00020 {
00021   is.is().read( ( char* )&n, sizeof( n ) );
00022 }
00023 
00024 void vsl_b_write(vsl_b_ostream& os, signed char n )
00025 {
00026   os.os().write( ( char* )&n, sizeof( n ) );
00027 }
00028 
00029 void vsl_b_read(vsl_b_istream &is, signed char& n )
00030 {
00031   is.is().read( ( char* )&n, sizeof( n ) );
00032 }
00033 
00034 
00035 void vsl_b_write(vsl_b_ostream& os,unsigned char n )
00036 {
00037   os.os().write( ( char* )&n, 1 );
00038 }
00039 
00040 void vsl_b_read(vsl_b_istream &is,unsigned char& n )
00041 {
00042   is.is().read( ( char* )&n, 1 );
00043 }
00044 
00045 
00046 void vsl_b_write(vsl_b_ostream& os, const vcl_string& str )
00047 {
00048     vcl_string::const_iterator          it;
00049 
00050     vsl_b_write(os,(short)str.length());
00051     for ( it = str.begin(); it != str.end(); ++it )
00052         vsl_b_write(os,*it);
00053 }
00054 
00055 void vsl_b_read(vsl_b_istream &is, vcl_string& str )
00056 {
00057     vcl_string::iterator                it;
00058     vcl_string::size_type               length;
00059 
00060     vsl_b_read(is,length);
00061     str.resize( length );
00062     for ( it = str.begin(); it != str.end(); ++it )
00063         vsl_b_read(is,*it);
00064 }
00065 
00066 
00067 void vsl_b_write(vsl_b_ostream& os,const char *s )
00068 {
00069   int i = -1;
00070   do {
00071      i++;
00072      vsl_b_write(os,s[i]);
00073   } while ( s[i] != 0 );
00074 }
00075 
00076 void vsl_b_read(vsl_b_istream &is,char *s )
00077 {
00078   int i = -1;
00079   do {
00080     i++;
00081     vsl_b_read(is,s[i]);
00082   } while ( s[i] != 0 );
00083 }
00084 
00085 
00086 void vsl_b_write(vsl_b_ostream& os,bool b)
00087 {
00088   if (b)
00089     vsl_b_write(os, (signed char) -1);
00090   else
00091     vsl_b_write(os, (signed char) 0);
00092 }
00093 
00094 void vsl_b_read(vsl_b_istream &is,bool& b)
00095 {
00096   signed char c;
00097   vsl_b_read(is, c);
00098   b = (c != 0);
00099 }
00100 
00101 
00102 void vsl_b_write(vsl_b_ostream& os,int n )
00103 {
00104   unsigned char buf[ VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(int)) ];
00105   unsigned long nbytes = vsl_convert_to_arbitrary_length(&n, buf);
00106   os.os().write((char*)buf, nbytes );
00107 }
00108 
00109 void vsl_b_read(vsl_b_istream &is,int& n )
00110 {
00111   unsigned char buf[VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(int))];
00112   unsigned char *ptr=buf;
00113   do
00114   {
00115     vsl_b_read(is, *ptr);
00116     if (ptr-buf >= (vcl_ptrdiff_t)VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(int)))
00117     {
00118       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream &, int& )\n"
00119                << "           Integer too big. Likely cause either file corruption, or\n"
00120                << "           file was created on platform with larger integer sizes.\n";
00121       is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00122       return;
00123     }
00124   }
00125   while (!(*(ptr++) & 128));
00126   vsl_convert_from_arbitrary_length(buf, &n);
00127 }
00128 
00129 
00130 void vsl_b_write(vsl_b_ostream& os,unsigned int n )
00131 {
00132   unsigned char
00133     buf[VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned int))];
00134   unsigned long nbytes = vsl_convert_to_arbitrary_length(&n, buf);
00135   os.os().write((char*)buf, nbytes );
00136 }
00137 
00138 void vsl_b_read(vsl_b_istream &is,unsigned int& n )
00139 {
00140   unsigned char buf[
00141     VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned int))];
00142   unsigned char *ptr=buf;
00143   do
00144   {
00145     vsl_b_read(is, *ptr);
00146     if (ptr-buf >= (vcl_ptrdiff_t)VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned int)))
00147     {
00148       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream &, unsigned int& )\n"
00149                << "           Integer too big. Likely cause either file corruption, or\n"
00150                << "           file was created on platform with larger integer sizes.\n";
00151       is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00152       return;
00153     }
00154   }
00155   while (!(*(ptr++) & 128));
00156   vsl_convert_from_arbitrary_length(buf, &n);
00157 }
00158 
00159 
00160 void vsl_b_write(vsl_b_ostream& os,short n )
00161 {
00162   unsigned char buf[VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(short))];
00163   unsigned long nbytes = vsl_convert_to_arbitrary_length(&n, buf);
00164   os.os().write((char*)buf, nbytes );
00165 }
00166 
00167 void vsl_b_read(vsl_b_istream &is,short& n )
00168 {
00169   unsigned char buf[VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(short))];
00170   unsigned char *ptr=buf;
00171   do
00172   {
00173     vsl_b_read(is, *ptr);
00174 
00175     if (ptr-buf >= (vcl_ptrdiff_t)VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(short)))
00176     {
00177       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream &, short& )\n"
00178                << "           Integer too big. Likely cause either file corruption, or\n"
00179                << "           file was created on platform with larger integer sizes.\n";
00180       is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00181       return;
00182     }
00183   }
00184   while (!(*(ptr++) & 128));
00185   vsl_convert_from_arbitrary_length(buf, &n);
00186 }
00187 
00188 void vsl_b_write(vsl_b_ostream& os, unsigned short n )
00189 {
00190   unsigned char buf[
00191     VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned short))];
00192   unsigned long nbytes = vsl_convert_to_arbitrary_length(&n, buf);
00193   os.os().write((char*)buf, nbytes );
00194 }
00195 
00196 void vsl_b_read(vsl_b_istream &is, unsigned short& n )
00197 {
00198   unsigned char buf[
00199     VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned short))];
00200   unsigned char *ptr=buf;
00201   do
00202   {
00203     vsl_b_read(is, *ptr);
00204     if (ptr-buf >= (vcl_ptrdiff_t)VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned short)))
00205     {
00206       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream &, unsigned short& )\n"
00207                << "           Integer too big. Likely cause either file corruption, or\n"
00208                << "           file was created on platform with larger integer sizes.\n";
00209       is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00210       return;
00211     }
00212   }
00213   while (!(*(ptr++) & 128));
00214   vsl_convert_from_arbitrary_length(buf, &n);
00215 }
00216 
00217 
00218 void vsl_b_write(vsl_b_ostream& os,long n )
00219 {
00220   unsigned char buf[VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(long))];
00221   unsigned long nbytes = vsl_convert_to_arbitrary_length(&n, buf);
00222   os.os().write((char*)buf, nbytes );
00223 }
00224 
00225 void vsl_b_read(vsl_b_istream &is,long& n )
00226 {
00227   unsigned char buf[VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(long))];
00228   unsigned char *ptr=buf;
00229   do
00230   {
00231     vsl_b_read(is, *ptr);
00232     if (ptr-buf >= (vcl_ptrdiff_t)VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(long)))
00233     {
00234       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream &, long& )\n"
00235                << "           Integer too big. Likely cause either file corruption, or\n"
00236                << "           file was created on platform with larger integer sizes.\n";
00237       is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00238       return;
00239     }
00240   }
00241   while (!(*(ptr++) & 128));
00242   vsl_convert_from_arbitrary_length(buf, &n);
00243 }
00244 
00245 void vsl_b_write(vsl_b_ostream& os,unsigned long n )
00246 {
00247   unsigned char buf[
00248     VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned long))];
00249   unsigned long nbytes = vsl_convert_to_arbitrary_length(&n, buf);
00250   os.os().write((char*)buf, nbytes );
00251 }
00252 
00253 void vsl_b_read(vsl_b_istream &is,unsigned long& n )
00254 {
00255   unsigned char buf[
00256     VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned long))];
00257   unsigned char *ptr=buf;
00258   do
00259   {
00260     vsl_b_read(is, *ptr);
00261     if (ptr-buf >= (vcl_ptrdiff_t)VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned long)))
00262     {
00263       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream &, unsigned long& )\n"
00264                << "           Integer too big. Likely cause either file corruption, or\n"
00265                << "           file was created on platform with larger integer sizes.\n";
00266       is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00267       return;
00268     }
00269   }
00270   while (!(*(ptr++) & 128));
00271   vsl_convert_from_arbitrary_length(buf, &n);
00272 }
00273 
00274 #if VXL_HAS_INT_64 && !VXL_INT_64_IS_LONG
00275 
00276 void vsl_b_write(vsl_b_ostream& os, vxl_int_64 n )
00277 {
00278   unsigned char buf[VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vxl_int_64))];
00279   unsigned long nbytes = vsl_convert_to_arbitrary_length(&n, buf);
00280   os.os().write((char*)buf, nbytes );
00281 }
00282 
00283 void vsl_b_read(vsl_b_istream &is,vxl_int_64& n )
00284 {
00285   unsigned char buf[VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vxl_int_64))];
00286   unsigned char *ptr=buf;
00287   do
00288   {
00289     vsl_b_read(is, *ptr);
00290     if (ptr-buf >= (vcl_ptrdiff_t)VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vxl_int_64)))
00291     {
00292       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream &, vxl_int_64& )\n"
00293                << "           Integer too big. Likely cause either file corruption, or\n"
00294                << "           file was created on platform with larger integer sizes.\n";
00295       is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00296       return;
00297     }
00298   }
00299   while (!(*(ptr++) & 128));
00300   vsl_convert_from_arbitrary_length(buf, &n);
00301 }
00302 
00303 void vsl_b_write(vsl_b_ostream& os, vxl_uint_64 n )
00304 {
00305   unsigned char buf[
00306     VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vxl_uint_64))];
00307   unsigned long nbytes = vsl_convert_to_arbitrary_length(&n, buf);
00308   os.os().write((char*)buf, nbytes );
00309 }
00310 
00311 void vsl_b_read(vsl_b_istream &is,vxl_uint_64& n )
00312 {
00313   unsigned char buf[
00314     VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vxl_uint_64))];
00315   unsigned char *ptr=buf;
00316   do
00317   {
00318     vsl_b_read(is, *ptr);
00319     if (ptr-buf >= (vcl_ptrdiff_t)VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vxl_uint_64)))
00320     {
00321       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream &, vxl_uint_64& )\n"
00322                << "           Integer too big. Likely cause either file corruption, or\n"
00323                << "           file was created on platform with larger integer sizes.\n";
00324       is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00325       return;
00326     }
00327   }
00328   while (!(*(ptr++) & 128));
00329   vsl_convert_from_arbitrary_length(buf, &n);
00330 }
00331 
00332 #endif // VXL_HAS_INT_64
00333 
00334 #if 0
00335 // When the macro is ready, this test will be
00336 // #if ! VCL_PTRDIFF_T_IS_A_STANDARD_TYPE
00337 
00338 void vsl_b_write(vsl_b_ostream& os, vcl_ptrdiff_t n )
00339 {
00340   unsigned char buf[
00341     VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vcl_ptrdiff_t))];
00342   unsigned long nbytes = vsl_convert_to_arbitrary_length(&n, buf);
00343   os.os().write((char*)buf, nbytes );
00344 }
00345 
00346 void vsl_b_read(vsl_b_istream &is, vcl_ptrdiff_t& n )
00347 {
00348   unsigned char buf[
00349     VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vcl_ptrdiff_t))];
00350   unsigned char *ptr=buf;
00351   do
00352   {
00353     vsl_b_read(is, *ptr);
00354     if (ptr-buf >= (vcl_ptrdiff_t)VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vcl_ptrdiff_t)))
00355     {
00356       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream &, vcl_ptrdiff_t& )\n"
00357                << "           Integer too big. Likely cause either file corruption, or\n"
00358                << "           file was created on platform with larger integer sizes\n"
00359                << "           and represents a very large data structure.\n";
00360       is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00361       return;
00362     }
00363   }
00364   while (!(*(ptr++) & 128));
00365   vsl_convert_from_arbitrary_length(buf, &n);
00366 }
00367 #endif // 0
00368 
00369 #if 0
00370 // When the macro is ready, this test will be
00371 // #if ! VCL_SIZE_T_IS_A_STANDARD_TYPE
00372 
00373 void vsl_b_write(vsl_b_ostream& os, vcl_size_t n )
00374 {
00375   unsigned char buf[
00376     VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vcl_size_t))];
00377   unsigned long nbytes = vsl_convert_to_arbitrary_length(&n, buf);
00378   os.os().write((char*)buf, nbytes );
00379 }
00380 
00381 void vsl_b_read(vsl_b_istream &is, vcl_size_t& n )
00382 {
00383   unsigned char buf[
00384     VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vcl_size_t))];
00385   unsigned char *ptr=buf;
00386   do
00387   {
00388     vsl_b_read(is, *ptr);
00389     if (ptr-buf >= (vcl_ptrdiff_t)VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vcl_size_t)))
00390     {
00391       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream &, vcl_size_t& )\n"
00392                << "           Integer too big. Likely cause either file corruption, or\n"
00393                << "           file was created on platform with larger integer sizes\n"
00394                << "           and represents a very large data structure.\n";
00395       is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00396       return;
00397     }
00398   }
00399   while (!(*(ptr++) & 128));
00400   vsl_convert_from_arbitrary_length(buf, &n);
00401 }
00402 #endif // 0
00403 
00404 
00405 void vsl_b_write(vsl_b_ostream& os,float n )
00406 {
00407   vsl_swap_bytes(( char* )&n, sizeof( n ) );
00408   os.os().write( ( char* )&n, sizeof( n ) );
00409 }
00410 
00411 void vsl_b_read(vsl_b_istream &is,float& n )
00412 {
00413   is.is().read( ( char* )&n, sizeof( n ) );
00414   vsl_swap_bytes(( char* )&n, sizeof( n ) );
00415 }
00416 
00417 void vsl_b_write(vsl_b_ostream& os,double n )
00418 {
00419   vsl_swap_bytes(( char* )&n, sizeof( n ) );
00420   os.os().write( ( char* )&n, sizeof( n ) );
00421 }
00422 
00423 void vsl_b_read(vsl_b_istream &is,double& n )
00424 {
00425   is.is().read( ( char* )&n, sizeof( n ) );
00426   vsl_swap_bytes(( char* )&n, sizeof( n ) );
00427 }
00428 
00429 
00430 const unsigned short vsl_b_ostream::version_no_ = 1;
00431 const vcl_streamoff vsl_b_ostream::header_length = 6;
00432 static const unsigned short vsl_magic_number_part_1=0x2c4e;
00433 static const unsigned short vsl_magic_number_part_2=0x472b;
00434 
00435 
00436 //: Create this adaptor using an existing stream
00437 // The stream (os) must be open (i.e. ready to be written to) so that the
00438 // IO version number can be written by this constructor.
00439 // User is responsible for deleting os after deleting the adaptor
00440 vsl_b_ostream::vsl_b_ostream(vcl_ostream *os): os_(os)
00441 {
00442   assert(os_ != 0);
00443   vsl_b_write_uint_16(*this, version_no_);
00444   vsl_b_write_uint_16(*this, vsl_magic_number_part_1);
00445   vsl_b_write_uint_16(*this, vsl_magic_number_part_2);
00446 }
00447 
00448 //: A reference to the adaptor's stream
00449 vcl_ostream& vsl_b_ostream::os() const
00450 {
00451   assert(os_ != 0);
00452   return *os_;
00453 }
00454 
00455 //: Returns true if the underlying stream has its fail bit set.
00456 bool vsl_b_ostream::operator!() const
00457 {
00458   return os_->operator!();
00459 }
00460 
00461 
00462 //: Clear the stream's record of any serialisation operations
00463 // Calling this function while outputting serialisable things to stream,
00464 // will mean that a second copy of an object may get stored to the stream.
00465 void vsl_b_ostream::clear_serialisation_records()
00466 {
00467   serialisation_records_.clear();
00468 }
00469 
00470 
00471 //: Adds an object pointer to the serialisation records.
00472 // Returns a unique identifier for the object.
00473 //
00474 // \a pointer must be non-null, so you should handle null pointers separately.
00475 //
00476 // You can optionally add some user-defined integer with each record
00477 // If error checking is on, and the object pointer is null or already in the records,
00478 // this function will abort()
00479 unsigned long vsl_b_ostream::add_serialisation_record
00480                     (void *pointer, int other_data /*= 0*/)
00481 {
00482   assert(pointer != 0);
00483   assert(serialisation_records_.find(pointer) == serialisation_records_.end());
00484   unsigned long id = serialisation_records_.size() + 1;
00485   serialisation_records_[pointer] = vcl_make_pair(id, other_data);
00486   return id;
00487 }
00488 
00489 
00490 //: Returns a unique identifier for the object.
00491 // Returns 0 if there is no record of the object.
00492 unsigned long vsl_b_ostream::get_serial_number(void *pointer) const
00493 {
00494   serialisation_records_type::const_iterator entry =
00495     serialisation_records_.find(pointer);
00496   if (entry == serialisation_records_.end())
00497   {
00498     return 0;
00499   }
00500   else
00501   {
00502     return (*entry).second.first;
00503   }
00504 }
00505 
00506 //: Set the user-defined data associated with the object
00507 // If there is no record of the object, this function will return 0.
00508 // However a retval of 0 does not necessarily imply that the object is
00509 // unrecorded.
00510 int vsl_b_ostream::get_serialisation_other_data(void *pointer) const
00511 {
00512   serialisation_records_type::const_iterator entry =
00513     serialisation_records_.find(pointer);
00514   if (entry == serialisation_records_.end())
00515   {
00516     return 0;
00517   }
00518   else
00519   {
00520     return (*entry).second.second;
00521   }
00522 }
00523 
00524 //: Modify the user-defined data associated with the object.
00525 // If there is no record of the object, this function will abort.
00526 int vsl_b_ostream::set_serialisation_other_data
00527     (void *pointer, int /*other_data*/)
00528 {
00529   serialisation_records_type::iterator entry =
00530     serialisation_records_.find(pointer);
00531   if (entry == serialisation_records_.end())
00532   {
00533     vcl_cerr << "vsl_b_ostream::set_serialisation_other_data():\n"
00534              << "No such value " << pointer << "in records.\n";
00535     vcl_abort();
00536   }
00537   return (*entry).second.second;
00538 }
00539 
00540 
00541 //: destructor.
00542 vsl_b_ofstream::~vsl_b_ofstream()
00543 {
00544   if (os_) delete os_;
00545 }
00546 
00547 
00548 //: Close the stream
00549 void vsl_b_ofstream::close()
00550 {
00551   assert(os_ != 0);
00552   ((vcl_ofstream *)os_)->close();
00553   clear_serialisation_records();
00554 }
00555 
00556 //: Create this adaptor using an existing stream.
00557 // The stream (is) must be open (i.e. ready to be read from) so that the
00558 // IO version number can be read by this constructor.
00559 // User is responsible for deleting is after deleting the adaptor
00560 vsl_b_istream::vsl_b_istream(vcl_istream *is): is_(is)
00561 {
00562   assert(is_ != 0);
00563   if (!(*is_)) return;
00564   unsigned long v, m1, m2;
00565   vsl_b_read_uint_16(*this, v);
00566   vsl_b_read_uint_16(*this, m1);
00567   vsl_b_read_uint_16(*this, m2);
00568 
00569   // If this test fails, either the file is missing, or it is not a
00570   // Binary VXL file, or it is a corrupted Binary VXL file
00571   if (m2 != vsl_magic_number_part_2 || m1 != vsl_magic_number_part_1)
00572   {
00573     vcl_cerr << "\nI/O ERROR: vsl_b_istream::vsl_b_istream(vcl_istream *is)\n"
00574              <<   "           The input stream does not appear to be a binary VXL stream.\n"
00575              <<   "           Can't find correct magic number.\n";
00576     is_->clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00577   }
00578 
00579   if (v != 1)
00580   {
00581     vcl_cerr << "\nI/O ERROR: vsl_b_istream::vsl_b_istream(vcl_istream *is)\n"
00582              << "             The stream's leading version number is "
00583              << v << ". Expected value 1.\n";
00584     is_->clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00585   }
00586   version_no_ = (unsigned short)v;
00587 }
00588 
00589 //: A reference to the adaptor's stream
00590 vcl_istream & vsl_b_istream::is() const
00591 {
00592   assert(is_ != 0);
00593   return *is_;
00594 }
00595 
00596 
00597 //: Return the version number of the IO format of the file being read.
00598 unsigned short vsl_b_istream::version_no() const
00599 {
00600   return version_no_;
00601 }
00602 
00603 //: Returns true if the underlying stream has its fail bit set.
00604 bool vsl_b_istream::operator!() const
00605 {
00606   return is_->operator!();
00607 }
00608 
00609 //: Clear the stream's record of any serialisation operations
00610 // Calling this function while inputting serialisable things from a stream,
00611 // could cause errors during loading unless the records were cleared at a
00612 // similar point during output.
00613 void vsl_b_istream::clear_serialisation_records()
00614 {
00615   serialisation_records_.clear();
00616 }
00617 
00618 //: Adds record of object's unique serial number, and location in memory.
00619 // \a pointer must be non-null, so you should handle null pointers separately.
00620 //
00621 // Adding a null pointer or one that already exists will cause the function to abort(),
00622 // if debugging is turned on;
00623 //
00624 // You can also store a single integer as other data.
00625 // Interpretation of this data is entirely up to the client code.
00626 void vsl_b_istream::add_serialisation_record(unsigned long serial_number,
00627                                              void *pointer, int other_data /*= 0*/)
00628 {
00629   assert(pointer != 0);
00630   assert(serialisation_records_.find(serial_number) == serialisation_records_.end());
00631   serialisation_records_[serial_number] = vcl_make_pair(pointer, other_data);
00632 }
00633 
00634 //: Returns the pointer to the object identified by the unique serial number.
00635 // Returns 0 if no record has been added.
00636 void* vsl_b_istream::get_serialisation_pointer(unsigned long serial_number) const
00637 {
00638   serialisation_records_type::const_iterator entry =
00639         serialisation_records_.find(serial_number);
00640   if (entry == serialisation_records_.end())
00641   {
00642     return 0;
00643   }
00644   else
00645   {
00646     return (*entry).second.first;
00647   }
00648 }
00649 
00650 //: Returns the user defined data associated with the unique serial number
00651 // Returns 0 if no record has been added.
00652 int vsl_b_istream::get_serialisation_other_data
00653     (unsigned long serial_number) const
00654 {
00655   serialisation_records_type::const_iterator entry =
00656     serialisation_records_.find(serial_number);
00657   if (entry == serialisation_records_.end())
00658   {
00659     return 0;
00660   }
00661   else
00662   {
00663     return (*entry).second.second;
00664   }
00665 }
00666 
00667 //: Modify the user-defined data associated with the unique serial number
00668 // If there is no record of the object, this function will  abort.
00669 int vsl_b_istream::set_serialisation_other_data
00670     (unsigned long serial_number, int /*other_data*/)
00671 {
00672   serialisation_records_type::const_iterator entry =
00673     serialisation_records_.find(serial_number);
00674   if (entry == serialisation_records_.end())
00675   {
00676     vcl_cerr << "vsl_b_istream::set_serialisation_other_data():\n"
00677              << "  No such value " << serial_number << "in records.\n";
00678     vcl_abort();
00679   }
00680   return (*entry).second.second;
00681 }
00682 
00683 
00684 //: destructor.so that it can be overloaded
00685 vsl_b_ifstream::~vsl_b_ifstream()
00686 {
00687   if (is_) delete is_;
00688 }
00689 
00690 //: Close the stream
00691 void vsl_b_ifstream::close()
00692 {
00693   assert(is_ != 0);
00694   ((vcl_ifstream *)is_)->close();
00695   clear_serialisation_records();
00696 }

Generated on Tue Dec 2 05:06:05 2008 for core/vsl by  doxygen 1.5.1