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

# dkcSJISFileSystem.c

説明を見る。

    00001
    00008 #define DKUTIL_C_SJIS_FILESYSTEM_C
    00009
    00010 #ifdef WIN32
    00011 #include <SYS/STAT.H>
    00012 #endif
    00013 #include "dkcOSIndependent.h"
    00014 #include "dkcSJISFileSystem.h"
    00015 #include "dkcStdio.h"
    00016 #include "dkcString.h"
    00017 #include "dkcThreadLock.h"
    00018 #include "dkcSingleList.h"
    00019 #include "dkcStream.h"
    00020
    00021
    00022
    00023 static DKC_INLINE BOOL jms1(int c){
    00024     return (((((unsigned char)(c))>=0x81)&&(((unsigned char)(c))<=0x9F))||((((unsigned char)(c))>=0xE0)&&(((unsigned char)(c))<=0xFC)));
    00025 }
    00026 static DKC_INLINE BOOL jms2(int c){
    00027     return ((((unsigned char)(c))!=0x7F)&&(((unsigned char)(c))>=0x40)&&(((unsigned char)(c))<=0xFC));
    00028 }
    00029
    00040 DKC_EXTERN int WINAPI dkcIsShiftJIS( const char *str, int nPos )
    00041 {
    00042     int i;
    00043     int state; // { 0, 1, 2 } = { １バイト文字, ２バイト文字の第１バイト, ２バイト文字の第２バイト }
    00044
    00045     state = 0;
    00046     for( i = 0; str[i] != '\0'; i++ )
    00047     {
    00048         if      ( ( state == 0 ) && ( jms1( str[i] ) ) ) state = 1; // 0 -> 1
    00049         else if ( ( state == 1 ) && ( jms2( str[i] ) ) ) state = 2; // 1 -> 2
    00050         else if ( ( state == 2 ) && ( jms1( str[i] ) ) ) state = 1; // 2 -> 1
    00051         else                                             state = 0; // 2 -> 0, その他
    00052
    00053         // str[nPos] での状態を返す。
    00054         if ( i == nPos ) return state;
    00055     }
    00056     return 0;
    00057 }
    00058 static DKC_INLINE int isJMS(const char *str, int nPos ){
    00059     return dkcIsShiftJIS(str,nPos);
    00060 }
    00062 static DKC_INLINE char *strtail( const char *stringg )
    00063 {
    00064     return strchr( stringg, '\0' );
    00065 }//strtail
    00066
    00071 char * WINAPI dkcGetFileExtension( const char *PathName )
    00072 {
    00073
    00074     char *p;
    00075     char *get_tail;
    00076
    00077     get_tail = strtail( PathName );
    00078     for( p = get_tail; p >= PathName; p-- ) // 文字列の最後から最初まで
    00079     {
    00080         if ( ('\\'==*p) && !isJMS(PathName,p-PathName) )
    00081             return get_tail; // ファイル名はここまで
    00082
    00083         if ( '.' == *p )
    00084             return p+1; // '.' を発見
    00085     }
    00086     return get_tail; // 拡張子なし
    00087 }//GetFileExtension
    00088
    00089
    00090 BOOL WINAPI dkcIsEffectivePath(const char *path,size_t size){
    00091     char dest[dkcdMAXPATH_BUFFER];
    00092     const size_t dsize = dkcdMAXPATH_BUFFER;
    00093
    00094     //相対パス？絶対パス？でもそのファイルが存在するか？
    00095     if(FALSE==dkcFileExist(path)){
    00096         return FALSE;
    00097     }
    00098     //pathを正規化
    00099     if(DKUTIL_FAILED(dkcToAbsolutelyPath(dest,dsize,path,size))){
    00100         return FALSE;
    00101     }
    00102     //正規化して、ファイルに使用して良い文字列を使っているか？
    00103     if(FALSE==dkcIsNativePathString(dest,strlen(dest))){
    00104         return FALSE;
    00105     }
    00106
    00107     return TRUE;
    00108 }
    00109 BOOL WINAPI dkcIsRelativityPath(const char *path)
    00110 {
    00111     int point;
    00112     dkcmNOT_ASSERT(NULL==path);
    00113     point = dkcSJIS_StrChrSearch(path,':');
    00114     if(point == -1) return TRUE;
    00115     return FALSE;
    00116 }
    00117 BOOL WINAPI dkcIsAbsolutelyPath(const char *path)
    00118 {
    00119     return !dkcIsRelativityPath(path);
    00120 }
    00121
    00123 BOOL WINAPI dkcIsTailPathSep(const char *src,size_t dlen){
    00124     int point;
    00125     point = dkcSJIS_SearchPathSepLast(src);
    00126     //if(point != -1 && (size_t)point == dlen - 1/*&& (size_t)point != dlen*/)
    00127     if((size_t)point == dlen - 1)
    00128     {   //みつかった。
    00129         return TRUE;
    00130     }
    00131     //みつからない。
    00132     return FALSE;
    00133 }
    00135 int WINAPI dkcPushBackPathSep(char *dest,size_t dlen,size_t size){
    00136     if(FALSE==dkcIsTailPathSep(dest,dlen)){
    00137         if(size < dlen + 2){
    00138             return edk_OutputBufferWasLost;//バッファが足らんよ！
    00139         }
    00140         dest[dlen ] = dkcdPATH_SEP;
    00141         dest[dlen + 1] = '\0';//こいつを忘れてはいけない。
    00142         return edk_SUCCEEDED;
    00143     }
    00144     return edk_EndProcess;
    00145 }
    00146
    00147 int WINAPI dkcDirectoryConcatenate(char *dest,size_t dlen,size_t dsize,const char *src){
    00148     //int point;
    00149     //error check
    00150     dkcmNOT_ASSERT(dlen + 2 > dsize);
    00151     if(dlen + 2 > dsize){
    00152         return edk_FAILED;
    00153     }
    00154
    00155     /*point = dkcSJIS_StrChrSearchTail(dest,dlen,dkcdPATH_SEP);
    00156     if(point != -1 && (size_t)point != dlen)
    00157     {//path separatorが見つかり、それがdestの最期に無い時
    00158         if(!dkcmIS_PATH_SEP(src[0]) )
    00159         {//path separatorで無い時
    00160             //path 区切り文字を付加してやる。
    00161             dest[dlen ] = dkcdPATH_SEP;
    00162             dest[dlen + 1] = '\0';//こいつを忘れてはいけない。
    00163         }
    00164     }*/
    00165     dkcPushBackPathSep(dest,dlen,dsize);
    00166     return dkc_strcat_amap(dest,dsize,dlen,src,strlen(src));
    00167 }
    00168
    00169 int WINAPI dkcCurrentDirectoryConcatenate(char *dest,size_t dsize,const char *src)
    00170 {
    00171     //size_t len;
    00172     //int point;
    00173
    00174     dkcmNOT_ASSERT(dsize <= dkcdMAXPATH_LEN);//<=はNULL文字も含むため。
    00175
    00176     dkcGetCurrentDirectory(dest,dsize);
    00177
    00178
    00179     return dkcDirectoryConcatenate(dest,strlen(dest),dsize,src);
    00180 }
    00181 #define MAX_PATH_CHECK(dsize) \
    00182 {\
    00183     dkcmNOT_ASSERT(dsize < dkcdMAXPATH_BUFFER);\
    00184     if(dsize < dkcdMAXPATH_BUFFER){\
    00185         return edk_BufferOverFlow;\
    00186     }\
    00187 }
    00188
    00189 static int ToAbsolutelyLogic(char *dest,size_t dsize,const char *src)
    00190 {
    00191     /*if(dsize < dkcdMAXPATH_BUFFER){//こんなバッファじゃどうなるか分からないよ＾＾；
    00192         return edk_BufferOverFlow;
    00193     }*/
    00194     MAX_PATH_CHECK(dsize);
    00195 #   ifdef WIN32
    00196
    00197     if(NULL==_fullpath(dest,src,dsize)){
    00198         return edk_FAILED;
    00199     }
    00200 #   else//unix or linux ??
    00201     if(NULL==__realpath(src,dest)){
    00202         return edk_FAILED;
    00203     }
    00204 #   endif
    00205     return edk_SUCCEEDED;
    00206 }
    00207 //パスを正規化する関数
    00208 int WINAPI dkcToAbsolutelyPath(char *dest,size_t dsize,const char *src,size_t ssize)
    00209 {
    00210     char *tp = NULL;
    00211     int r;
    00212     MAX_PATH_CHECK(dsize);
    00213
    00214
    00215     if(NULL==dest) return edk_FAILED;
    00216
    00217     if(dkcIsRelativityPath(src)==TRUE)
    00218     {//カレントディレクトリを付加する。
    00219
    00220         tp = (char *)malloc(dkcdMAXPATH_BUFFER);
    00221         if(NULL==tp) return edk_OutOfMemory;
    00222
    00223         dkcCurrentDirectoryConcatenate(tp,dkcdMAXPATH_BUFFER,src);
    00224         r =  ToAbsolutelyLogic(dest,dsize,tp);
    00225         free(tp);
    00226         return r;
    00227
    00228     }
    00229     return ToAbsolutelyLogic(dest,dsize,src);
    00230
    00231
    00232
    00233     /*
    00234     状態繊維
    00235     PATH_SEP
    00236     .
    00237     sjis
    00238
    00240     .....
    00241     ../../
    00242     /././
    00243
    00244     */
    00245         /*
    00246     size_t i,di;
    00247 //  size_t j;
    00248     int point;
    00249     //char prev;
    00250     const char *pathsep="\\/";
    00251     DKC_SINGLELIST_OBJECT *plo = NULL;
    00252     DKC_SINGLELIST *lit = NULL;
    00253
    00254
    00255     di = 0;
    00256
    00257     if(dsize < ssize){
    00258         return edk_ArgumentException;
    00259     }
    00260     //list確保
    00261     plo = dkcAllocSingleListObject(NULL,20);
    00262     if(NULL==plo) return edk_FAILED;
    00263
    00264     //directoryをパース
    00265     for(i=0;;){
    00266         point = dkcSJIS_StrChrSearchInStr(&src[i],pathsep);
    00267         if(point < 0){
    00268             if(i != ssize){
    00269                 if(FALSE==plo->push_back(plo,&src[i],size - i)){
    00270                     return edk_FAILED;
    00271                 }
    00272             }
    00273             break;
    00274         }
    00275
    00276         if(FALSE
    00277             ==plo->push_back(plo,&src[i],point - 1)//見つかったところまでだから-1
    00278             )
    00279         {
    00280             return edk_FAILED;
    00281         }
    00282
    00283         i += point;
    00284     }
    00285
    00286     for(i=0;i<ssize;){
    00287
    00288
    00289         if(dkcmIsSJIS1(src[i]) && dkcmIsSJIS2(src[i + 1]))
    00290         {//SJIS抜かし
    00291             i++;
    00292             i++;
    00293             continue;
    00294         }
    00295         // src == //
    00296         if(prev==dkcdPATH_SEP && src[i] == dkcdPATH_SEP)
    00297         {
    00298             i++;
    00299             continue;
    00300         }
    00301         // src == ..
    00302         if(prev=='.' && src[i] == '.')
    00303         {
    00304             while(src[i] != '.') i++;
    00305             if(dkcdPATH_SEP==src[i]) i++;
    00306             point = dkcSJIS_StrChrSearch(&src[i],dkcdPATH_SEP);
    00307
    00308             if(point == -1){
    00309                 break;
    00310             }
    00311             i += point;
    00312
    00313             continue;
    00314         }
    00315
    00316         dest[di] = src[i];
    00317         di++;
    00318         i++;
    00319         prev = src[i];
    00320     }
    00321
    00322
    00323     return edk_SUCCEEDED;   */
    00324 }
    00325
    00326
    00327 DKC_PATHSTRING * WINAPI dkcAllocPathString(const char *path)
    00328 {
    00329     DKC_PATHSTRING *p;
    00330     size_t len;
    00331     /*if(NULL==path){
    00332         return NULL;
    00333     }*/
    00334
    00335     p = (DKC_PATHSTRING *)dkcAllocate(sizeof(DKC_PATHSTRING));
    00336     if(NULL==p) return NULL;
    00337
    00338     p->mString = dkcAllocString(dkcdMAXPATH_BUFFER + 1);//このサイズじゃないとダメ
    00339     if(NULL==p->mString) goto Error;
    00340
    00341     //パス名をコピー
    00342     if(path){
    00343         len = strlen(path);
    00344         //ネイティブなパスを入れる。
    00345         if(FALSE==dkcIsNativePathString(path,len)){
    00346             goto Error;
    00347         }
    00348         if(DKUTIL_FAILED(dkcPathStringCopy(p,path,len))){
    00349             goto Error;
    00350         }
    00351     }
    00352     p->mIterateCount = 0;
    00353
    00354     return p;
    00355 Error:
    00356     if(p){
    00357         dkcFreeString(&p->mString);
    00358     }
    00359     dkcFree((void **)&p);
    00360     return NULL;
    00361 }
    00362
    00363 int WINAPI dkcFreePathString(DKC_PATHSTRING **ptr)
    00364 {
    00365     if(NULL==ptr || NULL==*ptr){
    00366         return edk_ArgumentException;
    00367     }
    00368     dkcFreeString(&((*ptr)->mString));
    00369     return dkcFree((void **)ptr);
    00370 }
    00371
    00372 //パスのデータを得る。
    00373 size_t WINAPI dkcPathStringSize(const DKC_PATHSTRING *p)
    00374 {
    00375     return dkcStringSize(p->mString);
    00376 }
    00377
    00378 const char *WINAPI dkcPathStringPointer(const DKC_PATHSTRING *p)
    00379 {
    00380     return dkcStringPointer(p->mString);
    00381 }
    00382
    00383
    00384 //パスを区切る。
    00385
    00386 int WINAPI dkcPathStringDevideBegin(DKC_PATHSTRING *ptr,char *buff,size_t size)
    00387 {
    00388     return dkcPathStringDevideBegin_Logic(ptr,&ptr->mIterateCount,buff,size);
    00389 }
    00390
    00391 int WINAPI dkcPathStringDevideNext(DKC_PATHSTRING *ptr,char *buff,size_t size)
    00392 {
    00393     return dkcPathStringDevideNext_Logic(ptr,&ptr->mIterateCount,buff,size);
    00394
    00395 }
    00396
    00397 void WINAPI dkcPathStringDevideEnd(DKC_PATHSTRING *ptr){
    00398     dkcPathStringDevideEnd_Logic(&ptr->mIterateCount);
    00399 }
    00400
    00401
    00402 int WINAPI dkcPathStringDevideBegin_Logic(DKC_PATHSTRING *ptr,size_t *count,char *buff,size_t size)
    00403 {
    00404     int i,point;
    00405     const char *p;
    00406     dkcmNOT_ASSERT(NULL==ptr || NULL==buff || 0==size);
    00407
    00408     //len = dkcPathStringSize(ptr);
    00409     p = dkcPathStringPointer(ptr);
    00410
    00411     point = dkcSJIS_StrChrSearch(p,'\\');
    00412     if(-1==point){return edk_EndProcess;}
    00413
    00414     for(i=0;i<point;i++){//drive指定のものがあるかどうか。
    00415         if(':'==p[i]){
    00416             if(DKUTIL_FAILED(dkc_strcpy(
    00417                 buff,size,p,(size_t)i//-1
    00418                 )))
    00419             {
    00420                 return edk_BufferOverFlow;
    00421             }
    00422             point = dkcSJIS_StrChrSearch(&p[i],'\\');//次の物を見つける。
    00423             //（まぁ:の次は\\と言う事が決まっているけど、いちおう。
    00424             *count = (size_t)i + point + 1;//次に始めるのは
    00425             return edk_SUCCEEDED;
    00426         }
    00427     }
    00428     if(DKUTIL_FAILED(dkc_strcpy(
    00429         buff,size,p,(size_t)point-1
    00430         )))
    00431     {
    00432         return edk_FAILED;
    00433     }
    00434     *count = (size_t)point + 1;//次に始めるのは
    00435     return edk_SUCCEEDED;
    00436 }
    00437
    00438 int WINAPI dkcPathStringDevideNext_Logic(DKC_PATHSTRING *ptr,size_t *count,char *buff,size_t size)
    00439 {
    00440     int point;
    00441     const char *p;
    00442     size_t len;
    00443     //len = dkcPathStringSize(ptr);
    00444     p = dkcPathStringPointer(ptr);
    00445     len = dkcStringSize(ptr->mString);
    00446     if(len <= *count)
    00447     {//もうこの関数を呼び出すのは終わりだっちゅうに！！
    00448         return edk_EndProcess;
    00449     }
    00450     point = dkcSJIS_StrChrSearch(&p[*count],'\\');
    00451     if(-1==point)
    00452     {//最後まで来ちまった。
    00453
    00454
    00455         len -= *count;
    00456         if(DKUTIL_FAILED(dkc_strcpy(//残り物を全部コピー
    00457             buff,size,&p[*count],len
    00458         )))
    00459         {
    00460             return edk_FAILED;
    00461         }
    00462         *count += len;
    00463         return edk_SUCCEEDED;//out
    00464     }
    00465     if(DKUTIL_FAILED(dkc_strcpy(
    00466         buff,size,&p[*count],(size_t)point
    00467         )))
    00468     {
    00469         return edk_FAILED;
    00470     }
    00471     *count += (size_t)point + 1;//次に始めるのは
    00472     return edk_SUCCEEDED;//out
    00473 }
    00474
    00475 void WINAPI dkcPathStringDevideEnd_Logic(size_t *count){
    00476     *count = 0;
    00477 }
    00478
    00479 int WINAPI dkcPathStringElementInsert_Logic(DKC_PATHSTRING *ptr,size_t count,
    00480                     const char *src,size_t len)
    00481 {
    00482     int r;
    00483     size_t size = len + 5;
    00484
    00485     char *p;
    00486     if(len==0 || FALSE==dkcIsNativePathString(src,len))
    00487     {
    00488         return edk_FAILED;
    00489     }
    00490     if(FALSE==dkcIsTailPathSep(src,len))//後ろにPathSeparatorが無い！！
    00491     {
    00492         p = (char *)malloc(size);
    00493
    00494         if(!p) return edk_OutOfMemory;
    00495         strcpy(p,src);//あまり使いたくないけどすでにバッファは保証されているのでstrcpy
    00496         dkcPushBackPathSep(p,len,size);
    00497
    00498         r = dkcStringInsert(ptr->mString,count,p,strlen(p));
    00499         free(p);
    00500     }else{
    00501         r = dkcStringInsert(ptr->mString,count,src,len);
    00502     }
    00503     return r;
    00504 }
    00505
    00506 int WINAPI dkcPathStringElementErase_Logic(
    00507     DKC_PATHSTRING *ptr,size_t count)
    00508 {
    00509     const char *p = dkcPathStringPointer(ptr);
    00510     int endlen = dkcSJIS_SearchPathSep(&p[count]);
    00511
    00512     if(-1==endlen){
    00513         endlen = dkcPathStringSize(ptr);
    00514         endlen = endlen - count;
    00515     }else{
    00516         //endlen;//マイナスしておく \\をReplaceしないため
    00517     }
    00518     return dkcStringErase(ptr->mString,count - 1,(size_t)endlen + 1);//count -1は前の\\を消すためendlen + 1は-1した為
    00519 }
    00520
    00521
    00522
    00523 int WINAPI dkcPathStringElementReplace_Logic(DKC_PATHSTRING *ptr,size_t count,
    00524                                                                             const char *src,size_t len)
    00525 {
    00526     const char *p = dkcPathStringPointer(ptr);
    00527     int endlen;
    00528     if(len==0 || FALSE==dkcIsNativePathString(src,len))
    00529     {
    00530         return edk_FAILED;
    00531     }
    00532     endlen = dkcSJIS_SearchPathSep(&p[count]);//countから検索している
    00533     if(-1==endlen){
    00534         endlen = dkcPathStringSize(ptr);
    00535         endlen = endlen - count;
    00536     }else{
    00537         if(0 != endlen)
    00538             endlen--;//マイナスしておく \\をReplaceしないため
    00539     }
    00540     return dkcStringReplace(ptr->mString,count,count + endlen,src,len);
    00541     /*
    00542     size_t size = len + 5;
    00543     int r;
    00544 //  int point;
    00545     const char *pointer;
    00546     char *p ;
    00547     if(FALSE==dkcIsTailPathSep(src,len))//後ろにPathSeparatorが無い！！
    00548     {
    00549         //文字列をちと変更
    00550         p = malloc(size);
    00551         if(!p) return edk_OutOfMemory;
    00552         strcpy(p,src);
    00553         r = dkcPushBackPathSep(p,len,size);
    00554     }else{
    00555         p = (char *)src;
    00556     }
    00557     pointer = dkcPathStringPointer(ptr);
    00558     //countから調べる。
    00559     dkcSJIS_SearchPathSep(&pointer[count]);
    00560     */
    00561
    00562
    00563
    00564
    00565
    00566 }
    00567
    00568
    00569
    00570
    00571
    00572 //パスを正規化して入れる。
    00573 static int dkcPathStringNormalizeCopyLogic(DKC_PATHSTRING *ptr,const char *buff,size_t size,
    00574                                                                                          int (WINAPI *function__)(DKC_STRING *,const char *,size_t))
    00575 {
    00576     //const size_t bsize = dkcdMAXPATH_BUFFER + 1;
    00577     size_t len;
    00578     int result;
    00579     //char *pb = malloc(bsize);
    00580     //if(NULL== pb) return edk_OutOfMemory;
    00581     char pb[dkcdMAXPATH_BUFFER];
    00582     size_t bsize = sizeof(pb);
    00583
    00584     result =    dkcToAbsolutelyPath(pb,bsize,buff,size);
    00585
    00586
    00587     len = strlen(pb);
    00588
    00589 #   ifdef DEBUG //ありえないよ〜エラーチェック
    00590     dkcmNOT_ASSERT(DKUTIL_FAILED(result));
    00591     dkcmNOT_ASSERT(len >= bsize);// >=にするのはNULL文字が潰されているかどうか。
    00592     dkcmNOT_ASSERT(NULL==function__);
    00593 #   endif
    00594     if(DKUTIL_FAILED(result)){
    00595         goto Error;
    00596     }
    00597     result = function__(ptr->mString,pb,len);
    00598
    00599 Error:
    00600     //if(pb){free(pb);pb=NULL;}
    00601     return result;
    00602 }
    00603 //パスを正規化して入れる。
    00604 int WINAPI dkcPathStringCopy(DKC_PATHSTRING *ptr,const char *buff,size_t size)
    00605 {
    00606
    00607     dkcmNOT_ASSERT(ptr->mString->mByteSize + size >= dkcdMAXPATH);
    00608     if(ptr->mString->mByteSize + size >= dkcdMAXPATH)
    00609     {//これ以上は入れられない。
    00610         return edk_FAILED;
    00611     }
    00612     return dkcPathStringNormalizeCopyLogic(ptr,buff,size,dkcStringCopy);
    00613 }
    00614
    00615 int WINAPI dkcPathStringNormalizeConcatenateLogic(
    00616     DKC_PATHSTRING *ptr,const char *buff,size_t size)
    00617 {
    00618     char dest[dkcdMAXPATH_BUFFER];
    00619
    00620
    00621     if(FALSE==dkcIsTailPathSep(dkcPathStringPointer(ptr),dkcPathStringSize(ptr)))
    00622     {
    00623         dkcStringConcatenate(ptr->mString,dkcdPATH_SEP_STR,1);
    00624     }
    00625     dkcStringConcatenate(ptr->mString,buff,size);
    00626
    00627     size = dkcPathStringSize(ptr) + 1;
    00628
    00629     //p = malloc(dkcPathStringSize(ptr));
    00630     //if(!p) return edk_OutOfMemory;
    00631
    00632
    00633     if(DKUTIL_FAILED(
    00634         ToAbsolutelyLogic(dest,sizeof(dest),dkcPathStringPointer(ptr))
    00635         )){
    00636         return edk_FAILED;
    00637     }
    00638
    00639     return dkcPathStringCopy(ptr,dest,strlen(dest));
    00640 }
    00641
    00642 //パスを正規化して繋げる。
    00643 int WINAPI dkcPathStringConcatenate(DKC_PATHSTRING *ptr,const char *buff,size_t size)
    00644 {
    00645     int result;
    00646
    00647     dkcmNOT_ASSERT(ptr->mString->mByteSize + size >= dkcdMAXPATH);
    00648     if(ptr->mString->mByteSize + size >= dkcdMAXPATH)
    00649     {//これ以上は入れられない。
    00650         return edk_FAILED;
    00651     }
    00652
    00653     if(ptr->mString->mByteSize)
    00654     {//すでに入っているものがある。
    00655         result = dkcPathStringNormalizeConcatenateLogic(ptr,buff,size);
    00656     }
    00657     else
    00658     {//何も無い時はこちらで
    00659         result =  dkcPathStringCopy(ptr,buff,size);
    00660     }
    00661     //return dkcPathStringNormalizeInsertLogic(ptr,buff,size,dkcStringConcatenate);
    00662     return result;
    00663 }
    00664
    00665
    00666
    00667 int WINAPI dkcPathStringGetDrive(DKC_PATHSTRING *ptr,char *buff,size_t size){
    00668     const char *p = dkcStringPointer(ptr->mString);
    00669     int point = dkcSJIS_StrChrSearch(p,':');
    00670     if(-1 == point) return edk_Not_Found;//見つからない。
    00671     //return dkc_memcpy(buff,size,p,(size_t)point - 1);
    00672     return dkc_strcpy(buff,size,p,(size_t)1);//driveなら1文字で十分だよね＾＾；
    00673 }
    00674
    00675 int WINAPI dkcPathStringGetFileExtension(DKC_PATHSTRING *ptr,char *buff,size_t size)
    00676 {
    00677     int point2;
    00678     size_t len;
    00679     const char *p = dkcStringPointer(ptr->mString);
    00680     int point = dkcSJIS_StrChrSearchLast(p,'.');
    00681
    00682     if(point < 0) return edk_Not_Found;//見つからない。
    00683
    00684     point2 = dkcSJIS_SearchPathSep(&p[point]);
    00685     if(point < point2){//C:\ok.OK\folderのような状況になっている。
    00686         return edk_Not_Found;
    00687     }
    00688     len = dkcStringSize(ptr->mString);
    00689     //if(point - 1 <= 0) return edk_FAILED;
    00690
    00691     if((size_t)(point + 1) > len) return edk_FAILED;//Logicalなエラー？？
    00692     return dkc_strcpy(buff,size,&p[point + 1],(size_t)len - (size_t)point );
    00693
    00694 }
    00695
    00696 int WINAPI dkcPathStringGetFileName(DKC_PATHSTRING *ptr,char *buff,size_t size)
    00697 {
    00698     const char *p = dkcStringPointer(ptr->mString);
    00699     //int point = dkcSJIS_StrChrSearchLast(p,dkcdPATH_SEP);
    00700     int point = dkcSJIS_SearchPathSepLast(p);
    00701     size_t len = dkcStringSize(ptr->mString);
    00702     //if(point - 1 <= 0) return edk_FAILED;
    00703 #if 0
    00704     if(point < 0) return edk_Not_Found;//見つからない。
    00705     if((size_t)(point + 1) > len) return edk_FAILED;
    00706     if((size_t)point == len) return edk_FAILED;//ファイル名が無い。
    00707
    00708 #else
    00709     printf("%d",point);
    00710
    00711     dkcmFORCE_NOT_ASSERT(NULL==p);
    00712     dkcmFORCE_NOT_ASSERT(point < 0);
    00713     dkcmFORCE_NOT_ASSERT((size_t)(point + 1) > len);
    00714     dkcmFORCE_NOT_ASSERT((size_t)point == len);
    00715
    00716 #endif
    00717     return dkc_strcpy(buff,size,&p[point + 1],(size_t)len - (size_t)point );
    00718 }
    00719
    00720 int WINAPI dkcPathStringGetDirectory(DKC_PATHSTRING *ptr,char *buff,size_t size)
    00721 {
    00722     const char *p = dkcStringPointer(ptr->mString);
    00723     int point = dkcSJIS_StrChrSearchTail(p,strlen(p),dkcdPATH_SEP);
    00724     size_t len = dkcStringSize(ptr->mString);
    00725     //if(point - 1 <= 0) return edk_FAILED;
    00726     if(point < 0) return edk_FAILED;
    00727     if((size_t)(point + 1) > len) return edk_FAILED;
    00728     //if((size_t)point == len) return edk_FAILED;//ファイル名が無い。
    00729     return dkc_strcpy(buff,size,p,point);//\\も含める。
    00730
    00731 }
    00732
    00733
    00734
    00735
    00736
    00737 BOOL WINAPI dkcFileExist(const char *filename){
    00738     struct stat s;
    00739     if(!filename) return FALSE;
    00740     //return (stat(filename,&s)==0) ? TRUE : FALSE;
    00741     return (stat(filename,&s)==0);
    00742 }
    00743
    00744 ULONG WINAPI dkcFileSize(const char *filename){
    00745     struct stat s;//s
    00746     if(!filename) return 0;
    00747   return (stat(filename,&s)==0) ? (ULONG)s.st_size : 0;
    00748 }
    00749 BOOL WINAPI dkcFileSize64(const char *str,DWORD *high,DWORD *low){
    00750 #ifdef WIN32
    00751     WIN32_FIND_DATA findData;
    00752     HANDLE hFind=NULL;
    00753     // ファイルサイズ取得
    00754     if((hFind = FindFirstFile(str,&findData)) == INVALID_HANDLE_VALUE){
    00755         return FALSE;
    00756     }
    00757
    00758     //ファイルのサイズをヴちこむ
    00759     *high = findData.nFileSizeHigh;
    00760     *low = findData.nFileSizeLow;
    00761     FindClose(hFind);
    00762     return TRUE;
    00763 #else
    00764
    00765 #endif
    00766 }
    00767
    00768
    00769 BOOL WINAPI dkcSetCurrentDirectory(const char *filename){
    00770 #ifdef DEBUG
    00771     size_t len = strlen(filename);
    00772     dkcmNOT_ASSERT(0==len || FALSE==dkcIsEffectivePath(filename,len));
    00773 #endif
    00774 #   ifdef WIN32
    00775     return(0 != SetCurrentDirectory(filename));
    00776     //return (_chdir(filename)==0);
    00777 #   else
    00778     return (chdir(filename)==0);
    00779 #   endif
    00780 }
    00781
    00782
    00783 BOOL WINAPI dkcGetCurrentDirectory(char *buff,size_t size){
    00784 #   ifdef WIN32
    00785     if(0==GetCurrentDirectory(size,buff)){
    00786         return FALSE;
    00787     }
    00788     /*if(NULL==_getcwd(path,dkcdMAXPATH_BUFFER)){
    00789         return FALSE;
    00790     }*/
    00791 #else
    00792   if(NULL==getcwd(buff,size))
    00793         return FALSE;
    00794 #endif
    00795     return TRUE;
    00796
    00797 #if 0
    00798     /* どういう実装になっているか分からないのでとりあえず+1 */
    00799     char path[dkcdMAXPATH_BUFFER + 1];
    00800     size_t len;
    00801 #   ifdef WIN32
    00802     if(0==GetCurrentDirectory(size,path)){
    00803         return FALSE;
    00804     }
    00805     /*if(NULL==_getcwd(path,dkcdMAXPATH_BUFFER)){
    00806         return FALSE;
    00807     }*/
    00808 #else
    00809   if(NULL==getcwd(path,dkcdMAXPATH_BUFFER))
    00810         return FALSE;
    00811 #endif
    00812     len = strlen(path);
    00813     return DKUTIL_SUCCEEDED(dkc_strcpy(buff,size,path,len));
    00814 #endif //end of if 0
    00815 }
    00816
    00817 static BOOL WINAPI dkcCreateDirectoryLogic(const char *dir,const void *ptr){
    00818 #ifdef WIN32
    00819      //return (0 == _mkdir( dir ));
    00820      return (0 != CreateDirectory(dir,(SECURITY_ATTRIBUTES *)ptr));
    00821 #else
    00822      return (0 == mkdir( dir ));
    00823 #endif
    00824 }
    00825
    00826
    00827
    00828 int WINAPI dkcCreateDirectory(const char *pPath)
    00829 {
    00830     BOOL result;
    00831     char work[dkcdMAXPATH_BUFFER];
    00832     unsigned long n = 0;
    00833     unsigned long len = strlen(pPath);
    00834
    00835 #ifdef WIN32//sjis support
    00836     SECURITY_ATTRIBUTES attr;
    00837
    00838     DKUTIL_STRUCTURE_INIT(attr);
    00839     NULL_CHAR_ARRAY(work);
    00840
    00841     //error check
    00842     if(dkcdMAXPATH_LEN < len){
    00843         dkcmNOT_ASSERT_MESSAGE("pathが長すぎる。",pPath);
    00844         return edk_FAILED;
    00845     }
    00846     if(0==len ){
    00847         return edk_ArgumentException;
    00848     }
    00849
    00850     //まずは一つ目を撃破
    00851     if ( dkcmIsSJIS1(pPath[n]) || ! dkcmIS_INVALID_FOLDERNAME_CHAR(pPath[n]) )
    00852     {//SJISの１文字目かINVALIDな値では無かったら。
    00853         work[n] = pPath[n];
    00854         if(1==len){
    00855             //フォルダ作成
    00856             attr.nLength = sizeof(SECURITY_ATTRIBUTES);
    00857             attr.lpSecurityDescriptor = NULL;
    00858             attr.bInheritHandle = FALSE;
    00859
    00860             result = dkcCreateDirectoryLogic( work, &attr );
    00861
    00862             dkcmNOT_ASSERT(FALSE==result && "directoryを作れなかった" );
    00863             return edk_SUCCEEDED;
    00864         }
    00865     }
    00866     n++;
    00867     //二つ目から開始
    00868     while ( n < len )
    00869     {
    00870          //フォルダ名取得
    00871         while ( n < len )
    00872         {
    00873
    00874             if(! dkcmIsSJIS1(pPath[n - 1]) && ! dkcmIsSJIS2(pPath[n]) )
    00875             {//SJISではない！！
    00876                 if ( ( dkcmIS_PATH_SEP(pPath[n]) ) /*&& pPath[n] != '\0'*//*(n != '\0')*/ )
    00877                 {
    00878                     if ( work[n-1] != ':' )
    00879                     {//driveを読み込ませたくないらしい。
    00880                         break;
    00881                     }
    00882                 }
    00883                 else if(dkcmIS_INVALID_FOLDERNAME_CHAR(pPath[n]))
    00884                 {//SJIS問題をクリアしたのに間違いだった
    00885                     return edk_FAILED;
    00886                 }
    00887             }
    00888
    00889             work[n] = pPath[n];
    00890             n++;
    00891         }
    00892         work[n] = '\0';
    00893
    00894         //フォルダ作成
    00895         attr.nLength = sizeof(SECURITY_ATTRIBUTES);
    00896         attr.lpSecurityDescriptor = NULL;
    00897         attr.bInheritHandle = FALSE;
    00898
    00899         result = dkcCreateDirectoryLogic( work, &attr );
    00900
    00901         //dkcmNOT_ASSERT("directoryを作れなかった" && FALSE==result);
    00902         if(FALSE==result){
    00903             return edk_FAILED;
    00904         }
    00905         work[n++] = dkcdPATH_SEP;
    00906     }
    00907 #else //no support sjis
    00908     NULL_CHAR_ARRAY(work);
    00909
    00910         //error check
    00911     if(dkcdMAXPATH_LEN < len){
    00912         dkcmNOT_ASSERT_MESSAGE("pathが長すぎる。",pPath);
    00913         return edk_FAILED;
    00914     }
    00915     if(0==len ){
    00916         return edk_ArgumentException;
    00917     }
    00918
    00919     while ( n < len )
    00920     {
    00921          //フォルダ名取得
    00922         while ( n < len )
    00923         {
    00924             if ( ( dkcmIS_PATH_SEP(pPath[n]) ) && (n != '\0') )
    00925             {
    00926                 if ( work[n-1] != ':' )//Linuxのドライブのパスはコレデいいのかな？
    00927                 {
    00928                     break;
    00929                 }
    00930             }
    00931             work[n] = pPath[n];
    00932             n++;
    00933         }
    00934         work[n] = '\0';
    00935
    00936         result = dkcCreateDirectoryLogic( work,NULL );
    00937
    00938         //dkcmNOT_ASSERT("directoryを作れなかった" && FALSE==result);
    00939         if(FALSE==result){
    00940             return edk_FAILED;
    00941         }
    00942         work[n++] = dkcdPATH_SEP;
    00943     }
    00944
    00945 #endif
    00946
    00947     return edk_SUCCEEDED;
    00948 }
    00949
    00950 BOOL WINAPI dkcFileCopy(const char *dest,const char *src,BOOL bReWrite){
    00951     return dkcFileCopyEx(dest,src,1024 * 64,bReWrite,FALSE,NULL,NULL);
    00952 }
    00953
    00954 BOOL WINAPI dkcFileCopyEx(const char *dest,const char *src,
    00955                                                                         size_t inner_buffer_size,BOOL bReWrite,
    00956                                                                         BOOL bThreadLock,
    00957                                                                         DKC_STD_CALLBACK pfcallback,void *parg)
    00958 {
    00959     void *buff;
    00960     FILE *srcf,*destf;
    00961     size_t filesize;//ファイルサイズ
    00962     size_t readed;//読み込んだデータ
    00963     size_t count;//count
    00964     size_t i;
    00965     size_t rest;//残り
    00966     int result = FALSE;//戻り値
    00967     DKC_THREAD_LOCK *lock = NULL;
    00968     DKC_FILECOPY_CALLBACK_STRUCT cbdata;
    00969
    00970
    00971     if(NULL==dest || NULL==src){
    00972         return FALSE;
    00973     }
    00974     if(inner_buffer_size <= 1024){
    00975         inner_buffer_size = 1024;
    00976     }
    00977
    00978     //バッファの準備
    00979     buff = malloc(inner_buffer_size);
    00980     if(NULL==buff){
    00981         inner_buffer_size = 1024 * 256;
    00982         buff = malloc(inner_buffer_size);
    00983         if(NULL==buff)
    00984             return FALSE;
    00985     }
    00986     //thread lock
    00987     if(bThreadLock){
    00988         lock = dkcAllocThreadLock();
    00989         if(NULL==lock){
    00990             goto Error;
    00991         }
    00992         dkcThreadLock_Lock(lock);
    00993     }
    00994     //ちっちゃい場合
    00995     filesize = dkcFileSize(src);
    00996     //destが存在する
    00997     if(FALSE==bReWrite && TRUE==dkcFileExist(dest)){
    00998         goto Error;
    00999     }
    01000     cbdata.filesize = filesize;
    01001     cbdata.count = 0;
    01002     for(;;)
    01003     {//non loop
    01004         if(0 == filesize)
    01005         {//ファイルサイズが０の場合
    01006             if(TRUE==dkcCreateEmptyFile(dest))
    01007             {
    01008                 result = TRUE;
    01009             }
    01010             break;
    01011         }
    01012         if(filesize < inner_buffer_size)
    01013         {//ファイルサイズがバッファに収まってしまう場合。
    01014             if(DKUTIL_FAILED(dkcLoadBinary(buff,filesize,src,&readed)))
    01015             {
    01016                 goto Error;
    01017             }
    01018 #   ifdef DEBUG
    01019             if(readed != filesize){
    01020                 ODS("readed != filesize why?\n");
    01021             }
    01022 #   endif
    01023             if(DKUTIL_SUCCEEDED(dkcSaveBinary(buff,filesize,dest)))
    01024             {
    01025                 result = TRUE;
    01026             }
    01027             break;
    01028         }
    01029         //バッファを使わなければコピーできない場合。
    01030
    01031         srcf = dkcFOpen(src,"rb");
    01032         if(NULL==srcf) goto Error;
    01033         destf = dkcFOpen(dest,"wb");
    01034         if(NULL==destf) goto Close;
    01035
    01036         //ループする回数を計算
    01037         count = filesize / inner_buffer_size;
    01038
    01039         for(i=0;i<count;i++){
    01040             dkcmFORCE_NOT_ASSERT(1 != fread(buff,inner_buffer_size,1,srcf));
    01041             dkcmFORCE_NOT_ASSERT(1 != fwrite(buff,inner_buffer_size,1,destf));
    01042
    01043             cbdata.count += inner_buffer_size;
    01044             if(pfcallback){//コールバックで相手方に伝える。
    01045                 if(FALSE==pfcallback(&cbdata,parg)){
    01046                     goto Close;
    01047                 }
    01048             }
    01049         }
    01050
    01051         rest = filesize - (count * inner_buffer_size);
    01052
    01053         //残りを出力
    01054         dkcmFORCE_NOT_ASSERT(rest != fread(buff,1,rest,srcf));
    01055         dkcmFORCE_NOT_ASSERT(rest != fwrite(buff,1,rest,destf));
    01056
    01057
    01058         cbdata.count += rest;
    01059         dkcmNOT_ASSERT(cbdata.count != cbdata.filesize);
    01060         if(pfcallback){//コールバックで相手方に伝える。
    01061             if(FALSE==pfcallback(&cbdata,parg)){
    01062                 goto Close;
    01063             }
    01064         }
    01065         result = TRUE;
    01066 Close:
    01067         //close
    01068         dkcFClose(&srcf);
    01069         dkcFClose(&destf);
    01070
    01071         break;
    01072     }//end of for
    01073
    01074
    01075
    01076
    01077 Error:
    01078     if(bThreadLock){
    01079         if(lock){
    01080             dkcThreadLock_Unlock(lock);
    01081             dkcFreeThreadLock(&lock);
    01082         }
    01083     }
    01084     if(buff){
    01085         free(buff);buff=NULL;
    01086     }
    01087     return result;
    01088 }
    01089
    01090 BOOL WINAPI dkcFileRemove(const char *filename)
    01091 {
    01092 #ifdef WIN32
    01093     return (0 != DeleteFile(filename));
    01094     //return (0==remove(filename));
    01095 #else
    01096     return (0==remove(filename));
    01097 #endif
    01098 }
    01099
    01100 BOOL WINAPI dkcFileRename(const char *oldname,const char *newname){
    01101 #ifdef WIN32
    01102     return (0==rename(oldname,newname));
    01103 #else
    01104     return (0==rename(oldname,newname));
    01105 #endif
    01106 }
    01107
    01108 BOOL WINAPI dkcCreateZeroByteFile(const char *filename,BOOL rewrite)
    01109 {
    01110     FILE *fp;
    01111     int r = FALSE;
    01112     if(FALSE==dkcFileExist(filename) || TRUE==rewrite){
    01113         fp = fopen(filename,"wb");
    01114         if(!fp){
    01115             return r;
    01116         }
    01117         fclose(fp);
    01118         r = TRUE;
    01119     }
    01120     return r;
    01121 }
    01122
    01123
    01124 int WINAPI dkcFileBinaryCompare(const char *filename1,const char *filename2)
    01125 {
    01126     BOOL r = FALSE;
    01127
    01128     //ファイルの存在を確かめる
    01129     r = dkcFileExist(filename1);
    01130     if(r==FALSE){
    01131         return edk_ArgumentException;
    01132     }
    01133     r = dkcFileExist(filename2);
    01134     if(r==FALSE){
    01135         return edk_ArgumentException;
    01136     }
    01137
    01138     //ファイルのサイズを確かめる
    01139     {
    01140         DWORD high = 0,low = 0,high2 = 0,low2 = 0;
    01141         r = dkcFileSize64(filename1,&high,&low);
    01142         if(r==FALSE){
    01143             return edk_ArgumentException;
    01144         }
    01145         r = dkcFileSize64(filename2,&high2,&low2);
    01146         if(r==FALSE){
    01147             return edk_ArgumentException;
    01148         }
    01149         r = (high==high2 && low==low2);
    01150         if(FALSE==r){//ファイルサイズが違った
    01151             return edk_FAILED;
    01152         }
    01153
    01154     }
    01155
    01156
    01157     {
    01158         DKC_STREAM *s1 = NULL,*s2=NULL;
    01159         BYTE *buffer1 = NULL,*buffer2 = NULL;
    01160         size_t buffsize = 1024 * 52;
    01161
    01162
    01163         //initialize
    01164
    01165         //ファイルをオープン
    01166         r = edk_LogicError;
    01167
    01168         s1 = dkcAllocStreamFileType(
    01169             edkcStreamDefaultEndian | edkcStreamProcessAsOrdered,
    01170             filename1,"rb");
    01171         if(NULL==s1){
    01172             return edk_LogicError;
    01173         }
    01174
    01175         s2 = dkcAllocStreamFileType(
    01176             edkcStreamDefaultEndian | edkcStreamProcessAsOrdered,
    01177             filename2,"rb");
    01178
    01179         if(NULL==s2){
    01180             goto Error;
    01181         }
    01182
    01183         //バッファを用意
    01184         r = edk_OutOfMemory;
    01185
    01186         buffer1 = malloc(buffsize);
    01187         if(NULL==buffer1){
    01188
    01189             goto Error;
    01190         }
    01191         buffer2 = malloc(buffsize);
    01192         if(NULL==buffer2){
    01193             goto Error;
    01194         }
    01195
    01196         //process
    01197
    01198         for(;;){
    01199             size_t readsize1,readsize2;
    01200             BOOL re1,re2;
    01201
    01202             dkcStreamRead(s1,buffer1,buffsize,&readsize1);
    01203             dkcStreamRead(s2,buffer2,buffsize,&readsize2);
    01204
    01205             re1 = dkcStreamError(s1);
    01206             re2 = dkcStreamError(s2);
    01207             if(re1 || re2){
    01208                 r = edk_LogicError;
    01209                 goto Error;
    01210             }
    01211
    01212
    01213             dkcmNOT_ASSERT(readsize1 != readsize2);
    01214
    01215
    01216             r = dkc_memcmp(buffer1,buffsize,buffer2,buffsize);
    01217             if(DKUTIL_FAILED(r)){
    01218                 r = edk_FAILED;
    01219                 break;
    01220             }
    01221             re1 = dkcStreamEOF(s1);
    01222             re2 = dkcStreamEOF(s2);
    01223             if(re1 && re2){
    01224                 r = edk_SUCCEEDED;
    01225                 break;
    01226             }
    01227             else if(FALSE==re1 && FALSE==re2)
    01228             {
    01229                 continue;
    01230             }
    01231             else
    01232             {
    01233                 r = edk_LogicError;
    01234                 goto Error;
    01235             }
    01236         }
    01237 Error:
    01238         if(buffer2){
    01239             free(buffer2);
    01240         }
    01241         if(buffer1){
    01242             free(buffer1);
    01243         }
    01244         dkcFreeStream(&s2);
    01245         dkcFreeStream(&s1);
    01246     }
    01247
    01248     return r;
    01249 }
    01250
    01251 int WINAPI dkcMemoryToFile(const char *filename,const void *buff,size_t size,UINT flag)
    01252 {
    01253     BOOL r;
    01254     DKC_STREAM *p;
    01255     int re = edk_FAILED;
    01256     if(!(edkcFileRewrite & flag))
    01257     {
    01258
    01259         //ファイルの存在を確かめる
    01260         r = dkcFileExist(filename);
    01261         if(r==TRUE){
    01262             return edk_ArgumentException;
    01263         }
    01264     }
    01265     p = dkcAllocStreamFileType(
    01266             edkcStreamDefaultEndian | edkcStreamProcessAsOrdered,
    01267             filename,"wb");
    01268
    01269     if(NULL==p){
    01270         return edk_FAILED;
    01271     }
    01272     if(DKUTIL_FAILED(dkcStreamWrite(p,buff,size))){
    01273         goto End;
    01274     }
    01275     re = edk_SUCCEEDED;
    01276 End:
    01277     dkcFreeStream(&p);
    01278
    01279     return re;
    01280
    01281 }
    01282
    01283
    01284 int WINAPI dkcFileToMemory(const char *filename,void *buff,size_t size)
    01285 {
    01286     DWORD h = 0,l = 0;
    01287     DKC_STREAM *p;
    01288     int r = edk_FAILED;
    01289     if(FALSE==dkcFileSize64(filename,&h,&l)){
    01290         return edk_FileNotFound;
    01291     }
    01292
    01293     if(h != 0 || ( (size_t)(l) > size ))
    01294     {//DWORD_MAX以上のサイズのファイルをメモリには読みこめないですよ^^;
    01295         return edk_BufferOverFlow;
    01296     }
    01297
    01298     p = dkcAllocStreamFileType(
    01299             edkcStreamDefaultEndian | edkcStreamProcessAsOrdered,
    01300             filename,"rb");
    01301
    01302     if(NULL==p){
    01303         return edk_FAILED;
    01304     }
    01305     if(DKUTIL_FAILED(dkcStreamRead(p,buff,l,(size_t *)&h))){
    01306         goto End;
    01307     }
    01308     if(h != l){
    01309         goto End;
    01310     }
    01311     r = edk_SUCCEEDED;
    01312 End:
    01313     dkcFreeStream(&p);
    01314     return r;
    01315 }
    01316
    01317 /*
    01318 int WINAPI dkcMemoryToTextFile(const char *filename,const void *buff,size_t size)
    01319 {
    01320
    01321
    01322
    01323 }
    01324
    01325 size_t WINAPI dkcTextFileToMemorySize(const char *filename)
    01326 {
    01327
    01328
    01329 }
    01330
    01331 int WINAPI dkcTextFileToMemory(const char *filename,void *buff,size_t size)
    01332 {
    01333
    01334
    01335 }
    01336 */
    01337
    01338 //**********************************************************
    01339
    01340
    01341 #if 0
    01342
    01343 DKC_FILE_FINDER * WINAPI dkcAllocFileFinder(
    01344             const char *target,const char *dir,BOOL bSubDir
    01345             ){
    01346
    01347     DKC_FILE_FINDER *p;
    01348     p = dkcAllocate(sizeof(DKC_FILE_FINDER));
    01349     if(NULL==p) return NULL;
    01350
    01351     //ディレクトリ
    01352     p->mDir = dkcAllocPathString(dir);//allocate and copy
    01353     if(NULL==p->mDir){
    01354         goto Error;
    01355     }
    01356     //再帰用スタック
    01357     p->mStack = dkcAllocStack(10,sizeof(DKC_PATHSTRING *));
    01358     if(NULL==p->mStack){
    01359         goto Error;
    01360     }
    01361     //target文字列
    01362     p->mTarget = dkcAllocString(128);
    01363     if(NULL==p->mTarget){
    01364         goto Error;
    01365     }
    01366     //target文字列をコピー
    01367     dkcStringCopy(p->mTarget,target,strlen(target));
    01368
    01369     p->mState = edkcFileFinderEmpty;//何もしていない。
    01370     p->mbSubDir = bSubDir;//サブdirectoryも検索するかどうか
    01371
    01372     return p;
    01373 Error:
    01374     if(p){
    01375         dkcFreeString(&(p->mTarget));
    01376         dkcFreeStack(&(p->mStack));
    01377         dkcFreePathString(&(p->mDir));
    01378     }
    01379     dkcFree((void **)&p);
    01380     return NULL;
    01381 }
    01382
    01383
    01384 int WINAPI dkcFreeFileFinder(DKC_FILE_FINDER **p){
    01385     if(NULL==p || NULL==(*p)){
    01386         return edk_ArgumentException;
    01387     }
    01388     dkcFreeString(&(*p)->mTarget);
    01389     dkcFreeStack(&(*p)->mStack);
    01390     dkcFreePathString(&(*p)->mDir);
    01391     return dkcFree((void **)p);
    01392 }
    01393
    01394 static BOOL isDot(DKC_FILE_FINDER *ptr){
    01395
    01396 #ifdef WIN32
    01397     return (
    01398         strcmp(ptr->mFindData.cFileName,"..") == 0 ||
    01399         strcmp(ptr->mFindData.cFileName,".") == 0
    01400     );
    01401 #else
    01402
    01403
    01404 #endif
    01405
    01406 }
    01407 static BOOL isFolder(DKC_FILE_FINDER *ptr){
    01408 #ifdef WIN32
    01409     return (
    01410             ptr->mFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
    01411             && strcmp(ptr->mFindData.cFileName,"..")!=0
    01412             && strcmp(ptr->mFindData.cFileName,".")!=0
    01413             );
    01414 #else
    01415
    01416
    01417 #endif
    01418 }
    01419 static int FFPushStack(DKC_FILE_FINDER *p){
    01420     DKC_PATHSTRING *tp;
    01421     int r;
    01422     char buff[dkcdMAXPATH_BUFFER];
    01423
    01424 #ifdef WIN32
    01425
    01426     dkcCurrentDirectoryConcatenate(buff,sizeof(buff),p->mFindData.cFileName);
    01427 #else
    01428     dkcCurrentDirectoryConcatenate(buff,sizeof(buff),ptr->mDirent.d_name);
    01429 #endif
    01430
    01431     tp = dkcAllocPathString(buff);
    01432     if(NULL==tp){
    01433         return edk_FAILED;
    01434     }
    01435     r = dkcStackDynamicPush(p->mStack,tp);
    01436     return r;
    01437 }
    01438
    01439 static BOOL FFIsStackEmpty(DKC_FILE_FINDER *p){
    01440     return dkcStackIsEmpty(p->mStack);
    01441 }
    01442
    01443
    01444 static int FFPopStack(DKC_FILE_FINDER *p){
    01445     int r;
    01446     DKC_PATHSTRING *tp;
    01447     r = dkcStackTop(p->mStack,&tp);
    01448     if(DKUTIL_FAILED(r)){return r;}
    01449
    01450     dkcFreePathString( &(p->mDir));
    01451     dkcStackPop(p->mStack);
    01452
    01453     p->mDir = tp;
    01454     return r;
    01455 }
    01456
    01457 static void FFReSearch(DKC_FILE_FINDER *p){
    01458     dkcFindClose(p);
    01459     FFPopStack(p);
    01460     p->mState = edkcFileFinderEmpty;
    01461     DKUTIL_STRUCTURE_INIT(p->mFindData);
    01462 }
    01463 /*
    01464 static int FFEndSearch(DKC_FILE_FINDER *p){
    01465
    01466 }
    01467 */
    01468
    01470 static int ReflexiveSearch(DKC_FILE_FINDER *p,DKC_PATHSTRING *path,BOOL *bCopySucceeded)
    01471 {
    01472
    01473 }
    01474 /*static int FFCheckingLogic(DKC_FILE_FINDER *p,DKC_PATHSTRING *path,BOOL *bCopySucceeded)
    01475 {*/
    01476 #define FFCHECKING(p,path,bCopySucceeded)\
    01477     if(TRUE==isDot(p))\
    01478     {/*こんなのじゃ文字列はいただけないなぁ。*/\
    01479         p->mState = edkcFileFinderSearching;\
    01480         return WithFolderSearch(p,path,bCopySucceeded);\
    01481     }\
    01482     if(TRUE==isFolder(p))\
    01483     {/*おや？フォルダーだ。*/\
    01484         dkcFileFinderReferenceFileName(p,path);\
    01485         p->mState = edkcFileFinderSearching;\
    01486         FFPushStack(p);/*folderをスタックに詰める。*/\
    01487         return WithFolderSearch(p,path,bCopySucceeded);\
    01488     }
    01489 /*}*/
    01490
    01491 static int WithFolderSearch(DKC_FILE_FINDER *p,DKC_PATHSTRING *path,BOOL *bCopySucceeded)
    01492 {
    01493     int r;
    01494 //  DKC_PATHSTRING *pps = NULL;
    01495 //  DKC_FILE_FINDER *
    01496
    01497     r = 0;
    01498     *bCopySucceeded = FALSE;
    01499
    01500     if(edkcFileFinderEmpty == p->mState)
    01501     {//呼び出して最初だったら、
    01502         r = dkcFindFirstFile(p);
    01503         if(DKUTIL_FAILED(r)) return edk_FAILED;
    01504 #   ifdef WIN32 //windowsの場合は内部に格納している･･･。
    01505         if(TRUE==isDot(p))
    01506         {//こんなのじゃ文字列はいただけないなぁ。
    01507             p->mState = edkcFileFinderSearching;
    01508             return WithFolderSearch(p,path,bCopySucceeded);
    01509         }
    01510         if(TRUE==isFolder(p))
    01511         {//おや？フォルダーだ。
    01512             dkcFileFinderReferenceFileName(p,path);
    01513             p->mState = edkcFileFinderSearching;
    01514             FFPushStack(p);//folderをスタックに詰める。
    01515             return WithFolderSearch(p,path,bCopySucceeded);
    01516         }
    01517         //FFCHECKING(p,path,bCopySucceeded)
    01518
    01519         r = dkcFileFinderReferenceFileName(p,path);
    01520
    01521         if(DKUTIL_SUCCEEDED(r)){//コピーも成功
    01522             *bCopySucceeded = TRUE;
    01523         }
    01524 #   endif
    01525         p->mState = edkcFileFinderSearching;
    01526         return r;
    01527     }else if(edkcFileFinderSearching == p->mState)
    01528     {//検索中だったら。
    01529         r = dkcFindNextFile(p);
    01530         if(edk_SUCCEEDED == r)
    01531         {//成功だ。
    01532             if(TRUE==isDot(p))
    01533             {//こんなのじゃ文字列はいただけないなぁ。
    01534                 p->mState = edkcFileFinderSearching;
    01535                 return WithFolderSearch(p,path,bCopySucceeded);
    01536             }
    01537             if(TRUE==isFolder(p))
    01538             {//おや？フォルダーだ。
    01539                 dkcFileFinderReferenceFileName(p,path);
    01540                 p->mState = edkcFileFinderSearching;
    01541                 FFPushStack(p);//folderをスタックに詰める。
    01542                 return WithFolderSearch(p,path,bCopySucceeded);
    01543             }
    01544
    01545             r = dkcFileFinderReferenceFileName(p,path);
    01546
    01547             if(DKUTIL_SUCCEEDED(r)){//コピーも成功
    01548                 *bCopySucceeded = TRUE;
    01549             }/*else{//コピー失敗！？？
    01550                 *bCopySucceeded = FALSE;
    01551             }*/
    01552         }else if(edk_EndProcess == r)
    01553         {//検索が終わった。
    01554             if(FALSE==FFIsStackEmpty(p))
    01555             {//空ではない。
    01556                 FFReSearch(p);
    01557                 return WithFolderSearch(p,path,bCopySucceeded);
    01558             }else{
    01559                 dkcFindClose(p);//終了ナリ。（内部でp->mState = edkcFileFinderFinish;をやっている。
    01560             }
    01561         }else{
    01562             dkcmNOT_ASSERT("そんなばかな〜");
    01563         }
    01564         return r;
    01565     }else if(edkcFileFinderFinish == p->mState)
    01566     {
    01567         return edk_EndProcess;
    01568     }
    01569     dkcmNOT_ASSERT("dkcFileFinderNextのプログラムがおかしい。チートされているかも！？");
    01570     return edk_FAILED;
    01571
    01572 }
    01573
    01574
    01575 static int NormalSearch(DKC_FILE_FINDER *p,DKC_PATHSTRING *path,BOOL *bCopySucceeded)
    01576 {
    01577     int r;
    01578     r = 0;
    01579     *bCopySucceeded = FALSE;
    01580
    01581     if(edkcFileFinderEmpty == p->mState)
    01582     {//呼び出して最初だったら、
    01583         r = dkcFindFirstFile(p);
    01584         if(DKUTIL_FAILED(r)) return edk_FAILED;
    01585 #   ifdef WIN32 //windowsの場合は内部に格納している･･･。
    01586         if(TRUE==isDot(p) || TRUE==isFolder(p))
    01587         {//こんなのじゃ文字列はいただけないなぁ。
    01588             p->mState = edkcFileFinderSearching;
    01589             return NormalSearch(p,path,bCopySucceeded);
    01590         }
    01591         r = dkcFileFinderReferenceFileName(p,path);
    01592
    01593         if(DKUTIL_SUCCEEDED(r)){//コピーも成功
    01594             *bCopySucceeded = TRUE;
    01595         }
    01596 #   endif
    01597         p->mState = edkcFileFinderSearching;
    01598         return r;
    01599     }else if(edkcFileFinderSearching == p->mState)
    01600     {//検索中だったら。
    01601         r = dkcFindNextFile(p);
    01602         if(edk_SUCCEEDED == r)
    01603         {//成功だ。
    01604             if(TRUE==isDot(p) || TRUE==isFolder(p))
    01605             {//こんなのじゃ文字列はいただけないなぁ。
    01606
    01607
    01608
    01609                 //p->mState = edkcFileFinderSearching;
    01610                 return NormalSearch(p,path,bCopySucceeded);
    01611             }
    01612             r = dkcFileFinderReferenceFileName(p,path);
    01613
    01614             if(DKUTIL_SUCCEEDED(r)){//コピーも成功
    01615                 *bCopySucceeded = TRUE;
    01616             }/*else{//コピー失敗！？？
    01617                 *bCopySucceeded = FALSE;
    01618             }*/
    01619         }else if(edk_EndProcess == r)
    01620         {//検索が終わった。
    01621             dkcFindClose(p);//終了ナリ。（内部でp->mState = edkcFileFinderFinish;をやっている。
    01622         }else{
    01623             dkcmNOT_ASSERT("そんなばかな〜");
    01624         }
    01625         return r;
    01626     }else if(edkcFileFinderFinish == p->mState)
    01627     {
    01628         return edk_EndProcess;
    01629     }/*else{
    01630         return edk_FAILED;
    01631     }*/
    01632     dkcmNOT_ASSERT("dkcFileFinderNextのプログラムがおかしい。チートされているかも！？");
    01633     return edk_FAILED;
    01634
    01635 }
    01636
    01642 int WINAPI dkcFileFinderNext(DKC_FILE_FINDER *p,DKC_PATHSTRING *path,BOOL *bCopySucceeded)
    01643 {
    01644     if(FALSE==p->mbSubDir){
    01645         return NormalSearch(p,path,bCopySucceeded);
    01646     }else{//sub directoryも検索
    01647         return WithFolderSearch(p,path,bCopySucceeded);
    01648     }
    01649     //return ReflexiveSearch(p,path,bCopySucceeded);
    01650 }
    01651 #endif
    01652
    01653 DKC_FINDFILE *WINAPI dkcAllocFindFile()
    01654 {
    01655     DKC_FINDFILE *p;
    01656     p = (DKC_FINDFILE *)dkcAllocate(sizeof(DKC_FINDFILE));
    01657     return p;
    01658 }
    01659 int WINAPI dkcFreeFindFile(DKC_FINDFILE **ptr){
    01660     if(NULL==ptr /*|| *ptr==NULL*/){
    01661         return edk_FAILED;
    01662     }
    01663     return dkcFree((void **)ptr);
    01664 }
    01665
    01666
    01667 int WINAPI dkcFindFirstFile(DKC_FINDFILE *ptr,const char *target){
    01668 #ifdef WIN32
    01669     ptr->mHandle =
    01670         FindFirstFileA( target, &(ptr->mFindData) );
    01671     if(ptr->mHandle == INVALID_HANDLE_VALUE){
    01672         return edk_FAILED;
    01673     }
    01674 #else
    01675     ptr->mHandle = opendir( target );
    01676     if(NULL==ptr->mHandle){
    01677         return edk_FAILED;
    01678     }
    01679
    01680 #endif
    01681     return edk_SUCCEEDED;
    01682 }
    01683
    01684 int WINAPI dkcFindNextFile(DKC_FINDFILE *ptr){
    01685 #   ifdef WIN32
    01686     if ( 0 == FindNextFileA( ptr->mHandle, &(ptr->mFindData) ))
    01687     {
    01688         if ( GetLastError() == ERROR_NO_MORE_FILES )
    01689         {//なんだ、もう無いじゃん。
    01690             return edk_EndProcess;
    01691         }
    01692         else//最悪のパターン
    01693         {
    01694             return edk_FAILED;
    01695         }
    01696     }
    01697 #   else
    01698   errno = 0;
    01699     ptr->mDirent = readdir( ptr->mHandle );
    01700   if ( ptr->mDirent == 0 )
    01701   {
    01702     if ( errno == 0 )
    01703     {//もう無いよ＾＾；
    01704             return edk_EndProcess;
    01705     }
    01706         else//最悪のパターン
    01707         {
    01708             return edk_FAILED;
    01709         }
    01710   }
    01711 #   endif
    01712     return edk_SUCCEEDED;
    01713 }
    01714
    01715 int WINAPI dkcFindClose(DKC_FINDFILE *ptr)
    01716 {
    01717 #ifdef WIN32
    01718     if(INVALID_HANDLE_VALUE == ptr->mHandle){
    01719         return edk_FAILED;
    01720     }
    01721     FindClose(ptr->mHandle);
    01722     ptr->mHandle = INVALID_HANDLE_VALUE;//しっかりリセット
    01723 #else
    01724     if(0 == ptr->mHandle){
    01725         return edk_FAILED;
    01726     }
    01727     closedir(ptr->mHandle);
    01728     ptr->mHandle = 0;//しっかりリセット
    01729     ptr->mDirent = NULL;
    01730 #endif
    01731
    01732     return edk_SUCCEEDED;
    01733
    01734 }
    01735
    01736 int WINAPI dkcFindFileGetFileName(DKC_FINDFILE *ptr,char *buff,size_t buffsize)
    01737 {
    01738     int r;
    01739     size_t len;
    01740 #ifdef WIN32
    01741     len = strlen(ptr->mFindData.cFileName);
    01742     if(0 == len) return edk_FAILED;
    01743     r = dkc_strcpy(buff,buffsize,ptr->mFindData.cFileName,len);
    01744 #else
    01745     if(NULL==ptr->mDirent)
    01746     {//呼び出しが間違っているよ＾＾；
    01747         return edk_LogicError;
    01748     }
    01749     len = strlen(ptr->mDirent.d_name);
    01750     if(0 == len) return edk_FAILED;
    01751     r = dkc_strcpy(buff,buffsize,ptr->mDirent.d_name,len);
    01752 #endif
    01753     return r;
    01754 }
    01755
    01756 BOOL WINAPI dkcFindFileIsFolder(DKC_FINDFILE *ptr){
    01757
    01758
    01759 #ifdef WIN32
    01760     return (
    01761             ptr->mFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
    01762             && strcmp(ptr->mFindData.cFileName,"..")!=0
    01763             && strcmp(ptr->mFindData.cFileName,".")!=0
    01764             );
    01765 #else
    01766
    01767
    01768 #endif
    01769 }
    01770
    01771
    01772 BOOL WINAPI dkcFindFileIsDot(DKC_FINDFILE *ptr){
    01773 #ifdef WIN32
    01774     return (
    01775         strcmp(ptr->mFindData.cFileName,"..") == 0 ||
    01776         strcmp(ptr->mFindData.cFileName,".") == 0
    01777     );
    01778 #else
    01779
    01780
    01781 #endif
    01782 }
    01783
    01784 BOOL WINAPI dkcFindFileIsNormalFile(DKC_FINDFILE *ptr)
    01785 {
    01786 #ifdef WIN32
    01787     return (ptr->mFindData.dwFileAttributes & FILE_ATTRIBUTE_NORMAL);
    01788 #else
    01789
    01790 #endif
    01791 }
    01792
    01793 BOOL WINAPI dkcFindFileIsReadOnly(DKC_FINDFILE *ptr){
    01794 #ifdef WIN32
    01795     return (ptr->mFindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY);
    01796 #else
    01797
    01798 #endif
    01799 }
    01800 void WINAPI dkcFindFileSize(DKC_FINDFILE *ptr,ULONG *High,ULONG *Low){
    01801 #ifdef WIN32
    01802     *High = ptr->mFindData.nFileSizeHigh;
    01803     *Low = ptr->mFindData.nFileSizeLow;
    01804 #else
    01805
    01806 #endif
    01807
    01808 }
    01809 /*
    01810 int WINAPI dkcFindFirstFile(DKC_FILE_FINDER *ptr){
    01811
    01812 #ifdef WIN32
    01813     ptr->mHandle =
    01814         FindFirstFileA( dkcPathStringPointer(ptr->mDir), &(ptr->mFindData) );
    01815     if(ptr->mHandle == INVALID_HANDLE_VALUE){
    01816         return edk_FAILED;
    01817     }
    01818 #else
    01819     ptr->mHandle = opendir( dkcPathStringPointer(ptr->mDir) );
    01820     if(NULL==ptr->mHandle){
    01821         return edk_FAILED;
    01822     }
    01823
    01824 #endif
    01825     return edk_SUCCEEDED;
    01826 }
    01827
    01828 int WINAPI dkcFindNextFile(DKC_FILE_FINDER *ptr)
    01829 {
    01830     if(edkcFileFinderFinish == ptr->mState){
    01831         return edk_LogicError;//呼び出しが間違っているナリ！
    01832     }
    01833 #   ifdef WIN32
    01834     if ( 0 == FindNextFileA( ptr->mHandle, &(ptr->mFindData) ))
    01835     {
    01836         if ( GetLastError() == ERROR_NO_MORE_FILES )
    01837         {//なんだ、もう無いじゃん。
    01838             return edk_EndProcess;
    01839         }
    01840         else//最悪のパターン
    01841         {
    01842             return edk_FAILED;
    01843         }
    01844     }
    01845 #   else
    01846   errno = 0;
    01847     ptr->mDirent = readdir( ptr->mHandle );
    01848   if ( ptr->mDirent == 0 )
    01849   {
    01850     if ( errno == 0 )
    01851     {//もう無いよ＾＾；
    01852             return edk_EndProcess;
    01853     }
    01854         else//最悪のパターン
    01855         {
    01856             return edk_FAILED;
    01857         }
    01858   }
    01859 #   endif
    01860     return edk_SUCCEEDED;
    01861 }
    01862
    01863 int WINAPI dkcFindClose(DKC_FILE_FINDER *ptr){
    01864 #ifdef WIN32
    01865     if(INVALID_HANDLE_VALUE == ptr->mHandle){
    01866         return edk_FAILED;
    01867     }
    01868     FindClose(ptr->mHandle);
    01869     ptr->mHandle = INVALID_HANDLE_VALUE;//しっかりリセット
    01870 #else
    01871     if(0 == ptr->mHandle){
    01872         return edk_FAILED;
    01873     }
    01874     closedir(ptr->mHandle);
    01875     ptr->mHandle = 0;//しっかりリセット
    01876     ptr->mDirent = NULL;
    01877 #endif
    01878     //終了！！
    01879     ptr->mState = edkcFileFinderFinish;
    01880
    01881     return edk_SUCCEEDED;
    01882 }
    01883
    01884
    01885 int WINAPI dkcFileFinderReferenceFileName(DKC_FILE_FINDER *ptr,DKC_PATHSTRING *path)
    01886 {
    01887     int r;
    01888     size_t len;
    01889 #ifdef WIN32
    01890     len = strlen(ptr->mFindData.cFileName);
    01891     if(0 == len) return edk_FAILED;
    01892     r = dkcPathStringCopy(path,ptr->mFindData.cFileName,len);
    01893 #else
    01894     if(NULL==ptr->mDirent)
    01895     {//呼び出しが間違っているよ＾＾；
    01896         return edk_LogicError;
    01897     }
    01898     len = strlen(ptr->mDirent.d_name);
    01899     if(0 == len) return edk_FAILED;
    01900     r = dkcPathStringCopy(path,ptr->mDirent.d_name,len);
    01901 #endif
    01902     return r;
    01903 }
    01904 */