OSDN Git Service

chnlib:CHNLIB_UUID(UUIDv4), メルセンヌ・ツイスターを利用した乱数生成器CHNLIB_RandomGeneratorMTを追加。
[chnosproject/CHNOSProject.git] / CHNOSProject / chn / chnlib06.c
1 //
2 //  chnlib06.c
3 //  chn
4 //
5 //  Created by 西田 耀 on 13/06/30.
6 //  Copyright (c) 2013年 Hikaru Nishida. All rights reserved.
7 //
8
9 // UUIDを格納する構造体
10
11 //
12 //Include headers
13 //
14 #include <stdio.h>
15 #include "chnlib.h"
16
17 //
18 //Define values
19 //
20
21 //
22 //Declare internal functions
23 //
24 CHNLIB_UUID *CHNLIB_UUID_Internal_Allocate(void);
25 void CHNLIB_UUID_Internal_Destruct(void **structure);
26 uint CHNLIB_UUID_Internal_GetHash(const void *structure);
27
28 //
29 //Define types
30 //
31 struct CHNLIB_UniversallyUniqueIDentifier {
32     //UUID based on RFC4122
33     //各フィールドはビッグエンディアンとして扱われるべき。
34     CHNLIB_StructureHeader header;
35     uchar time_low[4];
36     uchar time_mid[2];
37     uchar time_hi_and_version[2];
38     uchar clock_seq_hi_and_reserved[1];
39     uchar clock_seq_low[1];
40     uchar node[6];
41 };
42
43 //
44 //Functions
45 //
46
47 CHNLIB_UUID *CHNLIB_UUID_Initialise(void)
48 {
49     CHNLIB_UUID *uuid;
50     
51     uuid = CHNLIB_UUID_Internal_Allocate();
52     uuid->header.destructor = &CHNLIB_UUID_Internal_Destruct;
53     uuid->header.getHash = &CHNLIB_UUID_Internal_GetHash;
54     
55     CHNLIB_UUID_SetNullUUID(uuid);
56     
57     return uuid;
58 }
59
60 void CHNLIB_UUID_Free(CHNLIB_UUID *uuid)
61 {
62     //uuidを解放する。
63     if(CHNLIB_StructureHeader_GetTypeID(uuid) != CHNLIB_STRUCT_ID_UUID){
64         return;
65     }
66     
67     CHNLIB_UUID_SetNullUUID(uuid);
68     
69     uuid->header.typeid = CHNLIB_STRUCT_ID_Null;
70     uuid->header.signature = 0;
71     CHNLIB_System_FreeMemory(uuid, CHNLIB_DEBUG_ARGUMENTS);
72     
73     return;
74 }
75
76 void CHNLIB_UUID_Print(const CHNLIB_UUID *uuid)
77 {
78     if(CHNLIB_StructureHeader_GetTypeID(uuid) != CHNLIB_STRUCT_ID_UUID){
79         return;
80     }
81
82     printf("%02x%02x%02x%02x-", uuid->time_low[0], uuid->time_low[1], uuid->time_low[2], uuid->time_low[3]);
83     printf("%02x%02x-", uuid->time_mid[0], uuid->time_mid[1]);
84     printf("%02x%02x-", uuid->time_hi_and_version[0], uuid->time_hi_and_version[1]);
85     printf("%02x%02x-", uuid->clock_seq_hi_and_reserved[0], uuid->clock_seq_low[0]);
86     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]);
87 }
88
89 int CHNLIB_UUID_IsEqualToUUID(const CHNLIB_UUID *uuid1, const CHNLIB_UUID *uuid2)
90 {
91     int i;
92     
93     if(CHNLIB_StructureHeader_GetTypeID(uuid1) != CHNLIB_STRUCT_ID_UUID){
94         return False;
95     }
96     if(CHNLIB_StructureHeader_GetTypeID(uuid2) != CHNLIB_STRUCT_ID_UUID){
97         return False;
98     }
99     
100     for(i = 0; i < 4; i++){
101         if(uuid1->time_low[i] != uuid2->time_low[i]){
102             return False;
103         }
104     }
105     for(i = 0; i < 2; i++){
106         if(uuid1->time_mid[i] != uuid2->time_mid[i]){
107             return False;
108         }
109     }
110     for(i = 0; i < 2; i++){
111         if(uuid1->time_hi_and_version[i] != uuid2->time_hi_and_version[i]){
112             return False;
113         }
114     }
115     if(uuid1->clock_seq_hi_and_reserved[i] != uuid2->clock_seq_hi_and_reserved[i]){
116         return False;
117     }
118     if(uuid1->clock_seq_low[i] != uuid2->clock_seq_low[i]){
119         return False;
120     }
121     for(i = 0; i < 6; i++){
122         if(uuid1->node[i] != uuid2->node[i]){
123             return False;
124         }
125     }
126     return True;
127 }
128
129 void CHNLIB_UUID_SetValueAsUUIDVersion4CompatibleWithRFC4122(CHNLIB_UUID *uuid, uint random1, uint random2, uint random3, uint random4)
130 {
131     int i;
132     
133     if(CHNLIB_StructureHeader_GetTypeID(uuid) != CHNLIB_STRUCT_ID_UUID){
134         return;
135     }
136     
137     //random1
138     for(i = 0; i < 4; i++){
139         uuid->time_low[i] = ((random1 >> (i * 8)) & 0xff);
140     }
141     //random2
142     for(i = 0; i < 2; i++){
143         uuid->time_mid[i] = ((random2 >> (i * 8)) & 0xff);
144     }
145     for(i = 0; i < 2; i++){
146         uuid->time_hi_and_version[i] = ((random2 >> ((i + 2) * 8)) & 0xff);
147     }
148     //random3
149     uuid->clock_seq_hi_and_reserved[0] = ((random3 >> (1 * 8)) & 0xff);
150     uuid->clock_seq_low[0] = ((random3 >> (2 * 8)) & 0xff);
151     for(i = 0; i < 2; i++){
152         uuid->node[i] = ((random3 >> ((i + 2) * 8)) & 0xff);
153     }
154     //random4
155     for(i = 2; i < 6; i++){
156         uuid->node[i] = ((random4 >> ((i - 2) * 8)) & 0xff);
157     }
158     //Fixed field
159     uuid->clock_seq_hi_and_reserved[0] &= 0x3f;
160     uuid->clock_seq_hi_and_reserved[0] |= 0x80;
161     
162     uuid->time_hi_and_version[0] &= 0x0f;
163     uuid->time_hi_and_version[0] |= 0x40;
164     
165     return;
166 }
167
168 void CHNLIB_UUID_SetNullUUID(CHNLIB_UUID *uuid)
169 {
170     int i;
171     
172     if(CHNLIB_StructureHeader_GetTypeID(uuid) != CHNLIB_STRUCT_ID_UUID){
173         return;
174     }
175
176     for(i = 0; i < 4; i++){
177         uuid->time_low[i] = 0x00;
178     }
179     for(i = 0; i < 2; i++){
180         uuid->time_mid[i] = 0x00;
181     }
182     for(i = 0; i < 2; i++){
183         uuid->time_hi_and_version[i] = 0x00;
184     }
185     uuid->clock_seq_hi_and_reserved[0] = 0x00;
186     uuid->clock_seq_low[0] = 0x00;
187     for(i = 0; i < 6; i++){
188         uuid->node[i] = 0x00;
189     }
190     return;
191 }
192
193 CHNLIB_UUID *CHNLIB_UUID_Copy(const CHNLIB_UUID *uuidBase)
194 {
195     CHNLIB_UUID *uuidCopy;
196     
197     uuidCopy = CHNLIB_UUID_Initialise();
198     
199     int i;
200     
201     if(CHNLIB_StructureHeader_GetTypeID(uuidBase) == CHNLIB_STRUCT_ID_UUID){
202         for(i = 0; i < 4; i++){
203             uuidCopy->time_low[i] = uuidBase->time_low[i];
204         }
205         for(i = 0; i < 2; i++){
206             uuidCopy->time_mid[i] = uuidBase->time_mid[i];
207         }
208         for(i = 0; i < 2; i++){
209             uuidCopy->time_hi_and_version[i] = uuidBase->time_hi_and_version[i];
210         }
211         uuidCopy->clock_seq_hi_and_reserved[0] = uuidBase->clock_seq_hi_and_reserved[0];
212         uuidCopy->clock_seq_low[0] = uuidBase->clock_seq_low[0];
213         for(i = 0; i < 6; i++){
214             uuidCopy->node[i] = uuidBase->node[i];
215         }
216     }
217     return uuidCopy;
218
219 }
220
221 //
222 //Internal functions
223 //
224 CHNLIB_UUID *CHNLIB_UUID_Internal_Allocate(void)
225 {
226     CHNLIB_UUID *tag;
227     
228     tag = (CHNLIB_UUID *)CHNLIB_System_AllocateMemory_Strict(sizeof(CHNLIB_UUID), CHNLIB_DEBUG_ARGUMENTS);
229     
230     CHNLIB_StructureHeader_Initialize(&tag->header, CHNLIB_STRUCT_ID_UUID);
231     
232     return tag;
233 }
234
235 void CHNLIB_UUID_Internal_Destruct(void **structure)
236 {
237     //デストラクタ(実際にRelease->freeされる時に呼ばれる)
238     if(structure == NULL){
239         return;
240     }
241     
242 #ifdef DEBUG_MEMORY_REFERENCE_COUNT
243     CHNLIB_Debug("Release(with free)[%p].", CHNLIB_DEBUG_ARGUMENTS, *structure);
244 #endif
245     
246     CHNLIB_UUID_Free(*structure);
247     
248     *structure = NULL;
249     
250     return;
251 }
252
253 uint CHNLIB_UUID_Internal_GetHash(const void *structure)
254 {
255     uint hash;
256     CHNLIB_UUID *uuid;
257     
258     hash = 0;
259     
260     if(CHNLIB_StructureHeader_GetTypeID(structure) == CHNLIB_STRUCT_ID_UUID){
261         uuid = (CHNLIB_UUID *)structure;
262         hash = ((uuid->time_low[3] << 24) | (uuid->time_mid[1] << 16) | (uuid->clock_seq_low[0] << 8) | (uuid->node[5]));
263     }
264     
265     return hash;
266 }