contrib/gel/gevd/gevd_memory_mixin.cxx
Go to the documentation of this file.
00001 // This is gel/gevd/gevd_memory_mixin.cxx
00002 #include "gevd_memory_mixin.h"
00003 //:
00004 // \file
00005 // <begin copyright notice>
00006 // ---------------------------------------------------------------------------
00007 //
00008 //                   Copyright (c) 1997 TargetJr Consortium
00009 //               GE Corporate Research and Development (GE CRD)
00010 //                             1 Research Circle
00011 //                            Niskayuna, NY 12309
00012 //                            All Rights Reserved
00013 //              Reproduction rights limited as described below.
00014 //
00015 //      Permission to use, copy, modify, distribute, and sell this software
00016 //      and its documentation for any purpose is hereby granted without fee,
00017 //      provided that (i) the above copyright notice and this permission
00018 //      notice appear in all copies of the software and related documentation,
00019 //      (ii) the name TargetJr Consortium (represented by GE CRD), may not be
00020 //      used in any advertising or publicity relating to the software without
00021 //      the specific, prior written permission of GE CRD, and (iii) any
00022 //      modifications are clearly marked and summarized in a change history
00023 //      log.
00024 //
00025 //      THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
00026 //      EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
00027 //      WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
00028 //      IN NO EVENT SHALL THE TARGETJR CONSORTIUM BE LIABLE FOR ANY SPECIAL,
00029 //      INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND OR ANY
00030 //      DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00031 //      WHETHER OR NOT ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR ON
00032 //      ANY THEORY OF LIABILITY ARISING OUT OF OR IN CONNECTION WITH THE
00033 //      USE OR PERFORMANCE OF THIS SOFTWARE.
00034 //
00035 // ---------------------------------------------------------------------------
00036 // <end copyright notice>
00037 
00038 #include <vcl_cstring.h>   // memset() and memcpy() live here
00039 #include <vcl_algorithm.h>
00040 
00041 //=========================================================================
00042 //=========================================================================
00043 
00044 //====================================================================
00045 // Constructor.  Modified @ 6/11/91 gbs
00046 //====================================================================
00047 gevd_memory_mixin::gevd_memory_mixin(int s, void* ib, unsigned int type)
00048 {
00049   size      = s;
00050   curr_into = 0;
00051   offset    = 0;
00052   SetStatus((type&MM_CREATION_FLAGS));
00053 
00054   if ((ib == 0) && (s>0))
00055   {
00056     touched = 0;
00057     buffer  = new unsigned char[size];
00058 
00059     // If desired, zero out the buffer and set the touched
00060     // flag to indicate that all data is valid.
00061     //
00062     if (GetStatusCode() & MM_CLEAR)
00063     {
00064       vcl_memset(buffer, 0, size); // corrected by PVr.
00065       touched = size;
00066     }
00067 
00068     // If we allocate a buffer and MM_PROTECTED is set,
00069     // we must clear it so that it can be deallocated.
00070     //
00071     ClearStatus(MM_PROTECTED);
00072 
00073     if (!buffer)
00074     {
00075       SetStatus(MM_MEMORY_ERROR);
00076       size = 0;
00077     }
00078   }
00079   else
00080   {
00081     touched = size;
00082     buffer  = (unsigned char*)ib;
00083     if (!buffer)
00084       SetStatus(MM_NIL_BUFFER|MM_WARN);
00085     else
00086       SetStatus(MM_PROTECTED|MM_FOREIGN_BLOCK|MM_DIRTY);
00087   }
00088   current = buffer;
00089 }
00090 
00091 gevd_memory_mixin::gevd_memory_mixin(gevd_memory_mixin const& m)
00092  : gevd_status_mixin(), size(m.GetSize()), touched(size), curr_into(0), offset(0)
00093 {
00094   buffer  = new unsigned char[size];
00095   vcl_memcpy(buffer, m.GetBufferPtr(), size);
00096   current = buffer;
00097   SetStatus((m.Stat()&MM_CREATION_FLAGS));
00098   ClearStatus(MM_PROTECTED);
00099   if (!buffer)
00100   {
00101     SetStatus(MM_MEMORY_ERROR);
00102     size = 0;
00103   }
00104 }
00105 
00106 gevd_memory_mixin::~gevd_memory_mixin()
00107 {
00108   if (!(GetStatusCode()&MM_PROTECTED))
00109     delete [] buffer;
00110 }
00111 
00112 int
00113 gevd_memory_mixin::ReadBytes(void* ib, int b)
00114 {
00115   if ((ib == 0) || !(GetStatusCode()&MM_READ))
00116     return 0;
00117   int num_b;
00118   if ((num_b=vcl_min(b, touched-curr_into)) < 0) num_b = 0;
00119   if (num_b<b)
00120     SetStatus(MM_DATA_OVERFLOW);
00121   else
00122     ClearStatus(MM_ERROR|MM_WARN);
00123   vcl_memcpy(ib, current,num_b);
00124   current   += num_b;
00125   curr_into += num_b;
00126   return num_b;
00127 }
00128 
00129 //====================================================================
00130 //: Read b bytes from location loc to buffer ib.  New @ 6/11/91 gbs
00131 //====================================================================
00132 int
00133 gevd_memory_mixin::ReadBytes(void* ib, int b, int loc)
00134 {
00135   if ((ib == 0) || !(GetStatusCode()&MM_READ))
00136     return 0;
00137 
00138   //
00139   // loc is always relative to offset, so modify...
00140   //
00141   loc += offset;
00142   int num_b;
00143   if (loc<offset)
00144   {
00145     SetStatus(MM_UNDERFLOW);
00146     num_b = 0;
00147   }
00148   else
00149   {
00150     num_b = vcl_min(b+loc, touched) - loc;
00151     if (num_b<b)
00152       SetStatus(MM_OVERFLOW);
00153     else
00154       ClearStatus(MM_ERROR|MM_WARN);
00155   }
00156   vcl_memcpy(ib, buffer+loc,num_b);
00157   current = buffer + (curr_into += num_b);
00158   return num_b;
00159 }
00160 
00161 int
00162 gevd_memory_mixin::ReadBytes(void* ib, int b, int* mapping)
00163 {
00164   if ((ib == 0) || !(GetStatusCode()&MM_READ))
00165     return 0;
00166   int num_b;
00167   if ((num_b=vcl_min(b, touched-curr_into)) < 0) num_b = 0;;
00168   if (num_b<b)
00169     SetStatus(MM_OVERFLOW);
00170   else
00171     ClearStatus(MM_ERROR|MM_WARN);
00172   char* ibt = (char*)ib;
00173   for (int i = 0; i<num_b; i++)
00174     *(ibt++) = (char)mapping[*(current++)];
00175   curr_into += num_b;
00176   return num_b;
00177 }
00178 
00179 //====================================================================
00180 //: Read b bytes from loc to ib, thru mapping.  New @ 6/11/91 gbs
00181 //====================================================================
00182 int
00183 gevd_memory_mixin::ReadBytes(void* ib, int b, int loc, int* mapping)
00184 {
00185   if ((ib == 0) || !(GetStatusCode()&MM_READ))
00186     return 0;
00187   //
00188   // loc is always relative to offset, so modify...
00189   //
00190   loc += offset;
00191   int num_b;
00192   if (loc<offset)
00193   {
00194     SetStatus(MM_UNDERFLOW);
00195     num_b = 0;
00196   }
00197   else
00198   {
00199     num_b = vcl_min(b+loc, size) - loc;
00200   }
00201   if (num_b<b)
00202     SetStatus(MM_OVERFLOW);
00203   else
00204     ClearStatus(MM_ERROR|MM_WARN);
00205   if (loc<size && !(MM_UNDERFLOW & GetStatusCode()))
00206   {
00207     current   = buffer + loc;
00208     curr_into = vcl_min(loc+num_b,size);
00209   }
00210   char* ibt = (char*)ib;
00211   for (int i = 0; i<num_b; i++)
00212     *(ibt++) = (char)mapping[*(current++)];
00213   return num_b;
00214 }
00215 
00216 void
00217 gevd_memory_mixin::SetMemoryPtr(int s, void* ib)
00218 {
00219   // If status is MM_FIXED, we are not allowed to replace
00220   // the buffer with a new one...
00221   //
00222   if (GetStatusCode()&MM_FIXED)
00223   {
00224     SetStatus(MM_ERROR);
00225     return;
00226   }
00227 
00228   if (!(GetStatusCode()&MM_PROTECTED)) delete buffer;
00229   size      = s;
00230   curr_into = 0;
00231   offset    = 0;
00232   ClearStatus();
00233   SetStatus(MM_READ|MM_WRITE);
00234 
00235   if ((ib == 0) && (s>0))
00236   {
00237     touched = 0;
00238     buffer  = new unsigned char[size];
00239 
00240     // If desired, zero out the buffer and set the touched
00241     // flag to indicate that all data is valid.
00242     if (GetStatusCode() & MM_CLEAR)
00243     {
00244       vcl_memset(buffer, 0, size); // corrected by PVr.
00245       touched = size;
00246     }
00247 
00248     // If we allocate a buffer and MM_PROTECTED is set,
00249     // we must clear it so that it can be deallocated.
00250     //
00251     ClearStatus(MM_PROTECTED);
00252 
00253     if (!buffer)
00254     {
00255       SetStatus(MM_MEMORY_ERROR);
00256       size = 0;
00257     }
00258   }
00259   else
00260   {
00261     touched = size;
00262     buffer  = (unsigned char*)ib;
00263     if (!buffer)
00264       SetStatus(MM_NIL_BUFFER|MM_WARN);
00265     else
00266       SetStatus(MM_PROTECTED|MM_FOREIGN_BLOCK|MM_DIRTY);
00267   }
00268 
00269   current = buffer;
00270 }
00271 
00272 int
00273 gevd_memory_mixin::WriteBytes(const void* ib, int b)
00274 {
00275   if (!(GetStatusCode()&MM_WRITE))
00276     return 0;
00277   int num_b = vcl_min(b, size-curr_into);
00278   vcl_memcpy(current, ib,num_b);
00279   if (num_b<b)
00280     SetStatus(MM_OVERFLOW);
00281   else
00282     ClearStatus(MM_ERROR|MM_WARN);
00283   /* touched = curr_into += num_b; */ // << Massive brain damage!!!!!
00284   // What if the buffer already has valid data and we are
00285   // just writing over some of it, like we do in export!!!!
00286 
00287   curr_into += num_b;                  // fixed 11/1/91 ajh
00288   touched = vcl_max( touched, curr_into ); //
00289 
00290   current   += num_b;
00291   return num_b;
00292 }
00293 
00294 //====================================================================
00295 //: Write b bytes to location loc from buffer ib.  New @ 6/11/91 gbs
00296 //====================================================================
00297 int
00298 gevd_memory_mixin::WriteBytes(const void* ib, int b, int loc)
00299 {
00300   //
00301   // loc is always relative to offset, so modify...
00302   //
00303   loc += offset;
00304   int num_b;
00305   if (loc<offset)
00306   {
00307     SetStatus(MM_UNDERFLOW);
00308     num_b = 0;
00309   }
00310   else
00311   {
00312     num_b = vcl_min(b+loc, size) - loc;
00313   }
00314   if (num_b<b) SetStatus(MM_OVERFLOW);
00315   if (loc<size && !(MM_UNDERFLOW & GetStatusCode()))
00316   {
00317     vcl_memcpy(buffer+loc,ib,num_b);
00318     curr_into = vcl_min(loc+num_b,size);
00319     current   = buffer + curr_into;
00320   }
00321   return num_b;
00322 }
00323 
00324 //====================================================================
00325 //: Clear the memory and reset all of the appropriate variables.
00326 //====================================================================
00327 void
00328 gevd_memory_mixin::Clear()
00329 {
00330   touched = size;
00331   curr_into = 0;
00332   current = buffer;
00333   offset = 0;
00334   vcl_memset((char*)buffer,0,size);
00335 }