core/vsl/vsl_binary_loader.txx
Go to the documentation of this file.
00001 // This is core/vsl/vsl_binary_loader.txx
00002 #ifndef vsl_binary_loader_txx_
00003 #define vsl_binary_loader_txx_
00004 //:
00005 // \file
00006 
00007 #include "vsl_binary_loader.h"
00008 #include <vcl_vector.txx>
00009 
00010 template<class BaseClass>
00011 vsl_binary_loader<BaseClass>& vsl_binary_loader<BaseClass>::instance()
00012 {
00013   if (instance_ == 0)
00014   {
00015     instance_ = new vsl_binary_loader<BaseClass>;
00016 
00017     // Register for deletion by vsl_delete_all_loaders()
00018     instance_->register_this();
00019   }
00020   return *instance_;
00021 }
00022 
00023 template<class BaseClass>
00024 void vsl_binary_loader<BaseClass>::make_empty()
00025 {
00026   for (unsigned int i=0; i<object_.size(); ++i)
00027     delete object_[i];
00028   object_.resize(0);
00029 }
00030 
00031 template<class BaseClass>
00032 vsl_binary_loader<BaseClass>::~vsl_binary_loader()
00033 {
00034   make_empty();
00035   instance_=0;
00036 }
00037 
00038 // IO for  pointers to BaseClass:
00039 template<class BaseClass>
00040 void vsl_binary_loader<BaseClass>::load_object( vsl_b_istream& is, BaseClass*& b)
00041 {
00042   if (!is) return;
00043 
00044   // HELP ON RUN-TIME ERROR HERE
00045   // If you get a run-time error here it is most-likely because you called
00046   // vsl_b_read with an uninitialised null base_class pointer. The base class
00047   // pointer should either point to a real object, or be set to 0 - IMS.
00048   delete b;   // Delete old object pointed to by b
00049 
00050   vcl_string name;
00051   vsl_b_read(is,name);
00052 
00053   if (name=="VSL_NULL_PTR")
00054   {
00055     // Zero pointer
00056     b=0;
00057     return;
00058   }
00059 
00060   unsigned int i = 0;
00061   while (i<object_.size() && !(object_[i]->is_a()==name)) ++i;
00062 
00063   if (i<object_.size())
00064   {
00065     b = object_[i]->clone(); // If you get a compile error here you are probably trying to load into a non-base class pointer.
00066     b->b_read(is);
00067   }
00068   else
00069   {
00070     vcl_cerr << "\n I/O ERROR: " << is_a() << "::load_object: "
00071              << "class name <" << name << "> not in list of loaders\n"
00072              << object_.size()<<" valid loaders:\n";
00073     for (unsigned int j=0; j<object_.size(); ++j)
00074       vcl_cerr << object_[j]->is_a() << vcl_endl;
00075     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00076     return;
00077   }
00078 }
00079 
00080 #ifdef VCL_SGI_CC
00081 // This specialisation is needed since otherwise the more general template
00082 // void vsl_b_write(vsl_b_ostream& bfs, const BaseClass* b)
00083 // would be used for const char*, which is not correct.
00084 // This specialisation must of course precede the more general definition.
00085 //
00086 // Note that this must be declared "inline", since this function is already
00087 // implemented (and exported) in vsl_binary_io.cxx; exporting it from here
00088 // as well would give linker errors (multiple definition of the same symbol).
00089 //
00090 // An alternative solution is a single inline definition in vsl_binary_io.h
00091 // This definition must be implemented identically to the one in
00092 // vsl_binary_io.h, otherwise there may be an I/O incompatibility.
00093 
00094 inline void vsl_b_write(vsl_b_ostream& bfs, const char* b)
00095 {
00096   int i = -1;
00097   do {
00098      i++;
00099      vsl_b_write(bfs,b[i]);
00100   } while ( b[i] != 0 );
00101 }
00102 #endif
00103 
00104 // For pointer to baseclass types, but *not* for char* !
00105 template<class BaseClass>
00106 void vsl_b_write(vsl_b_ostream& bfs, const BaseClass* b)
00107 {
00108   if (b)
00109   {
00110     vsl_b_write(bfs, b->is_a());
00111     b->b_write(bfs);
00112   }
00113   else
00114     vsl_b_write(bfs, vcl_string("VSL_NULL_PTR"));
00115 }
00116 
00117 template <class BaseClass>
00118 vsl_binary_loader<BaseClass>* vsl_binary_loader<BaseClass>::instance_ = 0;
00119 
00120 
00121 #undef VSL_BINARY_LOADER_INSTANTIATE
00122 #define VSL_BINARY_LOADER_WITH_SPECIALIZATION_INSTANTIATE(T) \
00123 VCL_DEFINE_SPECIALIZATION vcl_string vsl_binary_loader<T >::is_a() const \
00124 {  return vcl_string("vsl_binary_loader<" #T ">"); }\
00125 template class vsl_binary_loader<T >
00126 #define VSL_BINARY_LOADER_INSTANTIATE(T) \
00127 VSL_BINARY_LOADER_WITH_SPECIALIZATION_INSTANTIATE(T); \
00128 VCL_INSTANTIATE_INLINE(void vsl_b_read( vsl_b_istream& bfs, T*& b)); \
00129 template void vsl_b_write(vsl_b_ostream& bfs, const T* b)
00130 
00131 #endif // vsl_binary_loader_txx_