reSIProcate/rutil  9694
DataStream.cxx
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include "config.h"
00003 #endif
00004 
00005 #include <cassert>
00006 #include "rutil/DataStream.hxx"
00007 #include "rutil/Data.hxx"
00008 
00009 // Remove warning about 'this' use in initiator list - pointer is only stored
00010 #if defined(WIN32) && !defined(__GNUC__)
00011 #pragma warning( disable : 4355 ) // using this in base member initializer list 
00012 #endif
00013 
00014 using namespace resip;
00015 
00016 DataBuffer::DataBuffer(Data& str)
00017    : mStr(str)
00018 {
00019 #ifdef RESIP_USE_STL_STREAMS
00020    char* gbuf = const_cast<char*>(mStr.mBuf);
00021    setg(gbuf, gbuf, gbuf+mStr.size());
00022    // expose the excess capacity as the put buffer
00023    setp(gbuf+mStr.mSize, gbuf+mStr.mCapacity);
00024 #endif
00025 }
00026 
00027 DataBuffer::~DataBuffer()
00028 {}
00029 
00030 #ifndef RESIP_USE_STL_STREAMS
00031 UInt64 DataBuffer::tellpbuf(void)
00032 { 
00033    return mStr.size(); 
00034 }
00035 
00036 size_t DataBuffer::readbuf(char *buf, size_t count)
00037 {
00038    if (count <= 0)
00039    {
00040       return 0;
00041    }
00042 
00043    if (!buf)
00044    {
00045       assert(0);
00046       return 0;
00047    }
00048 
00049    size_t cursize = mStr.size();
00050 
00051    size_t toread = (cursize < count) ? (cursize) : (count);
00052 
00053    memcpy(buf,mStr.begin(),toread);
00054 
00055    //wow, not efficient.  Just added this function for repro, need to revisit. @TODO.
00056    mStr = mStr.substr(toread);
00057 
00058    return toread;
00059 }
00060 
00061 size_t DataBuffer::writebuf(const char *str, size_t count)
00062 {
00063    if( count <= 0 )
00064    {
00065       return 0;
00066    }
00067 
00068    mStr.append(str,count);
00069    return count;
00070 }
00071 size_t DataBuffer::putbuf(char ch)
00072 {
00073    mStr += ch;
00074 
00075    return 1;
00076 }
00077 #else
00078 int
00079 DataBuffer::sync()
00080 {
00081    size_t len = pptr() - pbase();
00082    if (len > 0)
00083    {
00084       size_t pos = gptr() - eback();  // remember the get position
00085       mStr.mSize += len;
00086       char* gbuf = const_cast<char*>(mStr.data());
00087       // reset the get buffer
00088       setg(gbuf, gbuf+pos, gbuf+mStr.size());
00089       // reset the put buffer
00090       setp(gbuf + mStr.mSize, gbuf + mStr.mCapacity);
00091    }
00092    return 0;
00093 }
00094 
00095 int
00096 DataBuffer::overflow(int c)
00097 {
00098    // sync, but reallocate
00099    size_t len = pptr() - pbase();
00100    // .kw. test below is always true. Checked with David Butcher
00101    // and he says this is safe but perhaps performs unrequired
00102    // re-allocs.
00103    if (len >= 0)
00104    {
00105       size_t pos = gptr() - eback();  // remember the get position
00106 
00107       // update the length
00108       mStr.mSize += len;
00109 
00110       // resize the underlying Data and reset the input buffer
00111       mStr.resize(((mStr.mCapacity+16)*3)/2, true);
00112 
00113       char* gbuf = const_cast<char*>(mStr.mBuf);
00114       // reset the get buffer
00115       setg(gbuf, gbuf+pos, gbuf+mStr.mSize);
00116       // reset the put buffer
00117       setp(gbuf + mStr.mSize, gbuf + mStr.mCapacity);
00118    }
00119    if (c != -1)
00120    {
00121       mStr.mBuf[mStr.mSize] = c;
00122       pbump(1);
00123       return c;
00124    }
00125    return 0;
00126 }
00127 #endif
00128 
00129 iDataStream::iDataStream(Data& str)
00130    : DataBuffer(str), 
00131      DecodeStream(this)
00132 {
00133 }
00134 
00135 iDataStream::~iDataStream()
00136 {}
00137 
00138 oDataStream::oDataStream(Data& str)
00139    : DataBuffer(str), 
00140    EncodeStream(this)
00141 {
00142    // don't call this with a read-only buffer!
00143    assert(str.mShareEnum != Data::Share);
00144 }
00145 
00146 oDataStream::~oDataStream()
00147 {
00148    flush();
00149 }
00150 
00151 void
00152 oDataStream::reset()
00153 {
00154    flush();
00155    mStr.clear();
00156 #ifdef RESIP_USE_STL_STREAMS
00157    // reset the underlying buffer state
00158    char* gbuf = const_cast<char*>(mStr.mBuf);
00159    setg(gbuf, gbuf, gbuf+mStr.size());
00160    setp(gbuf+mStr.mSize, gbuf+mStr.mCapacity);
00161 #endif
00162 }
00163 
00164 DataStream::DataStream(Data& str)
00165    : DataBuffer(str), 
00166 #ifdef  RESIP_USE_STL_STREAMS
00167      std::iostream(this)
00168 #else
00169    ResipFastOStream(this)
00170 #endif
00171 {
00172    // don't call this with a read-only buffer!
00173    assert(str.mShareEnum != Data::Share);
00174 }
00175 
00176 DataStream::~DataStream()
00177 {
00178    flush();
00179 }
00180 
00181 /* ====================================================================
00182  * The Vovida Software License, Version 1.0
00183  *
00184  * Copyright 2000-2005
00185  *
00186  * Redistribution and use in source and binary forms, with or without
00187  * modification, are permitted provided that the following conditions
00188  * are met:
00189  *
00190  * 1. Redistributions of source code must retain the above copyright
00191  *    notice, this list of conditions and the following disclaimer.
00192  *
00193  * 2. Redistributions in binary form must reproduce the above copyright
00194  *    notice, this list of conditions and the following disclaimer in
00195  *    the documentation and/or other materials provided with the
00196  *    distribution.
00197  *
00198  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00199  *    and "Vovida Open Communication Application Library (VOCAL)" must
00200  *    not be used to endorse or promote products derived from this
00201  *    software without prior written permission. For written
00202  *    permission, please contact vocal@vovida.org.
00203  *
00204  * 4. Products derived from this software may not be called "VOCAL", nor
00205  *    may "VOCAL" appear in their name, without prior written
00206  *    permission of Vovida Networks, Inc.
00207  * 
00208  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00209  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00210  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00211  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00212  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00213  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00214  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00215  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00216  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00217  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00218  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00219  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00220  * DAMAGE.
00221  * 
00222  * ====================================================================
00223  * 
00224  * This software consists of voluntary contributions made by Vovida
00225  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00226  * Inc.  For more information on Vovida Networks, Inc., please see
00227  * <http://www.vovida.org/>.
00228  *
00229  */