core/vil/io/vil_io_smart_ptr.txx
Go to the documentation of this file.
00001 // This is core/vil/io/vil_io_smart_ptr.txx
00002 #ifndef vil_io_smart_ptr_txx_
00003 #define vil_io_smart_ptr_txx_
00004 //:
00005 // \file
00006 // \brief Serialised binary IO functions for vil_smart_ptr<T>
00007 // \author Tim Cootes/Ian Scott (Manchester)
00008 
00009 #include "vil_io_smart_ptr.h"
00010 #include <vsl/vsl_binary_io.h>
00011 #include <vil/vil_smart_ptr.h>
00012 
00013 //=========================================================================
00014 //: Binary save self to stream.
00015 template<class T>
00016 void vsl_b_write(vsl_b_ostream & os, const vil_smart_ptr<T> &p)
00017 {
00018   // write version number
00019   const short io_version_no = 2;
00020   vsl_b_write(os, io_version_no);
00021 
00022   if (p.ptr() == 0)  // Deal with Null pointers first.
00023   {
00024     vsl_b_write(os, true);
00025     vsl_b_write(os, 0ul); // Use 0 to indicate a null pointer.
00026                           // True serialisation IDs are always 1 or more.
00027     return;
00028   }
00029 
00030   // Get a serial_number for object being pointed to
00031   unsigned long id = os.get_serial_number(p.ptr());
00032   // Find out if this is the first time the object being pointed to is
00033   // being saved
00034   if (id == 0)
00035   {
00036     id = os.add_serialisation_record(p.ptr());
00037 
00038       // Say that this is the first time
00039       // that this object is being saved.
00040       // This isn't really necessary but
00041       // it is useful as an error check
00042     vsl_b_write(os, true);
00043     vsl_b_write(os, id);     // Save the serial number
00044 // If you get an error in the next line, it could be because your type T
00045 // has no vsl_b_write(vsl_b_ostream &,const T*)  defined on it.
00046 // See the documentation in the .h file to see how to add it.
00047     vsl_b_write(os, p.ptr());    // Only save the actual object if it
00048                                   //hasn't been saved before to this stream
00049   }
00050   else
00051   {
00052       // Say that this is not the first time
00053       // that this object is being saved.
00054       // This isn't really necessary but
00055       // it is useful as an error check
00056 
00057     vsl_b_write(os, false);
00058     vsl_b_write(os, id);         // Save the serial number
00059   }
00060 }
00061 
00062 //=====================================================================
00063 //: Binary load self from stream.
00064 template<class T>
00065 void vsl_b_read(vsl_b_istream &is, vil_smart_ptr<T> &p)
00066 {
00067   if (!is) return;
00068 
00069   short ver;
00070   vsl_b_read(is, ver);
00071   switch (ver)
00072   {
00073    case 1:
00074    case 2:
00075    {
00076     bool first_time; // true if the object is about to be loaded
00077     vsl_b_read(is, first_time);
00078 
00079     unsigned long id; // Unique serial number indentifying object
00080     vsl_b_read(is, id);
00081 
00082     if (id == 0) // Deal with Null pointers first.
00083     {
00084       p = 0;
00085       return;
00086     }
00087 
00088     T * pointer = static_cast<T *>( is.get_serialisation_pointer(id));
00089     if (first_time != (pointer == 0))
00090     {
00091       // This checks that the saving stream and reading stream
00092       // both agree on whether or not this is the first time they
00093       // have seen this object.
00094       vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, vil_smart_ptr<T>&)\n"
00095                << "           De-serialisation failure\n";
00096       is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00097       return;
00098     }
00099 
00100     if (pointer == 0)
00101     {
00102       // If you get an error in the next line, it could be because your type T
00103       // has no vsl_b_read(vsl_b_ostream&,T*&)  defined on it.
00104       // See the documentation in the .h file to see how to add it.
00105       vsl_b_read(is, pointer);
00106       is.add_serialisation_record(id, pointer);
00107     }
00108 
00109     p = pointer; // This operator method will set the internal
00110                  //pointer in vil_smart_ptr.
00111     break;
00112    }
00113    default:
00114     vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, vil_smart_ptr<T>&)\n"
00115              << "           Unknown version number "<< ver << '\n';
00116     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00117     return;
00118   }
00119 }
00120 
00121 //=====================================================================
00122 //: Output a human readable summary to the stream
00123 template<class T>
00124 void vsl_print_summary(vcl_ostream & os,const vil_smart_ptr<T> & p)
00125 {
00126   os << "Smart ptr to ";
00127   if (p.ptr())
00128   {
00129     // If you get an error in the next line, it could be because your type T
00130     // has no vsl_print_summary(vsl_b_ostream &, const T*)  defined on it.
00131     // See the documentation in the .h file to see how to add it.
00132     vsl_print_summary(os, (p.ptr()));
00133   }
00134   else
00135     os << "NULL";
00136 }
00137 
00138 
00139 #if 0 // commented out
00140 //===========================================
00141 // Deal with base class pointers
00142 template<class T>
00143 void vsl_b_read(vsl_b_istream& is, vil_smart_ptr<T> * &p)
00144 {
00145   delete p;
00146   bool not_null_ptr;
00147   vsl_b_read(is, not_null_ptr);
00148   if (not_null_ptr)
00149   {
00150     p = new vil_smart_ptr<T>;
00151     vsl_b_read(is, *p);
00152   }
00153   else
00154     p = 0;
00155 }
00156 
00157 template<class T>
00158 void vsl_b_write(vsl_b_ostream& os, const vil_smart_ptr<T> *p)
00159 {
00160   if (p==0)
00161   {
00162     vsl_b_write(os, false); // Indicate null pointer stored
00163   }
00164   else
00165   {
00166     vsl_b_write(os,true); // Indicate non-null pointer stored
00167     vsl_b_write(os,*p);
00168   }
00169 }
00170 
00171 template<class T>
00172 void vsl_print_summary(vcl_ostream, const vil_smart_ptr<T> *p)
00173 {
00174   if (p==0)
00175     os << "NULL PTR";
00176   else
00177   {
00178     os << "vil_smart_ptr: ";
00179     vsl_print_summary(*p);
00180   }
00181 }
00182 #endif
00183 
00184 #undef VIL_IO_SMART_PTR_INSTANTIATE
00185 #define VIL_IO_SMART_PTR_INSTANTIATE(T) \
00186 template void vsl_print_summary(vcl_ostream &, const vil_smart_ptr<T > &); \
00187 template void vsl_b_read(vsl_b_istream &, vil_smart_ptr<T > &); \
00188 template void vsl_b_write(vsl_b_ostream &, const vil_smart_ptr<T > &)
00189 
00190 #endif // vil_io_smart_ptr_txx_