00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <s3fc/s3_streamable.h>
00026 #include <sstream>
00027 #include <iostream>
00028
00029
00030 s3_pack_buffer::s3_pack_buffer(size_t n_capacity) :
00031 capacity(n_capacity),
00032 pos(0),
00033 buf(0),
00034 own_storage(true)
00035 {
00036 if ( capacity )
00037 {
00038 buf = new unsigned char[capacity];
00039 }
00040 }
00041
00042
00043 s3_pack_buffer::s3_pack_buffer(void* n_buf,
00044 size_t n_size) :
00045 capacity(n_size),
00046 pos(0),
00047 buf(static_cast<unsigned char*>(n_buf)),
00048 own_storage(false)
00049 {
00050 }
00051
00052
00053 s3_pack_buffer::~s3_pack_buffer()
00054 {
00055
00056 if ( own_storage )
00057 {
00058 delete[] buf;
00059 }
00060 }
00061
00062
00063 void s3_pack_buffer::reset()
00064 {
00065 pos = 0;
00066 }
00067
00068
00069 const s3_pack_buffer& s3_pack_buffer::operator+=(int n) const
00070 {
00071 CONST_OVERRIDE_THIS(s3_pack_buffer) operator+=(n);
00072 return *this;
00073 }
00074
00075
00076 s3_pack_buffer& s3_pack_buffer::operator+=(int n)
00077 {
00078
00079 if ( (n+pos) > capacity )
00080 {
00081 enlarge(n+pos);
00082 }
00083 pos += n;
00084 return *this;
00085 }
00086
00087
00088 const void* s3_pack_buffer::get_buffer() const
00089 {
00090 return CONST_OVERRIDE_THIS(s3_pack_buffer) get_buffer();
00091 }
00092
00093
00094 void* s3_pack_buffer::get_buffer()
00095 {
00096 return buf;
00097 }
00098
00099
00100 const void* s3_pack_buffer::get_current() const
00101 {
00102 return CONST_OVERRIDE_THIS(s3_pack_buffer) get_current();
00103 }
00104
00105
00106 void* s3_pack_buffer::get_current()
00107 {
00108 return buf + pos;
00109 }
00110
00111
00112 void s3_pack_buffer::set_capacity(size_t n)
00113 {
00114
00115 if ( capacity != n )
00116 {
00117 if ( own_storage )
00118 {
00119 delete[] buf;
00120 buf = new unsigned char[n];
00121 capacity = n;
00122 }
00123 else
00124 {
00125 std::cerr << "s3_pack_buffer::set_capacity(size_t n) "
00126 << "invoked with own_storage = false"
00127 << " (aborting)..."
00128 << std::endl << std::endl << std::flush;
00129 abort();
00130 }
00131 }
00132 pos = 0;
00133 }
00134
00135
00136 size_t s3_pack_buffer::get_size() const
00137 {
00138 return pos;
00139 }
00140
00141
00142 void s3_pack_buffer::copy_in(const void* src, size_t n)
00143 {
00144
00145 if ( (n+pos) > capacity )
00146 {
00147 enlarge(n+pos);
00148 }
00149 memcpy(get_current(), src, n);
00150 pos += n;
00151 }
00152
00153
00154 void s3_pack_buffer::copy_out(void* dst, size_t n) const
00155 {
00156
00157 if ( (n+pos) > capacity )
00158 {
00159 std::cerr << "s3_pack_buffer::copy_out(void* dst, size_t n) "
00160 << "n+pos > capacity"
00161 << " (aborting)..."
00162 << std::endl << std::endl << std::flush;
00163 abort();
00164 }
00165 memcpy(dst, get_current(), n);
00166 CONST_OVERRIDE_THIS(s3_pack_buffer) pos += n;
00167 }
00168
00169
00170 void s3_pack_buffer::enlarge(size_t n)
00171 {
00172 if ( ! own_storage )
00173 {
00174 std::cerr << "s3_pack_buffer::enlarge(size_t n) "
00175 << "invoked with own_storage = false"
00176 << " (aborting)..."
00177 << std::endl << std::endl << std::flush;
00178 abort();
00179 }
00180
00181 unsigned char* old_buf = buf;
00182 buf = new unsigned char[n];
00183 memcpy(buf, old_buf, pos);
00184 capacity = n;
00185 delete[] old_buf;
00186 }
00187
00188
00189 void s3_streamable_helper_other<std::string>::pack(const std::string& s,
00190 s3_pack_buffer& b)
00191 {
00192 #ifdef S3_VERBOSE_PACKING
00193 std::stringstream str;
00194 str << "string:";
00195 s3_streamable::pack_string(str.str(), b);
00196 #endif
00197 std::string::size_type i = s.length();
00198 s3_streamable::pack(i, b);
00199 b.copy_in(s.c_str(),
00200 sizeof(*s.c_str()) * s.length());
00201 }
00202
00203
00204 void s3_streamable_helper_other<std::string>::unpack(std::string& s,
00205 const s3_pack_buffer& b)
00206 {
00207 #ifdef S3_VERBOSE_PACKING
00208 s3_streamable::unpack_string(b);
00209 #endif
00210 std::string::size_type i;
00211 s3_streamable::unpack(i, b);
00212
00213 s.erase();
00214 s.append(static_cast<std::string::const_pointer>(b.get_current()), i);
00215 b += i;
00216 }
00217
00218 #ifdef S3_VERBOSE_PACKING
00219
00220 void s3_streamable::pack_string(const std::string& s,
00221 s3_pack_buffer& b)
00222 {
00223 std::string::size_type n = s.length();
00224 b.copy_in(&n, sizeof(n));
00225 b.copy_in(s.c_str(),
00226 sizeof(*s.c_str()) * s.length());
00227 }
00228
00229
00230 std::string s3_streamable::unpack_string(const s3_pack_buffer& b)
00231 {
00232 std::string::size_type n;
00233 b.copy_out(&n, sizeof(n));
00234
00235 std::string s(static_cast<std::string::const_pointer>(b.get_current()), n);
00236 b += n;
00237 return s;
00238 }
00239 #endif
00240
00241