OSDN Git Service

chnlib:構造体のハッシュ値取得を実装。検索の高速化に利用する予定。文字列の連結・コピーも実装。合わせてlibtestも更新。
[chnosproject/CHNOSProject.git] / CHNOSProject / chn / chnlib01.c
index 4375ef7..dbae310 100644 (file)
@@ -33,6 +33,7 @@ char *CHNLIB_String_Intenal_NullCString = "";
 \r
 CHNLIB_String *CHNLIB_String_Internal_Allocate(void);\r
 void CHNLIB_String_Internal_Destruct(void **structure);\r
+uint CHNLIB_String_Internal_GetHash(const void *structure);\r
 \r
 //\r
 //Define types\r
@@ -56,6 +57,7 @@ CHNLIB_String *CHNLIB_String_Initialize(const char str[])
     \r
     strtag = CHNLIB_String_Internal_Allocate();\r
     strtag->header.destructor = &CHNLIB_String_Internal_Destruct;\r
+    strtag->header.getHash = &CHNLIB_String_Internal_GetHash;\r
     \r
     if(str != NULL){\r
         CHNLIB_String_SetStringFromCString(strtag, str);\r
@@ -65,21 +67,22 @@ CHNLIB_String *CHNLIB_String_Initialize(const char str[])
 \r
 CHNLIB_String *CHNLIB_String_InitializeWithFormat(const char format[], ...)\r
 {\r
-    CHNLIB_String *strtag;\r
+    //CHNLIB_String *strtag;\r
     va_list ap;\r
     char str[CHNLIB_MAX_STRING_LENGTH];\r
     \r
     va_start(ap, format);\r
     vsnprintf(str, sizeof(str), format, ap);\r
     va_end(ap);\r
-    \r
+    /*\r
     strtag = CHNLIB_String_Internal_Allocate();\r
     strtag->header.destructor = &CHNLIB_String_Internal_Destruct;\r
     \r
     if(str != NULL){\r
         CHNLIB_String_SetStringFromCString(strtag, str);\r
     }\r
-    return strtag;\r
+     */\r
+    return CHNLIB_String_Initialize(str);\r
 }\r
 \r
 void CHNLIB_String_Free(CHNLIB_String *strtag)\r
@@ -162,6 +165,10 @@ CHNLIB_String *CHNLIB_String_ExtractByLength(const CHNLIB_String *strtag, int st
     char *retstr;\r
     CHNLIB_String *retstrtag;\r
     \r
+    if(strtag == NULL){\r
+        return NULL;\r
+    }\r
+    \r
     retstr = CHNLIB_CString_ExtractByLength(strtag->str, start, len);\r
     \r
     if(retstr == NULL){\r
@@ -174,6 +181,36 @@ CHNLIB_String *CHNLIB_String_ExtractByLength(const CHNLIB_String *strtag, int st
     return retstrtag;\r
 }\r
 \r
+CHNLIB_String *CHNLIB_String_Concatenate(const CHNLIB_String *s1, const CHNLIB_String *s2)\r
+{\r
+    //二つの文字列を0x00以外のバイトは全て文字と見なして連結する。\r
+    //戻り値はs1,s2の順に結合された、新たな文字列へのポインタ。\r
+    //どちらもNULLの場合はNULLポインタを、\r
+    //どちらかが文字列の場合はその文字列のコピーを新たに作成して返す。\r
+    char *retstr;\r
+    CHNLIB_String *retstrtag;\r
+    \r
+    if(s1 == NULL || s2 == NULL){\r
+        if(s1 != NULL){\r
+            return CHNLIB_String_Copy(s1);\r
+        }\r
+        if(s2 != NULL){\r
+            return CHNLIB_String_Copy(s2);\r
+        }\r
+    }\r
+    \r
+    retstr = CHNLIB_CString_Concatenate(s1->str, s2->str);\r
+    \r
+    if(retstr == NULL){\r
+        return NULL;\r
+    }\r
+    \r
+    retstrtag = CHNLIB_String_Initialize(NULL);\r
+    retstrtag->str = retstr;\r
+    \r
+    return retstrtag;\r
+}\r
+\r
 int CHNLIB_String_GetLength(const CHNLIB_String *strtag)\r
 {\r
     if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){\r
@@ -209,6 +246,27 @@ uint CHNLIB_String_GetCountOfContain(const CHNLIB_String *s, const CHNLIB_String
     return CHNLIB_UTF8_GetCountOfContain(CHNLIB_String_GetReferencePointerOfCString(s), CHNLIB_String_GetReferencePointerOfCString(search));\r
 }\r
 \r
+CHNLIB_String *CHNLIB_String_Copy(const CHNLIB_String *s)\r
+{\r
+    char *retstr;\r
+    CHNLIB_String *retstrtag;\r
+    \r
+    if(s == NULL){\r
+        return NULL;\r
+    }\r
+    \r
+    retstr = CHNLIB_CString_Copy(s->str);\r
+    \r
+    if(retstr == NULL){\r
+        return NULL;\r
+    }\r
+    \r
+    retstrtag = CHNLIB_String_Initialize(NULL);\r
+    retstrtag->str = retstr;\r
+    \r
+    return retstrtag;\r
+}\r
+\r
 //\r
 //Functions(CString(char[]))\r
 //\r
@@ -310,6 +368,7 @@ int CHNLIB_CString_CompareString(const char s[], const char search[])
     //終端文字'\0'はカウントしない。\r
     //search[]に含まれる文字(終端文字除く)がすべて入っていれば一致とみなす。\r
     //どちらかがNULLであった場合は、Falseを返す。\r
+    //一致文字数が0(search=="")だった場合もFalseを返す。\r
     int i;\r
     \r
     if(s == NULL || search == NULL){\r
@@ -324,6 +383,9 @@ int CHNLIB_CString_CompareString(const char s[], const char search[])
             return False;\r
         }\r
     }\r
+    if(i == 0){\r
+        return False;\r
+    }\r
     return True;\r
 }\r
 \r
@@ -368,6 +430,63 @@ int CHNLIB_CString_CompareString_LeftHand(const char s[], const char search[])
 \r
     return i;\r
 }\r
+\r
+char *CHNLIB_CString_Copy(const char s[])\r
+{\r
+    //与えられた文字列と等価な文字列を作成して、そのポインタを返す。\r
+    //有効な文字列が無い場合(NULLポインタも含む)、NULLを返す。\r
+    char *copyString;\r
+    int i, i_max;\r
+    \r
+    i_max = CHNLIB_CString_GetByteLength(s) + 1;\r
+    if(i_max <= 1){\r
+        return NULL;\r
+    }\r
+    \r
+    copyString = CHNLIB_System_AllocateMemory_Strict(i_max, CHNLIB_DEBUG_ARGUMENTS);\r
+    for(i = 0; i < i_max - 1; i++){\r
+        copyString[i] = s[i];\r
+    }\r
+    copyString[i] = '\0';\r
+    \r
+    return copyString;\r
+}\r
+\r
+char *CHNLIB_CString_Concatenate(const char s1[], const char s2[])\r
+{\r
+    //二つの文字列を0x00以外のバイトは全て文字と見なして連結する。\r
+    //戻り値はs1,s2の順に結合された、新たな文字列へのポインタ。\r
+    //どちらもNULLの場合はNULLポインタを、\r
+    //どちらかが文字列の場合はその文字列のコピーを新たに作成して返す。\r
+    int s1_len, s2_len, i, concatenatedSize;\r
+    char *concatenatedString;\r
+    \r
+    if(s1 == NULL || s2 == NULL){\r
+        if(s1 != NULL){\r
+            return CHNLIB_CString_Copy(s1);\r
+        }\r
+        \r
+        if(s2 != NULL){\r
+            return CHNLIB_CString_Copy(s2);\r
+        }\r
+    }\r
+    \r
+    s1_len = CHNLIB_CString_GetByteLength(s1);\r
+    s2_len = CHNLIB_CString_GetByteLength(s2);\r
+    \r
+    concatenatedSize = s1_len + s2_len + 1;\r
+    \r
+    concatenatedString = CHNLIB_System_AllocateMemory_Strict(concatenatedSize, CHNLIB_DEBUG_ARGUMENTS);\r
+    for(i = 0; i < s1_len; i++){\r
+        concatenatedString[i] = s1[i];\r
+    }\r
+    for(i = 0; i < s2_len; i++){\r
+        concatenatedString[i + s1_len] = s2[i];\r
+    }\r
+    concatenatedString[concatenatedSize - 1] = '\0';\r
+    \r
+    return concatenatedString;\r
+}\r
     \r
 //\r
 //Internal functions\r
@@ -401,3 +520,22 @@ void CHNLIB_String_Internal_Destruct(void **structure)
     \r
     return;\r
 }\r
+\r
+uint CHNLIB_String_Internal_GetHash(const void *structure)\r
+{\r
+    uint hash;\r
+    const char *p;\r
+    \r
+    hash = 0;\r
+    \r
+    if(CHNLIB_StructureHeader_GetTypeID(structure) == CHNLIB_STRUCT_ID_String){\r
+        p = ((CHNLIB_String *)structure)->str;\r
+        if(p != NULL){\r
+            for(; *p != '\0'; p++){\r
+                hash += *(unsigned char *)p;\r
+            }\r
+        }\r
+    }\r
+    \r
+    return hash;\r
+}\r