00001
00002
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 #include <vcl_cstring.h>
00038
00039 #include <vcl_algorithm.h>
00040
00041 #include "gevd_memory_mixin.h"
00042
00043
00044
00045
00046
00047
00048
00049
00050 gevd_memory_mixin::gevd_memory_mixin(int s, void* ib, unsigned int type)
00051 {
00052 size = s;
00053 curr_into = 0;
00054 offset = 0;
00055 SetStatus((type&MM_CREATION_FLAGS));
00056
00057 if ((ib == 0) && (s>0))
00058 {
00059 touched = 0;
00060 buffer = new unsigned char[size];
00061
00062
00063
00064
00065 if (GetStatusCode() & MM_CLEAR)
00066 {
00067 vcl_memset(buffer, 0, size);
00068 touched = size;
00069 }
00070
00071
00072
00073
00074 ClearStatus(MM_PROTECTED);
00075
00076 if (!buffer)
00077 {
00078 SetStatus(MM_MEMORY_ERROR);
00079 size = 0;
00080 }
00081 }
00082 else
00083 {
00084 touched = size;
00085 buffer = (unsigned char*)ib;
00086 if (!buffer)
00087 SetStatus(MM_NIL_BUFFER|MM_WARN);
00088 else
00089 SetStatus(MM_PROTECTED|MM_FOREIGN_BLOCK|MM_DIRTY);
00090 }
00091 current = buffer;
00092 }
00093
00094 gevd_memory_mixin::gevd_memory_mixin(gevd_memory_mixin const& m)
00095 : gevd_status_mixin(), size(m.GetSize()), touched(size), curr_into(0), offset(0)
00096 {
00097 buffer = new unsigned char[size];
00098 vcl_memcpy(buffer, m.GetBufferPtr(), size);
00099 current = buffer;
00100 SetStatus((m.Stat()&MM_CREATION_FLAGS));
00101 ClearStatus(MM_PROTECTED);
00102 if (!buffer)
00103 {
00104 SetStatus(MM_MEMORY_ERROR);
00105 size = 0;
00106 }
00107 }
00108
00109 gevd_memory_mixin::~gevd_memory_mixin()
00110 {
00111 if (!(GetStatusCode()&MM_PROTECTED))
00112 delete [] buffer;
00113 }
00114
00115 int
00116 gevd_memory_mixin::ReadBytes(void* ib, int b)
00117 {
00118 if ((ib == 0) || !(GetStatusCode()&MM_READ))
00119 return 0;
00120 int num_b;
00121 if ((num_b=vcl_min(b, touched-curr_into)) < 0) num_b = 0;
00122 if (num_b<b)
00123 SetStatus(MM_DATA_OVERFLOW);
00124 else
00125 ClearStatus(MM_ERROR|MM_WARN);
00126 vcl_memcpy(ib, current,num_b);
00127 current += num_b;
00128 curr_into += num_b;
00129 return num_b;
00130 }
00131
00132
00133
00134
00135 int
00136 gevd_memory_mixin::ReadBytes(void* ib, int b, int loc)
00137 {
00138 if ((ib == 0) || !(GetStatusCode()&MM_READ))
00139 return 0;
00140
00141
00142
00143
00144 loc += offset;
00145 int num_b;
00146 if (loc<offset)
00147 {
00148 SetStatus(MM_UNDERFLOW);
00149 num_b = 0;
00150 }
00151 else
00152 {
00153 num_b = vcl_min(b+loc, touched) - loc;
00154 if (num_b<b)
00155 SetStatus(MM_OVERFLOW);
00156 else
00157 ClearStatus(MM_ERROR|MM_WARN);
00158 }
00159 vcl_memcpy(ib, buffer+loc,num_b);
00160 current = buffer + (curr_into += num_b);
00161 return num_b;
00162 }
00163
00164 int
00165 gevd_memory_mixin::ReadBytes(void* ib, int b, int* mapping)
00166 {
00167 if ((ib == 0) || !(GetStatusCode()&MM_READ))
00168 return 0;
00169 int num_b;
00170 if ((num_b=vcl_min(b, touched-curr_into)) < 0) num_b = 0;;
00171 if (num_b<b)
00172 SetStatus(MM_OVERFLOW);
00173 else
00174 ClearStatus(MM_ERROR|MM_WARN);
00175 char* ibt = (char*)ib;
00176 for (int i = 0; i<num_b; i++)
00177 *(ibt++) = mapping[*(current++)];
00178 curr_into += num_b;
00179 return num_b;
00180 }
00181
00182
00183
00184
00185 int
00186 gevd_memory_mixin::ReadBytes(void* ib, int b, int loc, int* mapping)
00187 {
00188 if ((ib == 0) || !(GetStatusCode()&MM_READ))
00189 return 0;
00190
00191
00192
00193 loc += offset;
00194 int num_b;
00195 if (loc<offset)
00196 {
00197 SetStatus(MM_UNDERFLOW);
00198 num_b = 0;
00199 }
00200 else
00201 {
00202 num_b = vcl_min(b+loc, size) - loc;
00203 }
00204 if (num_b<b)
00205 SetStatus(MM_OVERFLOW);
00206 else
00207 ClearStatus(MM_ERROR|MM_WARN);
00208 if (loc<size && !(MM_UNDERFLOW & GetStatusCode()))
00209 {
00210 current = buffer + loc;
00211 curr_into = vcl_min(loc+num_b,size);
00212 }
00213 char* ibt = (char*)ib;
00214 for (int i = 0; i<num_b; i++)
00215 *(ibt++) = mapping[*(current++)];
00216 return num_b;
00217 }
00218
00219 void
00220 gevd_memory_mixin::SetMemoryPtr(int s, void* ib)
00221 {
00222
00223
00224
00225 if (GetStatusCode()&MM_FIXED)
00226 {
00227 SetStatus(MM_ERROR);
00228 return;
00229 }
00230
00231 if (!(GetStatusCode()&MM_PROTECTED)) delete buffer;
00232 size = s;
00233 curr_into = 0;
00234 offset = 0;
00235 ClearStatus();
00236 SetStatus(MM_READ|MM_WRITE);
00237
00238 if ((ib == 0) && (s>0))
00239 {
00240 touched = 0;
00241 buffer = new unsigned char[size];
00242
00243
00244
00245 if (GetStatusCode() & MM_CLEAR)
00246 {
00247 vcl_memset(buffer, 0, size);
00248 touched = size;
00249 }
00250
00251
00252
00253
00254 ClearStatus(MM_PROTECTED);
00255
00256 if (!buffer)
00257 {
00258 SetStatus(MM_MEMORY_ERROR);
00259 size = 0;
00260 }
00261 }
00262 else
00263 {
00264 touched = size;
00265 buffer = (unsigned char*)ib;
00266 if (!buffer)
00267 SetStatus(MM_NIL_BUFFER|MM_WARN);
00268 else
00269 SetStatus(MM_PROTECTED|MM_FOREIGN_BLOCK|MM_DIRTY);
00270 }
00271
00272 current = buffer;
00273 }
00274
00275 int
00276 gevd_memory_mixin::WriteBytes(const void* ib, int b)
00277 {
00278 if (!(GetStatusCode()&MM_WRITE))
00279 return 0;
00280 int num_b = vcl_min(b, size-curr_into);
00281 vcl_memcpy(current, ib,num_b);
00282 if (num_b<b)
00283 SetStatus(MM_OVERFLOW);
00284 else
00285 ClearStatus(MM_ERROR|MM_WARN);
00286
00287
00288
00289
00290
00291 curr_into += num_b;
00292 touched = vcl_max( touched, curr_into );
00293
00294 current += num_b;
00295 return num_b;
00296 }
00297
00298
00299
00300
00301 int
00302 gevd_memory_mixin::WriteBytes(const void* ib, int b, int loc)
00303 {
00304
00305
00306
00307 loc += offset;
00308 int num_b;
00309 if (loc<offset)
00310 {
00311 SetStatus(MM_UNDERFLOW);
00312 num_b = 0;
00313 }
00314 else
00315 {
00316 num_b = vcl_min(b+loc, size) - loc;
00317 }
00318 if (num_b<b) SetStatus(MM_OVERFLOW);
00319 if (loc<size && !(MM_UNDERFLOW & GetStatusCode()))
00320 {
00321 vcl_memcpy(buffer+loc,ib,num_b);
00322 curr_into = vcl_min(loc+num_b,size);
00323 current = buffer + curr_into;
00324 }
00325 return num_b;
00326 }
00327
00328
00329
00330
00331 void
00332 gevd_memory_mixin::Clear()
00333 {
00334 touched = size;
00335 curr_into = 0;
00336 current = buffer;
00337 offset = 0;
00338 vcl_memset((char*)buffer,0,size);
00339 }