00001
00007 #include "dkcOSIndependent.h"
00008 #include "dkcStream.h"
00009 #include "dkcStdio.h"
00010 #include <limits.h>
00011
00012
00013 static DKC_INLINE int SetStreamInfo(DKC_STREAM *p,UINT flag){
00014 UINT stream_mode = 0;
00015 BYTE endian_mode = 0;
00016 UINT proc_mode = 0;
00017
00018 BOOL isLittle = dkcIsLittleEndian();
00019
00020
00022 if(flag & edkcStreamInitMemory){
00023 stream_mode = edkcStreamInitMemory;
00024 }else if(flag & edkcStreamInitFile){
00025 stream_mode = edkcStreamInitFile;
00026 }else{
00027 goto Error;
00028 }
00029
00030
00031 endian_mode = FALSE;
00033 if(flag & edkcStreamBigEndian){
00034
00035 if(isLittle){
00036 endian_mode = TRUE;
00037 }
00038 }else if(flag & edkcStreamLittleEndian){
00039
00040 if(!isLittle){
00041 endian_mode = TRUE;
00042 }
00043 }else {
00044 if(isLittle){
00045
00046 }else{
00047
00048 }
00049 }
00050
00051
00052 proc_mode |= (flag & edkcStreamProcessDefault);
00053 if(0==proc_mode){
00054 proc_mode |= (flag & edkcStreamProcessAsOrdered);
00055
00056 if(0==proc_mode){
00057 proc_mode |= edkcStreamProcessAsOrdered;
00058 }
00059 }
00060 proc_mode |= (flag & edkcStreamWriteErrorWhenEndianChange );
00061
00062
00063 p->mMode = stream_mode;
00064
00065 dkcmNOT_ASSERT(proc_mode > UCHAR_MAX);
00066 p->mProcessMode = (BYTE)proc_mode;
00067
00068 p->mChangeEndian = endian_mode;
00069
00070 return edk_SUCCEEDED;
00071 Error:
00072 return edk_FAILED;
00073
00074 }
00075
00076 DKC_STREAM *WINAPI dkcAllocStreamMemoryType(UINT flag,const void *default_data,size_t size){
00077 DKUTIL_FLAG_DOWN(flag,edkcStreamInitFile);
00078 DKUTIL_FLAG_UP(flag,edkcStreamInitMemory);
00079 return dkcAllocStream(flag,default_data,size,NULL,NULL);
00080
00081 }
00082
00083 DKC_STREAM *WINAPI dkcAllocStreamFileType(UINT flag,const char *filename,const char *mode){
00084 DKUTIL_FLAG_DOWN(flag,edkcStreamInitMemory);
00085 DKUTIL_FLAG_UP(flag,edkcStreamInitFile);
00086 return dkcAllocStream(flag,NULL,0,filename,mode);
00087 }
00088
00089 DKC_STREAM * WINAPI dkcAllocStream(UINT flag,
00090 const void *default_data,size_t size,
00091 const char *filename,const char *mode)
00092 {
00093
00094 DKC_STREAM *p;
00095 void *psig;
00096
00097
00098 p = dkcAllocate(sizeof(DKC_STREAM));
00099 if(NULL==p){
00100 return NULL;
00101 }
00102
00103 if(DKUTIL_FAILED(SetStreamInfo(p,flag))){
00104 goto Error;
00105 }
00106
00107 switch(p->mMode){
00108 case edkcStreamInitMemory:
00109 psig = (void *)dkcAllocMemoryStream(size);
00110 if(NULL==psig){
00111 goto Error;
00112 }
00113
00114 p->mSig = psig;
00115
00116 dkcStreamWrite(p,default_data,size);
00117 break;
00118 case edkcStreamInitFile:
00119 psig = (void *)dkcFOpen(filename,mode);
00120 if(NULL==psig){
00121 goto Error;
00122 }
00123
00124 p->mSig = psig;
00125
00126 break;
00127 default:
00128 goto Error;
00129 }
00130
00131
00132
00133
00134 return p;
00135 Error:
00136 dkcFree(&p);
00137 return NULL;
00138 }
00139
00140
00141 int WINAPI dkcFreeStream(DKC_STREAM **p){
00142 DKC_STREAM *t;
00143 if(NULL==p){
00144 return edk_FAILED;
00145 }
00146 t = *p;
00147 if(NULL==t){
00148 return edk_FAILED;
00149 }
00150
00151 switch(t->mMode){
00152 case edkcStreamInitMemory:
00153 dkcFreeMemoryStream((DKC_MEMORYSTREAM **)&(t->mSig));
00154 break;
00155 case edkcStreamInitFile:
00156 dkcFClose((FILE **)&(t->mSig));
00157 break;
00158 #ifdef DEBUG
00159 default:
00160 dkcmNOT_ASSERT("dkcFreeStream FAILED");
00161 #endif
00162 }
00163 return dkcFree(p);
00164 }
00165
00166
00167
00168
00169 int WINAPI dkcStreamSeek(DKC_STREAM *ptr,int offset,int origin){
00170 int r = edk_FAILED;
00171 switch(ptr->mMode){
00172 case edkcStreamInitMemory:
00173 r = dkcMemoryStreamSeek(ptr->mSig,offset,origin);
00174 break;
00175 case edkcStreamInitFile:
00176 r = fseek(ptr->mSig,offset,origin);
00177 break;
00178 }
00179 return r;
00180
00181 }
00182
00184 long WINAPI dkcStreamTell(DKC_STREAM *ptr){
00185 int r = edk_FAILED;
00186 switch(ptr->mMode){
00187 case edkcStreamInitMemory:
00188 r = dkcMemoryStreamTell(ptr->mSig);
00189 case edkcStreamInitFile:
00190 r = ftell(ptr->mSig);
00191 }
00192 return r;
00193
00194 }
00195
00196 static DKC_INLINE int dkcStreamReadObayAnOrder(
00197 DKC_STREAM *ptr,void *buffer,size_t size,size_t *readsize)
00198 {
00199 int r = edk_FAILED;
00200 size_t readsize_ = 0;
00201 size_t count;
00202 size_t tc,tsize;
00203 BYTE *tbuffer;
00204 FILE *fp = ptr->mSig;
00205
00206 if(NULL==readsize){
00207 readsize = &readsize_;
00208 }
00209
00210
00211
00212
00213 tsize = size;
00214
00215 tc = 0;
00216
00217 count = 0;
00218
00219 tbuffer = (BYTE *)buffer;
00220 for(;;)
00221 {
00222
00223 if(ferror(fp) ){
00224
00225 r = edk_FAILED;
00226 break;
00227 }
00228 if(feof(fp)){
00229
00230 r = edk_BufferOverFlow;
00231 break;
00232 }
00233
00234 tc = fread(&tbuffer[count],1,tsize,fp);
00235
00236 tsize -= tc;
00237 count += tc;
00238
00239 if(count == size){
00240 r = edk_SUCCEEDED;
00241 break;
00242 }
00243 # ifdef DEBUG
00244
00245 dkcmNOT_ASSERT(count > size);
00246 # else
00247 if(count > size){
00248 break;
00249 }
00250 # endif
00251 }
00252 *readsize = count;
00253 return r;
00254
00255 }
00256
00257 DKC_INLINE int WINAPI dkcStreamRead(DKC_STREAM *ptr,void *buffer,size_t size,size_t *readsize){
00258 int r = edk_FAILED;
00259 FILE *fp = ptr->mSig;
00260 size_t redsize = 0;
00261 if(NULL==readsize){
00262 readsize = &redsize;
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272 switch(ptr->mMode){
00273 case edkcStreamInitMemory:
00274 r = dkcMemoryStreamRead(ptr->mSig,
00275 buffer,size,readsize);
00276 break;
00277 case edkcStreamInitFile:
00278
00279 if(ptr->mProcessMode & edkcStreamProcessDefault){
00280 *readsize = fread(buffer,1,size,fp);
00281 if(!ferror(fp)){
00282 r = edk_SUCCEEDED;
00283 }
00284 }else{
00285 r = dkcStreamReadObayAnOrder(ptr,buffer,size,readsize);
00286 }
00287
00288
00289 break;
00290 }
00291 return r;
00292 }
00293
00294 static DKC_INLINE int dkcStreamWriteObayAnOrder(DKC_STREAM *ptr,const void *buffer,size_t size){
00295 int r = edk_FAILED;
00296 size_t tc,tsize;
00297 size_t count;
00298 const BYTE *tbuffer = buffer;
00299 FILE *fp;
00300
00301 tc = 0;
00302 count = 0;
00303 tsize = size;
00304 fp = ptr->mSig;
00305
00306 for(;;){
00307
00308 if(ferror(fp)){
00309 return edk_FAILED;
00310 }
00311 if(feof(fp)){
00312 return edk_BufferOverFlow;
00313 }
00314
00315 tc = fwrite(&tbuffer[count],1,tsize,fp);
00316
00317 tsize -= tc;
00318 count += tc;
00319
00320 if(count == size){
00321 r = edk_SUCCEEDED;
00322 break;
00323 }
00324 # ifdef DEBUG
00325
00326 dkcmNOT_ASSERT(count > size);
00327 # else
00328 if(count > size){
00329
00330 break;
00331 }
00332 # endif
00333
00334 }
00335
00336
00337 return r;
00338 }
00339
00340 DKC_INLINE int WINAPI dkcStreamWrite(DKC_STREAM *ptr,const void *buffer,size_t size)
00341 {
00342 int r = edk_FAILED;
00343
00344 UINT proc_flag = ptr->mProcessMode;
00346 if(proc_flag & edkcStreamWriteErrorWhenEndianChange){
00347 if(ptr->mChangeEndian){
00348 return edk_Not_Satisfactory;
00349 }
00350 }
00351
00352 switch(ptr->mMode){
00353 case edkcStreamInitMemory:
00354 r = dkcMemoryStreamWrite(ptr->mSig,buffer,size);
00355 break;
00356 case edkcStreamInitFile:
00357 r = dkcStreamWriteObayAnOrder(ptr,buffer,size);
00358 break;
00359 }
00360
00361 return r;
00362 }
00363
00364 static int WINAPI StreamWrite(DKC_STREAM *ptr, void *buffer,size_t size,void *hoge){
00365 return dkcStreamWrite(ptr,buffer,size);
00366 }
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 int WINAPI dkcStreamWrite16(DKC_STREAM *ptr, const void *buffer,size_t size){
00391 return dkcStreamProcess16(ptr,(void *)buffer,size,StreamWrite,NULL);
00392 }
00393
00394 int WINAPI dkcStreamWrite32(DKC_STREAM *ptr, const void *buffer,size_t size){
00395 return dkcStreamProcess32(ptr,(void *)buffer,size,StreamWrite,NULL);
00396
00397 }
00398
00399
00400
00401 int WINAPI dkcStreamWrite64(DKC_STREAM *ptr, const void *buffer,size_t size){
00402 return dkcStreamProcess64(ptr,(void *)buffer,size,StreamWrite,NULL);
00403 }
00404
00405
00406
00407
00408 int WINAPI dkcStreamProcess(DKC_STREAM *ptr,void *buffer,size_t size,
00409 DKC_STREAM_PROCESS_TYPE write_t,void *data)
00410 {
00411 return write_t(ptr,buffer,size,data);
00412 }
00413
00414
00415
00416 int WINAPI dkcStreamProcess16(DKC_STREAM *ptr,void *buffer,size_t size,
00417 DKC_STREAM_PROCESS_TYPE write_t,void *data){
00418 int r;
00419 USHORT *pb;
00420 size_t elem_num,pause = 16;
00421 size_t i;
00422
00423 if(size % pause != 0){
00424 return edk_ArgumentException;
00425 }
00426 if(ptr->mChangeEndian)
00427 {
00428 pb = (USHORT *)malloc(size);
00429 if(NULL==pb){
00430 return edk_FAILED;
00431 }
00432
00433
00434 memcpy(pb,buffer,size);
00435 elem_num = size / pause;
00436
00437
00438 for(i=0;i<elem_num;i++){
00439 pb[i] = dkcReverseEndian16(pb[i]);
00440 }
00441
00442 r = write_t(ptr,pb,size,data);
00443
00444 free(pb);
00445 }else{
00446 r = write_t(ptr,buffer,size,data);
00447 }
00448 return r;
00449 }
00450 int WINAPI dkcStreamProcess32(DKC_STREAM *ptr,void *buffer,size_t size,
00451 DKC_STREAM_PROCESS_TYPE write_t,void *data){
00452 int r;
00453 ULONG *pb;
00454 size_t elem_num,pause = 32;
00455 size_t i;
00456
00457 if(size % pause != 0){
00458 return edk_ArgumentException;
00459 }
00460 if(ptr->mChangeEndian)
00461 {
00462 pb = (ULONG *)malloc(size);
00463 if(NULL==pb){
00464 return edk_FAILED;
00465 }
00466
00467
00468 memcpy(pb,buffer,size);
00469 elem_num = size / pause;
00470
00471
00472 for(i=0;i<elem_num;i++){
00473 pb[i] = dkcReverseEndian32(pb[i]);
00474 }
00475
00476 r = write_t(ptr,pb,size,data);
00477
00478 free(pb);
00479 }else{
00480 r = write_t(ptr,buffer,size,data);
00481 }
00482 return r;
00483
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493 int WINAPI dkcStreamProcess64(DKC_STREAM *ptr,void *buffer,size_t size,
00494 DKC_STREAM_PROCESS_TYPE write_t,void *data){
00495 int r;
00496 ULONGLONG *pb;
00497 size_t elem_num,pause = 64;
00498 size_t i;
00499
00500 if(size % pause != 0){
00501 return edk_ArgumentException;
00502 }
00503 if(ptr->mChangeEndian)
00504 {
00505 pb = (ULONGLONG *)malloc(size);
00506 if(NULL==pb){
00507 return edk_FAILED;
00508 }
00509
00510
00511 memcpy(pb,buffer,size);
00512 elem_num = size / pause;
00513
00514
00515 for(i=0;i<elem_num;i++){
00516 pb[i] = dkcReverseEndian64(pb[i]);
00517 }
00518
00519 r = write_t(ptr,pb,size,data);
00520
00521 free(pb);
00522 }else{
00523 r = write_t(ptr,buffer,size,data);
00524 }
00525 return r;
00526 }
00527
00528
00529
00530
00531 int WINAPI dkcStreamClear(DKC_STREAM *ptr){
00532
00533 size_t fsize;
00534
00535 size_t tsize;
00536 size_t write_size;
00537 FILE *fp;
00538 int r = edk_FAILED;
00539 char null_array[1024];
00540
00541
00542 switch(ptr->mMode){
00543 case edkcStreamInitMemory:
00544 r = dkcMemoryStreamClear( ptr->mSig );
00545 break;
00546 case edkcStreamInitFile:
00547
00548 memset(null_array,0,sizeof(null_array));
00549 fp = ptr->mSig;
00550
00551
00552 fseek( fp, 0, SEEK_END ) ;
00553 fsize = ftell( fp ) ;
00554 fseek( fp, 0, SEEK_SET ) ;
00555
00556 if(fsize > sizeof(null_array))
00557 {
00558
00559 tsize = 0;
00560 write_size = sizeof(null_array);
00561 for(;;){
00562
00563 r = dkcStreamWrite(ptr,null_array,write_size);
00564
00565 if(DKUTIL_FAILED(r)){
00566 return r;
00567 }
00568 if(tsize >= fsize){
00569 r = edk_SUCCEEDED;
00570 break;
00571 }
00572
00573 if(tsize + write_size > fsize){
00574 write_size = fsize - tsize;
00575 }else{
00576 tsize += write_size;
00577
00578
00579 write_size = sizeof(null_array);
00580 }
00581 }
00582 }else{
00583 r = dkcStreamWrite(ptr,null_array,fsize);
00584 }
00585
00586 break;
00587 }
00588 return r;
00589 }