arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

KokoBuffer.cpp

Go to the documentation of this file.
00001 //
00002 //------------------------------------------------------------------------
00003 //
00004 // File   : KokoBuffer.cpp 
00005 // Author : Patrick McCormick (pat@acl.lanl.gov)
00006 // 
00007 // $Date: 2003/08/04 04:57:49 $
00008 // $Revision: 1.8 $
00009 //
00010 // This class implements a very simple buffer for holding bytes of data. 
00011 // The main purpose of the class is to support the packing of data for
00012 // sending it over the network. 
00013 //
00014 // This code has similar features to the MPI pack and unpack routines.
00015 //
00016 // TODO NOTE: It may be necessary to use MPI_Alloc() for memory allocation if
00017 //       you plan on using these buffers as contents for messages.  Is 
00018 //       this only an issue with MPIPro???  
00019 //
00020 //------------------------------------------------------------------------
00021 #include <iostream>
00022 #include <string.h>
00023 
00024 #include "koko.h"
00025 
00026 #include "KokoBuffer.h"
00027 
00028 //
00029 // When we grow a buffer we'll add an extra number
00030 // of bytes.  This is the default.  TOTO: We should
00031 // probably just make this a factor (e.g. grow in 
00032 // size by a factor of...).
00033 //
00034 const float KOKOBUF_GROWTH_FACTOR = 2.0;  
00035 
00036 using namespace std;
00037 
00038 // ------------------
00039 // --- KokoBuffer ---
00040 // ------------------
00041 //
00042 KokoBuffer::KokoBuffer(void)
00043 {
00044   _locked   = false;
00045   _size     = 0; 
00046   _start    = 0;
00047   _buf      = 0;
00048   _aptr     = 0;
00049   _eptr     = 0;
00050   _cursize  = 0;
00051   _growfact = KOKOBUF_GROWTH_FACTOR;
00052 }
00053 
00054 
00055 // ------------------
00056 // --- KokoBuffer ---
00057 // ------------------
00058 //
00059 KokoBuffer::KokoBuffer(unsigned int size)
00060 {
00061   _locked   = false;
00062   _size     = size;
00063   _start    = new unsigned char[_size + sizeof(KokoTag)];
00064   _buf      = _start + sizeof(KokoTag);
00065   _aptr     = _buf;
00066   _eptr     = _buf;
00067   _cursize  = 0;  // no data in buffer yet.
00068   _growfact = KOKOBUF_GROWTH_FACTOR;
00069 }
00070 
00071 
00072 // ------------------
00073 // --- KokoBuffer ---
00074 // ------------------
00075 //
00076 KokoBuffer::KokoBuffer(unsigned char *buf, unsigned int size, bool pad)
00077 {
00078   _growfact = KOKOBUF_GROWTH_FACTOR;
00079   if (pad == true)
00080     _size = (int)(size + _growfact);
00081   else
00082     _size = size;
00083  
00084   _locked  = false;
00085   _start   = new unsigned char[_size + sizeof(KokoTag)];
00086   _buf     = _start + sizeof(KokoTag);
00087   _cursize = size;
00088   _aptr    = _buf + _cursize;
00089   _eptr    = _buf;
00090   memcpy((void *)_buf, buf, sizeof(unsigned char) * size);
00091 }
00092 
00093 
00094 // ------------------
00095 // --- KokoBuffer ---
00096 // ------------------
00097 //
00098 KokoBuffer::KokoBuffer(const KokoBuffer &kbuf)
00099 {
00100   _locked    = false;        // For our purposes, it isn't a good 
00101                              //   idea to copy the lock state.
00102   _size      = kbuf._size;
00103   _start     = new unsigned char[_size + sizeof(KokoTag)];
00104   _buf       = _start + sizeof(KokoTag);
00105   _cursize   = kbuf._cursize;
00106   _growfact  = kbuf._growfact;
00107 
00108   memcpy((void *)_buf, (const void *)kbuf._buf, sizeof(unsigned char) * _size);
00109   _aptr      = _buf + (kbuf._aptr - kbuf._buf);
00110   _eptr      = _buf + (kbuf._eptr - kbuf._buf);
00111 }
00112 
00113 
00114 // ---------------
00115 // --- memcopy ---
00116 // ---------------
00117 //
00118 void KokoBuffer::Memcopy(unsigned char *bufp, unsigned int size)
00119 {
00120   if (bufp == 0) {
00121     cerr << "KokoBuffer::Memcopy() : Warning! Buffer pointer is null.\n";
00122     return;
00123   }
00124 
00125   if (_locked) {
00126     cerr << "KokoBuffer::Memcopy() : Buffer is locked!  Copy can't proceed.\n";
00127     return;
00128   }
00129 
00130   if (_size < size) {
00131     delete []_start;
00132     _start   = new unsigned char[size + sizeof(KokoTag)];
00133     _buf     = _start + sizeof(KokoBuffer);
00134     _size    = size;
00135     _cursize = size;
00136   } else {
00137     _cursize = size;
00138   }
00139 
00140   // Note that we currently don't copy the tag portion
00141   // of the buffer. 
00142   memcpy((void *)_buf, (const void *)bufp, size);
00143 }
00144 
00145 
00146 // ------------
00147 // --- Pack ---
00148 // ------------
00149 //
00150 bool KokoBuffer::Pack(unsigned char *bufp, unsigned int size)
00151 {
00152   if (bufp == 0) {
00153     cerr << "KokoBuffer::Pack() : Warning! Buffer pointer is null.\n";
00154     return false;
00155   }
00156 
00157   if (_locked) {
00158     cerr << "KokoBuffer::Pack() : Buffer is locked!  Pack can't proceed.\n";
00159     return false;
00160   }
00161 
00162   if (size > bytes_free()) {
00163     grow(_size + (int)(size * _growfact));
00164     _growfact *= 2; //
00165   }
00166 
00167   memcpy((void *)_aptr, (const void *)bufp, size);
00168   _aptr    += size;
00169   _cursize += size;
00170   return true;
00171 }
00172 
00173 
00174 // --------------
00175 // --- Unpack ---
00176 // --------------
00177 //
00178 bool KokoBuffer::Unpack(unsigned char *dest, unsigned int size)
00179 {
00180   if (dest == 0) {
00181     cerr << "KokoBuffer::Unpack() : Warning!  Destination pointer is null.\n";
00182     return false;
00183   }
00184 
00185   if (_buf == 0) {
00186     cerr << "KokoBuffer::Unpack() : Warning! Buffer is empty!\n";
00187     return false;
00188   }
00189 
00190   if (_locked) {
00191     cerr << "KokoBuffer::Unpack() : Buffer is locked! Unpack can't proceed.\n";
00192     return false;
00193   }
00194 
00195   if (size > _size) {
00196     cerr << "KokoBuffer::Unpack() : Warning! Requested size exceeds "
00197          << "entire buffer size.\n";
00198     cerr << "\t*** Total buffer size   = " << _size << endl;
00199     cerr << "\t*** Unpack request size = " << size << endl;
00200     return false;
00201   }
00202 
00203   unsigned int bytes_left = _cursize - (_eptr - _buf);
00204 
00205   if (size > bytes_left) {
00206     cerr << "KokoBuffer::Unpack() : Warning! Request size exceeds space "
00207          << "remaining in buffer.\n";
00208     cerr << "\t*** Size       = " << size << endl;
00209     cerr << "\t*** bytes left = " << bytes_left << endl; 
00210     cerr << "\t*** cursize    = " << _cursize << endl;
00211     return false;
00212   }
00213 
00214   memcpy((void *)dest, (const void *)_eptr, size);
00215   _eptr += size;
00216 
00217   bytes_left = _cursize - (_eptr - _buf);
00218 
00219   return true;
00220 }
00221 
00222 
00223 // --------------
00224 // --- SetTag ---
00225 // --------------
00226 // Set the buffer's tag value -- stored at the front of the 
00227 // buffer. 
00228 //
00229 void KokoBuffer::SetTag(KokoTag &tag)
00230 {
00231   if( _start != 0) 
00232     memcpy((void *)_start, (const void *)&tag, sizeof(KokoTag));
00233 }
00234 
00235 
00236 // --------------
00237 // --- GetTag ---
00238 // --------------
00239 // Get the buffer's tag value -- stored at the front of the 
00240 // buffer. 
00241 //
00242 KokoTag KokoBuffer::GetTag(void)
00243 {
00244   KokoTag  tag;
00245   if (_start != 0) {
00246     memcpy((void *)&tag, (const void *)_start, sizeof(KokoTag));
00247     return tag;
00248   } else {
00249     return KOKO_ANY_TAG;  // Not sure if this is wise -- perhaps
00250                           // we should have a KOKO_INVALID_TAG
00251                           // value?
00252   }
00253 }
00254 
00255 
00256 // ------------
00257 // --- grow ---
00258 // ------------
00259 // Grow the buffer to the new size. 
00260 //
00261 void KokoBuffer::grow(unsigned int new_size)
00262 {
00263   if (_locked) {
00264     cerr << "KokoBuffer::grow() : Buffer is locked.  "
00265          << "Resize/grow can't proceed.\n";
00266     return;
00267   }
00268 
00269   cerr << "growing kokobuffer to " << new_size << " bytes.\n";
00270   unsigned char *nbuf = new unsigned char[new_size];
00271   memcpy((void *)nbuf, (const void *)_buf, _cursize);
00272   delete []_buf;  // clean up.
00273   _buf    = nbuf;
00274   _aptr   = _buf + _cursize;
00275   _size   = new_size;
00276 }
00277 

Send questions, comments, and bug reports to:
jmk