core/vsl/vsl_vector_io.txx
Go to the documentation of this file.
00001 // This is core/vsl/vsl_vector_io.txx
00002 #ifndef vsl_vector_io_txx_
00003 #define vsl_vector_io_txx_
00004 //:
00005 // \file
00006 // \brief binary IO functions for vcl_vector<T>
00007 // \author Tim Cootes
00008 
00009 #include "vsl_vector_io.h"
00010 #include <vsl/vsl_binary_io.h>
00011 #include <vsl/vsl_block_binary.h>
00012 #include <vsl/vsl_b_read_block_old.h>
00013 #include <vcl_iostream.h>
00014 #include <vcl_cassert.h>
00015 #include <vsl/vsl_indent.h>
00016 
00017 //====================================================================================
00018 //: Write vector to binary stream
00019 template <class T>
00020 void vsl_b_write(vsl_b_ostream& s, const vcl_vector<T>& v)
00021 {
00022   vcl_size_t n = v.size();
00023   // There is nothing in the STL standard that says that vector<> has
00024   // to store its data in a contiguous memory block. However, most
00025   // implementations do store data this way.
00026   // Check this assumption holds.
00027   assert(n == 0 || &v[n-1] + 1 == &v[0] + n);
00028 
00029   const short version_no = 3;
00030   vsl_b_write(s, version_no);
00031   vsl_b_write(s,n);
00032   if (n!=0)
00033     vsl_block_binary_write(s, &v.front(), n);
00034 }
00035 
00036 
00037 template <class T> bool vsl_is_char(const T&);
00038 
00039 VCL_DEFINE_SPECIALIZATION inline bool vsl_is_char(const unsigned char &)
00040 { return true; }
00041 VCL_DEFINE_SPECIALIZATION inline bool vsl_is_char(const signed char &)
00042 { return true; }
00043 template <class T> bool vsl_is_char(const T&) { return false; }
00044 
00045 //====================================================================================
00046 //: Read vector from binary stream
00047 template <class T>
00048 void vsl_b_read(vsl_b_istream& is, vcl_vector<T>& v)
00049 {
00050   if (!is) return;
00051 
00052   short ver;
00053   vsl_b_read(is, ver);
00054   unsigned n;
00055   vsl_b_read(is,n);
00056   v.resize(n); // Note that this resize means that the object must be default
00057                // constructable. It is very hard to see how to avoid this requirement,
00058                // without designing types that are constructable directly from a stream.
00059 
00060   // In some old versions of the standard STL there is no requirement for
00061   // vector<> to store its data in a contiguous memory block. However, most
00062   // implementations do store data this way.
00063   // Check this assumption holds.
00064   assert(n == 0 || &v[n-1] + 1 == &v[0] + n);
00065 
00066   switch (ver)
00067   {
00068    case 1:
00069     if (n!=0)
00070     {
00071       vsl_b_read_block_old(is, &v.front(), n);
00072     }
00073     break;
00074    case 2:
00075     if (n!=0)
00076     {
00077       if (vsl_is_char(v.front())) // signed char or unsigned char
00078       {
00079         vsl_block_binary_read_confirm_specialisation(is, false);
00080         vsl_b_read_block_old(is, &v.front(), n);
00081       }
00082       else
00083         vsl_block_binary_read(is, &v.front(), n);
00084     }
00085     break;
00086    case 3:
00087     if (n!=0)
00088     {
00089       vsl_block_binary_read(is, &v.front(), n);
00090     }
00091     break;
00092 
00093 
00094    default:
00095     vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, vcl_vector<T>&)\n"
00096              << "           Unknown version number "<< ver << '\n';
00097     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00098     return;
00099   }
00100 }
00101 
00102 //====================================================================================
00103 //: Output a human readable summary to the stream
00104 template <class T>
00105 void vsl_print_summary(vcl_ostream& os, const vcl_vector<T> &v)
00106 {
00107   os << vsl_indent() << "Vector length: " << v.size() << '\n';
00108   for (unsigned int i=0; i<v.size() && i<5; i++)
00109   {
00110     os << vsl_indent() << ' ' << i << ": ";
00111     vsl_indent_inc(os);
00112     vsl_print_summary(os, v[i]);
00113     os << '\n';
00114     vsl_indent_dec(os);
00115   }
00116   if (v.size() > 5)
00117     os << vsl_indent() << " ...\n";
00118 }
00119 
00120 
00121 #define VSL_VECTOR_IO_INSTANTIATE(T) \
00122 template void vsl_print_summary(vcl_ostream& s, const vcl_vector<T >& v); \
00123 template void vsl_b_write(vsl_b_ostream& s, const vcl_vector<T >& v); \
00124 template void vsl_b_read(vsl_b_istream& s, vcl_vector<T >& v)
00125 
00126 #endif // vsl_vector_io_txx_