OSDN Git Service

chnlib:CHNLIB_UUID(UUIDv4), メルセンヌ・ツイスターを利用した乱数生成器CHNLIB_RandomGeneratorMTを追加。
[chnosproject/CHNOSProject.git] / CHNOSProject / chn / chnlib06.c
diff --git a/CHNOSProject/chn/chnlib06.c b/CHNOSProject/chn/chnlib06.c
new file mode 100644 (file)
index 0000000..5177f2a
--- /dev/null
@@ -0,0 +1,266 @@
+//
+//  chnlib06.c
+//  chn
+//
+//  Created by 西田 耀 on 13/06/30.
+//  Copyright (c) 2013年 Hikaru Nishida. All rights reserved.
+//
+
+// UUIDを格納する構造体
+
+//
+//Include headers
+//
+#include <stdio.h>
+#include "chnlib.h"
+
+//
+//Define values
+//
+
+//
+//Declare internal functions
+//
+CHNLIB_UUID *CHNLIB_UUID_Internal_Allocate(void);
+void CHNLIB_UUID_Internal_Destruct(void **structure);
+uint CHNLIB_UUID_Internal_GetHash(const void *structure);
+
+//
+//Define types
+//
+struct CHNLIB_UniversallyUniqueIDentifier {
+    //UUID based on RFC4122
+    //各フィールドはビッグエンディアンとして扱われるべき。
+    CHNLIB_StructureHeader header;
+    uchar time_low[4];
+    uchar time_mid[2];
+    uchar time_hi_and_version[2];
+    uchar clock_seq_hi_and_reserved[1];
+    uchar clock_seq_low[1];
+    uchar node[6];
+};
+
+//
+//Functions
+//
+
+CHNLIB_UUID *CHNLIB_UUID_Initialise(void)
+{
+    CHNLIB_UUID *uuid;
+    
+    uuid = CHNLIB_UUID_Internal_Allocate();
+    uuid->header.destructor = &CHNLIB_UUID_Internal_Destruct;
+    uuid->header.getHash = &CHNLIB_UUID_Internal_GetHash;
+    
+    CHNLIB_UUID_SetNullUUID(uuid);
+    
+    return uuid;
+}
+
+void CHNLIB_UUID_Free(CHNLIB_UUID *uuid)
+{
+    //uuidを解放する。
+    if(CHNLIB_StructureHeader_GetTypeID(uuid) != CHNLIB_STRUCT_ID_UUID){
+        return;
+    }
+    
+    CHNLIB_UUID_SetNullUUID(uuid);
+    
+    uuid->header.typeid = CHNLIB_STRUCT_ID_Null;
+    uuid->header.signature = 0;
+    CHNLIB_System_FreeMemory(uuid, CHNLIB_DEBUG_ARGUMENTS);
+    
+    return;
+}
+
+void CHNLIB_UUID_Print(const CHNLIB_UUID *uuid)
+{
+    if(CHNLIB_StructureHeader_GetTypeID(uuid) != CHNLIB_STRUCT_ID_UUID){
+        return;
+    }
+
+    printf("%02x%02x%02x%02x-", uuid->time_low[0], uuid->time_low[1], uuid->time_low[2], uuid->time_low[3]);
+    printf("%02x%02x-", uuid->time_mid[0], uuid->time_mid[1]);
+    printf("%02x%02x-", uuid->time_hi_and_version[0], uuid->time_hi_and_version[1]);
+    printf("%02x%02x-", uuid->clock_seq_hi_and_reserved[0], uuid->clock_seq_low[0]);
+    printf("%02x%02x%02x%02x%02x%02x", uuid->node[0], uuid->node[1], uuid->node[2], uuid->node[3], uuid->node[4], uuid->node[5]);
+}
+
+int CHNLIB_UUID_IsEqualToUUID(const CHNLIB_UUID *uuid1, const CHNLIB_UUID *uuid2)
+{
+    int i;
+    
+    if(CHNLIB_StructureHeader_GetTypeID(uuid1) != CHNLIB_STRUCT_ID_UUID){
+        return False;
+    }
+    if(CHNLIB_StructureHeader_GetTypeID(uuid2) != CHNLIB_STRUCT_ID_UUID){
+        return False;
+    }
+    
+    for(i = 0; i < 4; i++){
+        if(uuid1->time_low[i] != uuid2->time_low[i]){
+            return False;
+        }
+    }
+    for(i = 0; i < 2; i++){
+        if(uuid1->time_mid[i] != uuid2->time_mid[i]){
+            return False;
+        }
+    }
+    for(i = 0; i < 2; i++){
+        if(uuid1->time_hi_and_version[i] != uuid2->time_hi_and_version[i]){
+            return False;
+        }
+    }
+    if(uuid1->clock_seq_hi_and_reserved[i] != uuid2->clock_seq_hi_and_reserved[i]){
+        return False;
+    }
+    if(uuid1->clock_seq_low[i] != uuid2->clock_seq_low[i]){
+        return False;
+    }
+    for(i = 0; i < 6; i++){
+        if(uuid1->node[i] != uuid2->node[i]){
+            return False;
+        }
+    }
+    return True;
+}
+
+void CHNLIB_UUID_SetValueAsUUIDVersion4CompatibleWithRFC4122(CHNLIB_UUID *uuid, uint random1, uint random2, uint random3, uint random4)
+{
+    int i;
+    
+    if(CHNLIB_StructureHeader_GetTypeID(uuid) != CHNLIB_STRUCT_ID_UUID){
+        return;
+    }
+    
+    //random1
+    for(i = 0; i < 4; i++){
+        uuid->time_low[i] = ((random1 >> (i * 8)) & 0xff);
+    }
+    //random2
+    for(i = 0; i < 2; i++){
+        uuid->time_mid[i] = ((random2 >> (i * 8)) & 0xff);
+    }
+    for(i = 0; i < 2; i++){
+        uuid->time_hi_and_version[i] = ((random2 >> ((i + 2) * 8)) & 0xff);
+    }
+    //random3
+    uuid->clock_seq_hi_and_reserved[0] = ((random3 >> (1 * 8)) & 0xff);
+    uuid->clock_seq_low[0] = ((random3 >> (2 * 8)) & 0xff);
+    for(i = 0; i < 2; i++){
+        uuid->node[i] = ((random3 >> ((i + 2) * 8)) & 0xff);
+    }
+    //random4
+    for(i = 2; i < 6; i++){
+        uuid->node[i] = ((random4 >> ((i - 2) * 8)) & 0xff);
+    }
+    //Fixed field
+    uuid->clock_seq_hi_and_reserved[0] &= 0x3f;
+    uuid->clock_seq_hi_and_reserved[0] |= 0x80;
+    
+    uuid->time_hi_and_version[0] &= 0x0f;
+    uuid->time_hi_and_version[0] |= 0x40;
+    
+    return;
+}
+
+void CHNLIB_UUID_SetNullUUID(CHNLIB_UUID *uuid)
+{
+    int i;
+    
+    if(CHNLIB_StructureHeader_GetTypeID(uuid) != CHNLIB_STRUCT_ID_UUID){
+        return;
+    }
+
+    for(i = 0; i < 4; i++){
+        uuid->time_low[i] = 0x00;
+    }
+    for(i = 0; i < 2; i++){
+        uuid->time_mid[i] = 0x00;
+    }
+    for(i = 0; i < 2; i++){
+        uuid->time_hi_and_version[i] = 0x00;
+    }
+    uuid->clock_seq_hi_and_reserved[0] = 0x00;
+    uuid->clock_seq_low[0] = 0x00;
+    for(i = 0; i < 6; i++){
+        uuid->node[i] = 0x00;
+    }
+    return;
+}
+
+CHNLIB_UUID *CHNLIB_UUID_Copy(const CHNLIB_UUID *uuidBase)
+{
+    CHNLIB_UUID *uuidCopy;
+    
+    uuidCopy = CHNLIB_UUID_Initialise();
+    
+    int i;
+    
+    if(CHNLIB_StructureHeader_GetTypeID(uuidBase) == CHNLIB_STRUCT_ID_UUID){
+        for(i = 0; i < 4; i++){
+            uuidCopy->time_low[i] = uuidBase->time_low[i];
+        }
+        for(i = 0; i < 2; i++){
+            uuidCopy->time_mid[i] = uuidBase->time_mid[i];
+        }
+        for(i = 0; i < 2; i++){
+            uuidCopy->time_hi_and_version[i] = uuidBase->time_hi_and_version[i];
+        }
+        uuidCopy->clock_seq_hi_and_reserved[0] = uuidBase->clock_seq_hi_and_reserved[0];
+        uuidCopy->clock_seq_low[0] = uuidBase->clock_seq_low[0];
+        for(i = 0; i < 6; i++){
+            uuidCopy->node[i] = uuidBase->node[i];
+        }
+    }
+    return uuidCopy;
+
+}
+
+//
+//Internal functions
+//
+CHNLIB_UUID *CHNLIB_UUID_Internal_Allocate(void)
+{
+    CHNLIB_UUID *tag;
+    
+    tag = (CHNLIB_UUID *)CHNLIB_System_AllocateMemory_Strict(sizeof(CHNLIB_UUID), CHNLIB_DEBUG_ARGUMENTS);
+    
+    CHNLIB_StructureHeader_Initialize(&tag->header, CHNLIB_STRUCT_ID_UUID);
+    
+    return tag;
+}
+
+void CHNLIB_UUID_Internal_Destruct(void **structure)
+{
+    //デストラクタ(実際にRelease->freeされる時に呼ばれる)
+    if(structure == NULL){
+        return;
+    }
+    
+#ifdef DEBUG_MEMORY_REFERENCE_COUNT
+    CHNLIB_Debug("Release(with free)[%p].", CHNLIB_DEBUG_ARGUMENTS, *structure);
+#endif
+    
+    CHNLIB_UUID_Free(*structure);
+    
+    *structure = NULL;
+    
+    return;
+}
+
+uint CHNLIB_UUID_Internal_GetHash(const void *structure)
+{
+    uint hash;
+    CHNLIB_UUID *uuid;
+    
+    hash = 0;
+    
+    if(CHNLIB_StructureHeader_GetTypeID(structure) == CHNLIB_STRUCT_ID_UUID){
+        uuid = (CHNLIB_UUID *)structure;
+        hash = ((uuid->time_low[3] << 24) | (uuid->time_mid[1] << 16) | (uuid->clock_seq_low[0] << 8) | (uuid->node[5]));
+    }
+    
+    return hash;
+}