Go to the documentation of this file.00001
00002 #include "gevd_memory_mixin.h"
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <vcl_cstring.h>
00039 #include <vcl_algorithm.h>
00040
00041
00042
00043
00044
00045
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
00060
00061
00062 if (GetStatusCode() & MM_CLEAR)
00063 {
00064 vcl_memset(buffer, 0, size);
00065 touched = size;
00066 }
00067
00068
00069
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
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
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
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
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
00220
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
00241
00242 if (GetStatusCode() & MM_CLEAR)
00243 {
00244 vcl_memset(buffer, 0, size);
00245 touched = size;
00246 }
00247
00248
00249
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
00284
00285
00286
00287 curr_into += num_b;
00288 touched = vcl_max( touched, curr_into );
00289
00290 current += num_b;
00291 return num_b;
00292 }
00293
00294
00295
00296
00297 int
00298 gevd_memory_mixin::WriteBytes(const void* ib, int b, int loc)
00299 {
00300
00301
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
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 }