メインページ | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

dkcString.c

説明を見る。
00001 
00006 #include "dkcString.h"
00007 #include "dkcStdio.h"
00008 #include "dkcOSIndependent.h"
00009 #include <limits.h>
00010 
00011 /*
00012 // SJIS文字の1バイト目のコード
00013 extern const BYTE SJIS1_S1 = 0x81;
00014 extern const BYTE SJIS1_E1 = 0x9f;
00015 extern const BYTE SJIS1_S2 = 0xe0;
00016 extern const BYTE SJIS1_E2 = 0xf5;
00017 
00018 // SJIS文字の2バイト目のコード
00019 extern const BYTE SJIS2_S1 = 0x40;
00020 extern const BYTE SJIS2_E1 = 0x7e;
00021 extern const BYTE SJIS2_S2 = 0x80;
00022 extern const BYTE SJIS2_E2 = 0xfc;
00023 */
00024 
00025 // SJIS文字の1バイト目のコード
00026 static const BYTE SJIS1_S1 = 0x81;
00027 static const BYTE SJIS1_E1 = 0x9f;
00028 static const BYTE SJIS1_S2 = 0xe0;
00029 static const BYTE SJIS1_E2 = 0xf5;
00030 
00031 // SJIS文字の2バイト目のコード
00032 static const BYTE SJIS2_S1 = 0x40;
00033 static const BYTE SJIS2_E1 = 0x7e;
00034 static const BYTE SJIS2_S2 = 0x80;
00035 static const BYTE SJIS2_E2 = 0xfc;
00036 
00037 
00038 
00039 
00040 BOOL dkcIsSJIS1(BYTE c)
00041 {
00042   // 普通に書けばこのような感じだが、高速化する
00043   // if((c >= SJIS1_S1 && c <= SJIS1_E1) || (c >= SJIS1_S2 && c <= SJIS1_E2)) return TRUE;
00044   /*
00045     c ^= 0x20;
00046   if(c >= (SJIS1_S1 ^ 0x20) && c <= (SJIS1_E2 ^ 0x20)) return TRUE;
00047   return FALSE;
00048     */
00049     return ((c ^= 0x20) && (c >= (SJIS1_S1 ^ 0x20) && c <= (SJIS1_E2 ^ 0x20)));
00050 }
00051 
00052 BOOL dkcIsSJIS2(BYTE c)
00053 {
00054     /*if(dkcmIsSJIS2(c)) return TRUE;
00055   return FALSE;
00056     */
00057     return (c >= SJIS2_S1 && c <= SJIS2_E1) || (c >= SJIS2_S2 && c <= SJIS2_E2);
00058 }
00059 
00060 BOOL dkcIsSpace(BYTE c)
00061 {
00062     return (c=='\0' || c==0x0a || c==0x0d || c==' ' || c=='\t');
00063 }
00064 
00065 const char *dkcGetSpaceSeparator(){
00066     static const char temp[]={
00067         '\0',0x0a,0x0d,' ','\t'
00068     };
00069     return temp;
00070 }
00071 
00072 // SJIS文字を除外して文字を検索、最初に見つかった位置を返す
00073 int WINAPI dkcSJIS_StrChrSearch(const char *s, char c)
00074 {
00075   // c == 0 も考慮している
00076   int i;
00077     for(i = 0; ; i++){
00078       if(s[i] == c) return i;
00079       if(s[i] == '\0') break;
00080       if(dkcmIsSJIS1(s[i]) && dkcmIsSJIS2(s[i + 1])) i++;
00081   }
00082   return -1;
00083 } 
00084 
00085 // SJIS文字を除外して文字を検索、最後に見つかった位置を返す
00086 int WINAPI dkcSJIS_StrChrSearchLast(const char *s, char c)
00087 {
00088   int nLast = -1,i;
00089   // c == 0 も考慮している
00090   for(i = 0; ; i++){
00091     if(s[i] == c) nLast = i;
00092     if(s[i] == '\0') break;
00093     if(dkcmIsSJIS1(s[i]) && dkcmIsSJIS2(s[i + 1])) i++;
00094   }
00095   return nLast;
00096 } 
00097 
00098 int WINAPI dkcSJIS_StrChrSearchTail(const char *s,size_t len,char c){
00099     int i;
00100     for(i=len;i > 0;i--){//sjisを調べるためi > 0 iが0になったら終了。
00101         if(dkcmIsSJIS1(s[i - 1]) && dkcmIsSJIS2(s[i]) )
00102         {
00103             i--;
00104             continue;
00105         }
00106         if(s[i] == c) return i;
00107     }
00108     //iが0の時。
00109     if(! (dkcmIsSJIS1(s[i]) && dkcmIsSJIS2(s[i + 1]) ))
00110     {
00111         if(c==s[i]){
00112             return 0;
00113         }
00114     }
00115     return -1;
00116 }
00117 
00118 int WINAPI dkcSJIS_StrChrSearchInStr(const char *s,const char *c)
00119 {
00120     // c == 0 も考慮している
00121   size_t i,j;
00122     size_t len = strlen(c);
00123     for(i = 0; ; i++){
00124         if(s[i] == '\0') break;
00125         if(dkcmIsSJIS1(s[i]) && dkcmIsSJIS2(s[i + 1])){
00126             i++;
00127             continue;
00128         }
00129         for(j=0;j<len;j++){
00130       if(s[i] == c[j]) return i;
00131         }
00132   }
00133   return -1;
00134 }
00135 
00136 int WINAPI dkcSJIS_StrChrSearchInStrLast(const char *s, const char *c)
00137 {
00138   int nLast = -1;
00139     size_t i,j;
00140     size_t len = strlen(c);
00141   // c == 0 も考慮している
00142   for(i = 0; ; i++){
00143     if(s[i] == '\0') break;
00144     if(dkcmIsSJIS1(s[i]) && dkcmIsSJIS2(s[i + 1])){
00145             i++;
00146             continue;
00147         }
00148         for(j=0;j<len;j++){
00149             if(s[i] == c[j]) nLast = i;
00150         }
00151   }
00152   return nLast;
00153 } 
00154 
00155 int WINAPI dkcSJIS_SearchPathSep(const char *s)
00156 {
00157     const char *target = dkcGetPathSep();
00158     return dkcSJIS_StrChrSearchInStr(s,target);
00159 }
00160 
00161 int WINAPI dkcSJIS_SearchPathSepLast(const char *s)
00162 {
00163     const char *target = dkcGetPathSep();
00164     return dkcSJIS_StrChrSearchInStrLast(s,target);
00165 }
00166 
00167 
00168 int WINAPI dkcStrStr(const char *dest,const char *src)
00169 {
00170     char *p = strstr(dest,src);
00171     if(NULL==p) return -1;
00172     return (int)(p - dest);
00173     /*int offset = p - dest;//overflowすると危ない
00174     if(offset < 0) return -1;
00175     return offset;
00176     */
00177 }
00178 
00179 static int dkcBMStrStrLogic(const char *text,const char *pattern)
00180 {
00181     int i, j, k, len;
00182     int skip[UCHAR_MAX + 1];
00183     unsigned char c, tail;
00184 
00185     len = strlen((char *)pattern);  /* 文字列の長さ */
00186     if (len == 0) return -1;        /* エラー: 長さ0 */
00187     tail = pattern[len - 1];        /* 最後の文字 */
00188     if (len == 1) {                 /* 長さ1なら簡単! */
00189         for (i = 0; text[i] != '\0'; i++)
00190             if (text[i] == tail) return i;
00191     } else {                        // 長さ2以上なら表を作って… 
00192         for (i = 0; i <= UCHAR_MAX; i++) skip[i] = len;
00193         for (i = 0; i < len - 1; i++)
00194             skip[pattern[i]] = len - 1 - i;
00195         /* i = len - 1; */          // いよいよ照合 
00196         while ((c = text[i]) != '\0') {
00197 /*     // デモンストレーション用 
00198             printf("テ: %s\n", text);
00199             printf("照: %*s\n", i + 1, pattern);
00200 */
00201             if (c == tail) {
00202                 j = len - 1;  k = i;
00203                 while (pattern[--j] == text[--k])
00204                     if (j == 0) return k;  //見つかった 
00205             }
00206             i += skip[c];
00207         }
00208     }
00209     return -1;  // 見つからなかった 
00210 }
00211 
00212 
00213 int WINAPI dkcBMStrStr(const char *dest,const char *src)
00214 {
00215     return dkcBMStrStrLogic(dest,src);
00216 }
00217 
00218 //**********************************************************
00219 
00220 
00221 
00222 DKC_STRING * WINAPI dkcAllocString(size_t size){
00223     DKC_STRING *p;
00224     //へんな引数は除外
00225     //if(dkcErrorFlagCheck(flag)) return edk_ArgumentException;
00226     
00227     p = (DKC_STRING *)dkcAllocate(sizeof(DKC_STRING));
00228     if(NULL==p) return NULL;
00229     
00230     p->mStream = dkcAllocMemoryStream(size + 1);
00231     if(NULL==p->mStream) goto Error;
00232 
00233     p->mByteSize = 0;
00234 
00235     return p;
00236 Error:
00237     dkcFree((void **)&p);
00238     return NULL;
00239 }
00240 
00241 int WINAPI dkcFreeString(DKC_STRING **ptr){
00242     //変な引数入れるな!
00243     if(NULL==ptr || NULL==*ptr || NULL==(*ptr)->mStream){return edk_ArgumentException;}
00244     dkcFreeMemoryStream(&(*ptr)->mStream);
00245     return dkcFree(ptr);
00246 }
00247 
00248 
00249 int WINAPI dkcStringCopy(DKC_STRING *ptr,const char *str,size_t size)
00250 {
00251     dkcmNOT_ASSERT(NULL==ptr  || NULL==ptr->mStream || 0==size);
00252 
00253     if(DKUTIL_FAILED(dkcMemoryStreamSeek(ptr->mStream,0,edkcMemoryStreamSeekSet))){
00254         return edk_FAILED;
00255     }
00256 
00257     dkcMemoryStreamClear(ptr->mStream);
00258     
00259     if(DKUTIL_FAILED(dkcMemoryStreamDynamicWrite(ptr->mStream,str,
00260         size + 1/* + 1してNULL文字分もコピー*/)))
00261     {
00262         return edk_FAILED;
00263     }
00264 
00265     ptr->mByteSize = size;
00266 
00267     return edk_SUCCEEDED;
00268 }
00269 
00270 int WINAPI dkcStringConcatenate(DKC_STRING *ptr,const char *str,size_t size){
00271     dkcmNOT_ASSERT(NULL==ptr  || NULL==ptr->mStream || 0==size);
00272 
00273     if(0 != ptr->mByteSize){
00274         ptr->mStream->mNowOffset --;//一つ減らしてNULL文字分を潰す。
00275     }
00276     if(DKUTIL_FAILED(dkcMemoryStreamDynamicWrite(ptr->mStream,str,size + 1)))//+1してNULL文字もコピー
00277     {
00278         return edk_FAILED;
00279     }
00280 
00281     ptr->mByteSize += size;
00282 
00283     return edk_SUCCEEDED;
00284 }
00285 
00286 int WINAPI dkcStringInsert(DKC_STRING *ptr,size_t point,const char *str,size_t size)
00287 {
00288     size_t tpo;//一時オフセット保存
00289     char *tp;//bufferのtemp
00290     //char *mlctp;//mallocで確保したバッファのtemp
00291     //size_t len;//tpo - point
00292     //size_t maxbuffsize;//ptr->mStream->mSize - len
00293 
00294     dkcmNOT_ASSERT(NULL==ptr  || NULL==ptr->mStream);
00295     if(0==size){
00296         return edk_Not_Satisfactory;
00297     }
00298     //lock thread
00299 
00300     //ここらへんがステートマシンだから嫌^^;
00301 
00302 
00303 
00304     //エラーチェック
00305     {
00306         tpo = dkcMemoryStreamGetSeekPoint(ptr->mStream);
00307         if(point > tpo)
00308         {//pointがはみ出ている。
00309             return edk_ArgumentException;
00310         }
00311         //とりあえず、push!!
00312         dkcStringConcatenate(ptr,str,size);//これでmByteSizeは+=されている。
00313 
00314         tp = (char *)ptr->mStream->mBuffer;
00315 
00316         //一度、Concatenateしたので再取得
00317         tpo = dkcMemoryStreamGetSeekPoint(ptr->mStream);
00318 
00319         //入れ替えしてやる。
00320         dkc_stream_swap(&tp[point],tpo - point - 1,tpo - point - size - 1);
00321 
00322     }
00323     return edk_SUCCEEDED;
00324         
00325     //unlock thread
00326 
00327 
00328 
00329 }
00330 
00331 int WINAPI dkcStringErase(DKC_STRING *ptr,size_t point,size_t len)
00332 {
00333     char *tp;
00334     size_t size;
00335     int r;
00336 
00337     tp = (char *)ptr->mStream->mBuffer;
00338     size = ptr->mStream->mNowOffset;
00339     if(point + len >= size){
00340         len = size - len;
00341         dkcMemoryStreamSeek(ptr->mStream,len,edkcMemoryStreamSeekSet);
00342 
00343         return edk_Not_Satisfactory;
00344     }
00345     else
00346     {
00347         dkc_stream_swap(&tp[point],size - point - 1,len);//要らない領域を後ろに持ってくる。
00348     
00349         ptr->mByteSize -= len;//少なくする。
00350         //多分バッファオーバーフローしないと思うけど・・・。
00351         ptr->mStream->mBuffer[ptr->mByteSize] = '\0';
00352         
00353     
00354         r = dkcMemoryStreamSeek(ptr->mStream,size - len,edkcMemoryStreamSeekSet);
00355     }
00356     return r;
00357 }
00358 
00359 int WINAPI dkcStringReplace(DKC_STRING *ptr,size_t begin_,size_t end_,
00360                                                         const char *str,size_t size)
00361 {
00362     //非効率だけどこれで^^;;;;
00363     dkcStringErase(ptr,begin_,end_ - begin_);
00364     return dkcStringInsert(ptr,begin_,str,size);
00365 }
00366 
00367 
00368 
00369 size_t dkcStringSize(const DKC_STRING *ptr){
00370     return ptr->mByteSize;
00371 }
00372 
00373 size_t dkcStringNum(const DKC_STRING *ptr){
00374     return ptr->mByteSize;
00375 }
00376 
00377 const char * WINAPI dkcStringPointer(const DKC_STRING *ptr){
00378     //if(dkcErrorPtrCheck(ptr)) return edk_FAILED;
00379     return (const char *)ptr->mStream->mBuffer;
00380 }
00381 
00382 int WINAPI dkcStringGetBuffer(const DKC_STRING *ptr,char *buffer,size_t buffsize)
00383 {
00384     int r;
00385     size_t num;
00386     if(NULL==ptr) return edk_FAILED;
00387     num = dkcStringNum(ptr);
00388     r = dkc_memcpy(buffer,buffsize,ptr->mStream->mBuffer,ptr->mStream->mNowOffset);
00389     if(DKUTIL_FAILED(r)) return r;
00390     
00391     return r;
00392     //return dkcStreamToBuffer(ptr->mStream,edkcStreamSeekSet,0,num,buffer,buffsize);
00393 }
00394 
00395 
00396 int WINAPI dkcStringSerialize(const DKC_STRING *ptr,DKC_SERIALIZE *se)
00397 {
00398     int id = edkcSerializeIDString;
00399     dkcmNOT_ASSERT(NULL==ptr);
00400     dkcSerializeWrite(se,&id,sizeof(id));
00401     dkcMemoryStreamSerialize(ptr->mStream,se);
00402     return dkcSerializeWrite(se,ptr,sizeof(DKC_STRING));
00403 }
00404 
00405 DKC_STRING* WINAPI dkcAllocStringDeserialize(DKC_DESERIALIZE *se)
00406 {
00407     DKC_STRING *p;
00408     DKC_STRING t;
00409     DKC_MEMORYSTREAM *mem;
00410     size_t read;
00411     int id;
00412     
00413     dkcDeserializeRead(se,&id,sizeof(id),&read);
00414     if(id !=  edkcSerializeIDString)
00415     {
00416         return NULL;
00417     }
00418 
00419     mem = dkcAllocMemoryStreamDeserialize(se);
00420     if(NULL==mem){
00421         return NULL;
00422         }
00423 
00424     dkcDeserializeRead(se,&t,sizeof(t),&read);
00425 
00426     p = dkcAllocString(0);
00427     if(NULL==p){
00428         return NULL;
00429         }
00430     
00431     dkcFreeMemoryStream(&p->mStream);
00432     p->mByteSize = t.mByteSize;
00433     p->mStream = mem;
00434 
00435     //dkcmNOT_ASSERT(read != p->mSize);
00436     
00437     return p;
00438 
00439 }
00440 

dkutil_cに対してSun Jul 18 22:45:22 2004に生成されました。 doxygen 1.3.6