S3FC project page S3FC home page

Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

s3_streamable.cc

Go to the documentation of this file.
00001 /*
00002  * Stone Three Foundation Class (s3fc) provides a number of utility classes.
00003  * Copyright (C) 2001 by Stone Three Signal Processing (Pty) Ltd.
00004  *
00005  * Authored by Stone Three Signal Processing (Pty) Ltd.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  * 
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  * 
00021  * Please see the file 'COPYING' in the source root directory.
00022  */
00023 
00024 
00025 #include <s3fc/s3_streamable.h>
00026 #include <sstream>
00027 #include <iostream>
00028 
00029 // dflt and init ctor - init with size (can and may be 0)
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 // init ctor - init from _existing_ array
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 // dtor - dealloc buffer if we own it
00053 s3_pack_buffer::~s3_pack_buffer()
00054 {
00055    // _only_ blow storage if it's _our_ problem
00056    if ( own_storage )
00057    {
00058       delete[] buf;
00059    }
00060 }
00061 
00062 // reset position
00063 void s3_pack_buffer::reset()
00064 {
00065    pos = 0;
00066 }
00067 
00068 // const operator+=
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 // increment the current position by n
00076 s3_pack_buffer& s3_pack_buffer::operator+=(int n)
00077 {
00078    // reallocate and retain data if we're going to spill
00079    if ( (n+pos) > capacity )
00080    {
00081       enlarge(n+pos);
00082    }
00083    pos += n;
00084    return *this;
00085 }
00086 
00087 // const get_address
00088 const void* s3_pack_buffer::get_buffer() const
00089 {
00090    return CONST_OVERRIDE_THIS(s3_pack_buffer) get_buffer();
00091 }
00092 
00093 // return addresss of first element
00094 void* s3_pack_buffer::get_buffer()
00095 {
00096    return buf;
00097 }
00098 
00099 // const get_current
00100 const void* s3_pack_buffer::get_current() const
00101 {
00102    return CONST_OVERRIDE_THIS(s3_pack_buffer) get_current();
00103 }
00104 
00105 // return address of current element
00106 void* s3_pack_buffer::get_current()
00107 {
00108    return buf + pos;
00109 }
00110 
00111 // set the capacity to specified value
00112 void s3_pack_buffer::set_capacity(size_t n)
00113 {
00114    // only realloc if necessary
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 // return size
00136 size_t s3_pack_buffer::get_size() const
00137 {
00138    return pos;
00139 }
00140 
00141 // copy n bytes from src to current pos and increment pos
00142 void s3_pack_buffer::copy_in(const void* src, size_t n) 
00143 {
00144    // reallocate and retain data if we're going to spill
00145    if ( (n+pos) > capacity )
00146    {
00147       enlarge(n+pos);
00148    }
00149    memcpy(get_current(), src, n);
00150    pos += n;
00151 }
00152 
00153 // copy n bytes from current pos to dst and increment pos
00154 void s3_pack_buffer::copy_out(void* dst, size_t n) const
00155 {
00156    // this is WAY wrong
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 // new - memcpy - delete
00170 void s3_pack_buffer::enlarge(size_t n)
00171 {
00172    if ( ! own_storage ) // should NEVER happen !
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    // clear old string
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    // construct string from first i chars
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             

Send comments to: s3fc@stonethree.com SourceForge Logo