メインページ | アルファベット順一覧 | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

# dkcMemoryStream.c

説明を見る。

    00001
    00006 #define DKUTIL_C_MEMORYSTREAM_C
    00007 #include <limits.h>
    00008 #include "dkcMemoryStream.h"
    00009 #include "dkcSJISFileSystem.h"
    00010 #include "dkcStdio.h"
    00011
    00012
    00013
    00014
    00015
    00016 DKC_MEMORYSTREAM * WINAPI dkcAllocMemoryStream(size_t size){
    00017     DKC_MEMORYSTREAM *p;
    00018     if(0==size) return NULL;
    00019
    00020     p = (DKC_MEMORYSTREAM *)dkcAllocate(sizeof(DKC_MEMORYSTREAM));
    00021
    00022     if(NULL==p) return NULL;
    00023     p->mBuffer = (BYTE *)dkcAllocate(size);
    00024     if(NULL==p->mBuffer) goto Error;
    00025
    00026     p->mSize = size;
    00027     p->mNowOffset = 0;
    00028     return p;
    00029 Error:
    00030     dkcFree((void **)&p);
    00031     return NULL;
    00032
    00033 }
    00034
    00035
    00036 int WINAPI dkcFreeMemoryStream(DKC_MEMORYSTREAM **ptr){
    00037     if(NULL==ptr || NULL==*ptr) return edk_ArgumentException;
    00038     if(NULL==(*ptr)->mBuffer) return edk_FAILED;
    00039
    00040     dkcFree((void **)&((*ptr)->mBuffer));
    00041     return dkcFree((void **)ptr);
    00042 }
    00043
    00044
    00045
    00046
    00047 static int WINAPI dkcMemoryStreamSeekLogic(DKC_MEMORYSTREAM *ptr,int offset,int point,int origin){
    00048     /*
    00049     状態繊維：
    00050     offset + succeeded
    00051     offset - succeeded
    00052     offset + length error
    00053     offset - length error
    00054     */
    00055     size_t change = (size_t)(point + offset);
    00056
    00057     if(TRUE==dkcCheckOverflow32(point,offset)){
    00058         return edk_FAILED;
    00059     }
    00060     //if(!(ptr->mSize > change)){
    00061     if(!(ptr->mSize >= change)){
    00062         return edk_FAILED;
    00063     }
    00064
    00065     //common...
    00066
    00067     ptr->mNowOffset = change;
    00068
    00069
    00070     return edk_SUCCEEDED;
    00071 }
    00072
    00073 int WINAPI dkcMemoryStreamSeek(DKC_MEMORYSTREAM *ptr,int offset,int origin){
    00074     int result = edk_FAILED;
    00075     if(NULL==ptr) return edk_ArgumentException;
    00076     switch(origin)
    00077     {
    00078     case edkcMemoryStreamSeekCurrent://今の位置からシーク
    00079         result = dkcMemoryStreamSeekLogic(ptr,offset,ptr->mNowOffset,origin);
    00080         break;
    00081     case edkcMemoryStreamSeekEnd://最後の位置からシーク
    00082         //result = dkcMemoryStreamSeekLogic(ptr,offset,0,origin);
    00083         result = dkcMemoryStreamSeekLogic(ptr,offset,ptr->mSize /*- 1*/,origin);
    00084         break;
    00085     case edkcMemoryStreamSeekSet://最初の位置からシーク
    00086         //result = dkcMemoryStreamSeekLogic(ptr,offset,ptr->mSize /*- 1*/,origin);
    00087         result = dkcMemoryStreamSeekLogic(ptr,offset,0,origin);
    00088         break;
    00089     default:
    00090         //変な引数入れるな！
    00091         return edk_ArgumentException;
    00092     }
    00093     return result;
    00094 }
    00095
    00096 size_t WINAPI dkcMemoryStreamGetSeekPoint(DKC_MEMORYSTREAM *ptr)
    00097 {
    00098     return ptr->mNowOffset;
    00099 }
    00100
    00101 DKC_INLINE int WINAPI dkcMemoryStreamRead(DKC_MEMORYSTREAM *ptr,void *buffer,size_t size,size_t *readsize){
    00102
    00103
    00104     size_t f_read = 0;
    00105     //error check
    00106
    00107     if(NULL==ptr || NULL==readsize) return edk_ArgumentException;
    00108
    00109     //Read = (int)(ptr->mNowOffset + size);
    00110     //Read = (int)(ptr->mSize - Read);
    00111     //if(Read < 0) return edk_BufferOverFlow;
    00112
    00113     //process...
    00114
    00115     f_read = ptr->mNowOffset + size;
    00116
    00117     if(ptr->mSize <= f_read){
    00118         f_read = ptr->mSize - ptr->mNowOffset;
    00119         if(0==f_read) return edk_BufferOverFlow;
    00120     }else{
    00121         f_read = size;
    00122     }
    00123
    00124
    00125     //酷バグ：まずい、酷いバグだ。
    00126     /*dkcmNOT_ASSERT(edk_FAILED==dkc_memcpy(buffer,size,
    00127         ptr->mBuffer + ptr->mNowOffset,f_read
    00128     ));*/
    00129     if(DKUTIL_FAILED(dkc_memcpy(buffer,size,ptr->mBuffer + ptr->mNowOffset,f_read)))
    00130     {
    00131         return edk_FAILED;
    00132     }
    00133
    00134     //update...
    00135     ptr->mNowOffset += f_read;
    00136     *readsize = f_read;
    00137
    00138     return edk_SUCCEEDED;
    00139 }
    00140
    00141
    00142 int WINAPI dkcMemoryStreamResize(DKC_MEMORYSTREAM *ptr,size_t want_size)
    00143 {
    00144     int ra_r = 0;
    00145     void *NewPtr = NULL;
    00146     void *OldPtr = NULL;
    00147
    00148     //error check
    00149     if(NULL==ptr) return edk_ArgumentException;
    00150
    00151
    00152     //process
    00153     OldPtr = ptr->mBuffer;
    00154
    00155     ra_r = dkcReallocate(&NewPtr,want_size,&OldPtr);
    00156     if(DKUTIL_FAILED(ra_r)){
    00157         return edk_FAILED;
    00158     }
    00159
    00160     //update...
    00161     ptr->mBuffer = (BYTE *)NewPtr;
    00162     ptr->mSize = want_size;
    00163
    00164
    00165     return edk_SUCCEEDED;
    00166 }
    00167
    00172 static int WINAPI dkcMemoryStreamAutoExpandResize(DKC_MEMORYSTREAM *ptr,size_t expand_size){
    00173     int ra_r = 0;
    00174     void *NewPtr = NULL;
    00175     void *OldPtr = NULL;
    00176     size_t ReallocatedSize = 0;
    00177     size_t want_size;
    00178     //size_t want_size = ptr->mSize + expand_size + 1;//なんとなく＋１
    00179
    00180     if(NULL==ptr) return edk_ArgumentException;
    00181
    00182     OldPtr = ptr->mBuffer;
    00183     /*
    00184     ra_r = dkcReallocateAutoExpand(realloc,&NewPtr,&OldPtr,ptr->mSize,&ReallocatedSize);
    00185     if(DKUTIL_FAILED(ra_r)){
    00186         return edk_FAILED;
    00187     }
    00188     if(want_size > ReallocatedSize){
    00189         OldPtr = NewPtr;
    00190         ra_r = dkcReallocate(&NewPtr,want_size,&OldPtr);
    00191         if(DKUTIL_FAILED(ra_r)){
    00192             return edk_FAILED;
    00193         }
    00194         ReallocatedSize = want_size;
    00195     }
    00196     */
    00197     want_size = dkcReallocateSizeFunction(
    00198         ptr->mSize + ptr->mNowOffset,
    00199         (expand_size <= 256) ? 256 : expand_size
    00200     );
    00201     ra_r = dkcReallocate(&NewPtr,want_size,&OldPtr);
    00202     if(DKUTIL_FAILED(ra_r)){
    00203         return edk_FAILED;
    00204     }
    00205     ReallocatedSize = want_size;
    00206
    00207
    00208
    00209     ptr->mBuffer = (BYTE *)NewPtr;
    00210     ptr->mSize = ReallocatedSize;
    00211
    00212
    00213     return edk_SUCCEEDED;
    00214
    00215 }
    00216
    00217 DKC_INLINE int WINAPI dkcMemoryStreamWrite(DKC_MEMORYSTREAM *ptr,const void *buffer,size_t size){
    00218     size_t rest;
    00219
    00220     if(NULL==ptr) return edk_ArgumentException;
    00221
    00222
    00223     if(ptr->mSize < ptr->mNowOffset + size){return edk_FAILED;}
    00224     rest = ptr->mSize - ptr->mNowOffset;
    00225
    00226     //酷バグ：dkcmNOT_ASSERTはDEBUGモード時にしか展開されない。
    00227     /*dkcmNOT_ASSERT(
    00228     ));*/
    00229     if(DKUTIL_FAILED(dkc_memcpy(
    00230         (void *)((BYTE *)ptr->mBuffer + ptr->mNowOffset),
    00231         rest,
    00232         buffer,size))){
    00233         return edk_FAILED;
    00234     }
    00235
    00236     ptr->mNowOffset += size;
    00237
    00238     return edk_SUCCEEDED;
    00239 }
    00240
    00241
    00242 int WINAPI dkcMemoryStreamDynamicWrite(DKC_MEMORYSTREAM *ptr,const void *buffer,size_t size){
    00243     int result;
    00244     size_t want_size;
    00245
    00246     if(NULL==ptr) return edk_ArgumentException;
    00247
    00248     want_size =  ptr->mNowOffset + size;
    00249
    00250     if(ptr->mSize < want_size)
    00251     {
    00252         result = dkcMemoryStreamAutoExpandResize(ptr,size);
    00253         //result = dkcMemoryStreamResize(ptr,want_size);
    00254         if(DKUTIL_FAILED(result)) return edk_FAILED;
    00255     }
    00256
    00257     return dkcMemoryStreamWrite(ptr,buffer,size);
    00258 }
    00259
    00260
    00261
    00262
    00263
    00264
    00265
    00266
    00267 DKC_INLINE int WINAPI dkcMemoryStreamClear(DKC_MEMORYSTREAM *ptr){
    00268     dkcmNOT_ASSERT(NULL==ptr);
    00269     //if(NULL==ptr) return edk_ArgumentException;
    00270     memset(ptr->mBuffer,0,ptr->mSize);
    00271     ptr->mNowOffset = 0;
    00272     return edk_SUCCEEDED;
    00273 }
    00274
    00275 DKC_INLINE size_t WINAPI dkcMemoryStreamNowOffset(DKC_MEMORYSTREAM *p){
    00276     return p->mNowOffset;
    00277 }
    00278
    00279 DKC_INLINE BYTE *WINAPI dkcMemoryStreamPointer(DKC_MEMORYSTREAM *p){
    00280     return p->mBuffer;
    00281
    00282 }
    00283
    00284 DKC_MEMORYSTREAM * WINAPI dkcAllocMemoryStreamCopy(const DKC_MEMORYSTREAM *ptr)
    00285 {
    00286     DKC_MEMORYSTREAM *tp = NULL;
    00287
    00288     dkcmNOT_ASSERT(NULL==ptr);
    00289
    00290     tp = dkcAllocMemoryStream(ptr->mSize);
    00291     if(NULL==tp) return NULL;
    00292
    00293     dkcMemoryStreamWrite(tp,ptr->mBuffer,ptr->mSize);
    00294
    00295     //内部オフセット変更                                    /* 先頭から */
    00296     dkcMemoryStreamSeek(tp,ptr->mNowOffset,edkcMemoryStreamSeekSet);
    00297     return tp;
    00298 }
    00299
    00300 /*
    00301 DKC_INLINE int WINAPI dkcMemoryStreamPushBack(DKC_MEMORYSTREAM_ADAPTER *p,const BYTE *buff,size_t size)
    00302 {
    00303     return msa_rw_proc(p,(BYTE *)buff,size,FALSE);
    00304 }
    00305 */
    00306 DKC_INLINE int WINAPI dkcMemoryStreamPopBack(DKC_MEMORYSTREAM_ADAPTER *p,size_t size)
    00307 {
    00308     /*if(size > p->mNowOffset){
    00309         return edk_FAILED;
    00310     }
    00311     p->mNowOffset -= size;
    00312     return edk_SUCCEEDED;*/
    00313     int t;
    00314     if(size > (size_t)(-(INT_MIN))){//sizeがでかい
    00315         return edk_ArgumentException;
    00316     }
    00317     t = (int)size;
    00318     t = -t;
    00319     return dkcMemoryStreamSeek(p,t,SEEK_CUR);
    00320 }
    00321
    00322 //**********************************************************
    00323 //memory stream adapter
    00324 /*
    00326 static DKC_FORCE_INLINE int msa_rw_proc(DKC_MEMORYSTREAM_ADAPTER *p,BYTE *buff,size_t size,BOOL is_read)
    00327 {
    00328     size_t offset = p->mNowOffset;
    00329     BYTE *tb = p->mBuffer;
    00330     if(dkcCheckOverflowULONG(offset,size)){
    00331         return edk_FAILED;
    00332     }
    00333     if(p->mNowOffset >= p->mSize){
    00334         return edk_FAILED;
    00335     }
    00336     if(is_read){
    00337         size_t rs = size;//only for debug
    00338         if(offset + size > p->mSize){
    00339             rs = offset + size - p->mSize;
    00340         }
    00341         memcpy(buff,&tb[offset],rs);
    00342         p->mNowOffset += rs;
    00343     }else{
    00344         //if(offset + size >= p->mSize){
    00345         if(offset + size > p->mSize){
    00346             return edk_BufferOverFlow;
    00347         }
    00348         memcpy(&tb[offset],buff,size);
    00349         p->mNowOffset += size;
    00350     }
    00351
    00352     return edk_SUCCEEDED;
    00353 }
    00354 */
    00355 DKC_INLINE void WINAPI dkcMemoryStreamAdapterInit(DKC_MEMORYSTREAM_ADAPTER *p,BYTE *buff,size_t size)
    00356 {
    00357     p->mBuffer = buff;
    00358     p->mSize = size;
    00359     p->mNowOffset = 0;
    00360
    00361 }
    00362 DKC_MEMORYSTREAM_ADAPTER *WINAPI dkcAllocMemoryStreamAdapter(BYTE *buff,size_t size){
    00363     DKC_MEMORYSTREAM_ADAPTER *p = dkcAllocate(sizeof(DKC_MEMORYSTREAM_ADAPTER));
    00364     if(NULL==p) return NULL;
    00365     dkcMemoryStreamAdapterInit(p,buff,size);
    00366     return p;
    00367 }
    00368
    00369 int WINAPI dkcFreeMemoryStreamAdapter(DKC_MEMORYSTREAM_ADAPTER **p)
    00370 {
    00371     return dkcFree(p);
    00372 }
    00373 DKC_MEMORYSTREAM_ADAPTER *dkcAllocMemoryStreamAdapterCopy(DKC_MEMORYSTREAM_ADAPTER *p)
    00374 {
    00375     DKC_MEMORYSTREAM_ADAPTER *tp = dkcAllocMemoryStreamAdapter(p->mBuffer,p->mSize);
    00376     if(!tp) return NULL;
    00377     tp->mNowOffset = p->mNowOffset;
    00378     return tp;
    00379 }
    00380
    00381
    00382 #if 0
    00383 DKC_INLINE int WINAPI dkcMemoryStreamAdapterSetOffset(DKC_MEMORYSTREAM_ADAPTER *p,size_t offset){
    00384     if(offset > p->mSize){
    00385         return edk_FAILED;
    00386     }
    00387     p->mNowOffset = offset;
    00388     return edk_SUCCEEDED;
    00389 }
    00390 DKC_INLINE size_t WINAPI dkcMemoryStreamAdapterGetOffset(DKC_MEMORYSTREAM_ADAPTER *p){
    00391     return p->mNowOffset;
    00392 }
    00393
    00394 DKC_INLINE int WINAPI dkcMemoryStreamAdapterRead(DKC_MEMORYSTREAM_ADAPTER *p,void *buff,size_t buffsize,size_t *readsize)
    00395 {
    00396     return msa_rw_proc(p,(BYTE *)buff,buffsize,TRUE);
    00397 }
    00398 DKC_INLINE int WINAPI dkcMemoryStreamAdapterGetChar(DKC_MEMORYSTREAM_ADAPTER *p,BYTE *t)
    00399 {
    00400     /*size_t offset = p->mNowOffset;
    00401     if(dkcCheckOverflowULONG(offset,1)){
    00402         return edk_FAILED;
    00403     }
    00404     if(offset + 1 > p->mSize){
    00405         return edk_BufferOverFlow;
    00406     }
    00407     //p->mNowOffset += 1;
    00408     *t = p->mBuffer[p->mNowOffset++];
    00409     return edk_SUCCEEDED;*/
    00410     size_t rs;
    00411     return dkcMemoryStreamAdapterRead(p,t,1,&rs);
    00412 }
    00413 #endif
    00414
    00415 int WINAPI dkcMemoryStreamDump(DKC_MEMORYSTREAM *ptr,const char *filename,UINT flag){
    00416     if(flag == edkcDumpRegistBufferAll){
    00417
    00418         return dkcSaveBinary(ptr->mBuffer,ptr->mSize,filename);
    00419     }else{
    00420
    00421     }
    00422     return dkcSaveBinary(ptr->mBuffer,ptr->mNowOffset,filename);
    00423 }
    00424
    00425 int WINAPI dkcMemoryStreamWriteToMemory(const DKC_MEMORYSTREAM *ptr,void *buffer,size_t buffsize,UINT flag)
    00426 {
    00427     int r=edk_FAILED;
    00428     /*if(buffsize < ptr->mSize){
    00429         return edk_BufferOverFlow;
    00430     }   */
    00431     size_t size_temp = 0;
    00432     switch(flag){
    00433     case edkcStreamBufferAll:
    00434         r = dkc_memcpy(buffer,buffsize,ptr->mBuffer,ptr->mSize);
    00435         break;
    00436     case edkcStreamBufferToNowOffset:
    00437         r = dkc_memcpy(buffer,buffsize,ptr->mBuffer,ptr->mNowOffset);
    00438         break;
    00439     case edkcStreamBufferFirst:
    00440         if(buffsize >= ptr->mSize){//ここの条件間違って要る可能性あり
    00441             size_temp = ptr->mSize;
    00442         }else{
    00443             size_temp = buffsize;
    00444         }
    00445         r = dkc_memcpy(buffer,buffsize,ptr->mBuffer,size_temp);
    00446     default://todo:強制終了させてもOK
    00447         return edk_FAILED;
    00448     }
    00449     return r;
    00450 }
    00451
    00452 int WINAPI dkcMemoryStreamGet8(DKC_MEMORYSTREAM *ptr,BYTE *t){
    00453     size_t rs;
    00454     return dkcMemoryStreamRead(ptr,t,1,&rs);
    00455
    00456 }
    00457 int WINAPI dkcMemoryStreamPut8(DKC_MEMORYSTREAM *ptr,BYTE t){
    00458     return dkcMemoryStreamWrite(ptr,&t,1);
    00459 }
    00460 //#error メモリストリーム系全般をテスト
    00461 /*
    00462 todo:
    00463 put get 8bit系
    00464 write readバッファオーバーフローチェック
    00465  状態を元に戻すのをチェック
    00466 seek tell の統一
    00467
    00468
    00469 */
    00470
    00471
    00472
    00473 /*
    00474 @param flag[in] edkcStreamBufferAll または edkcStreamBufferFirst
    00475 */
    00476 DKC_INLINE int WINAPI dkcMemoryStreamLoadFromFile(DKC_MEMORYSTREAM *ptr,const char *filename,size_t permit_size,UINT flag)
    00477 {
    00478     size_t size;
    00479     //許容サイズよりファイルサイズが大きい条件の結果をc1に入れる
    00480     int c1 ;
    00481     int r = edk_FAILED;
    00482     size_t readsize = 0;
    00483     size_t size_temp = 0;
    00484
    00485     if(FALSE==dkcFileExist(filename))
    00486         return edk_FileNotFound;
    00487
    00488
    00489     size  = dkcFileSize(filename);
    00490     c1 = (permit_size < size);
    00491     switch(flag){
    00492     case edkcStreamBufferAll:
    00493         if(c1){
    00494             return edk_FAILED;
    00495         }
    00496         size_temp = size;
    00497         break;
    00498     case edkcStreamBufferFirst:
    00499
    00500         if(c1){
    00501             size_temp = permit_size;
    00502         }else{
    00503             size_temp = size;
    00504         }
    00505         break;
    00506     default:
    00507         return edk_ArgumentException;
    00508     }
    00509
    00510
    00511     r = dkcMemoryStreamResize(ptr,size_temp);
    00512     if(DKUTIL_FAILED(r)) goto End;
    00513
    00514     r = dkcLoadBinary(ptr->mBuffer,size_temp,filename,&readsize);
    00515
    00516     if(DKUTIL_FAILED(r)) goto End;
    00517 End:
    00518     return r;
    00519 }
    00520 DKC_INLINE int WINAPI dkcMemoryStreamLoadFromMemory(DKC_MEMORYSTREAM *ptr,
    00521                                                                                                         const void *buffer,size_t buffsize)
    00522 {//#error checkLoadFromMeory and LoadFromFile
    00523     //return load(ptr,NULL,srcsize,edkcStreamBufferAll,buffer,buffsize,FALSE);
    00524     int r;
    00525     //size_t read_size;
    00526     r = dkcMemoryStreamResize(ptr,buffsize);
    00527     if(DKUTIL_FAILED(r)) goto End;
    00528
    00529     r = dkc_memcpy(ptr->mBuffer,ptr->mSize,buffer,buffsize);
    00530
    00531     //if(DKUTIL_FAILED(r)) goto End;
    00532 End:
    00533     return r;
    00534 }