0027932: Improvement of standard attributes usability.
[occt.git] / src / Standard / Standard_GUID.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <Standard_GUID.hxx>
17 #include <Standard_IStream.hxx>
18 #include <Standard_RangeError.hxx>
19
20 #include <stdio.h>
21
22 //Fixes incorrect treatment of GUID given as a string with invalid format
23
24 //=======================================================================
25 //function : Standard_GUID_MatchChar
26 //purpose  : 
27 //=======================================================================
28 Standard_Integer Standard_GUID_MatchChar(const Standard_CString buffer, 
29                                          const Standard_Character aChar)
30 {
31   Standard_CString tmpbuffer = buffer;
32   Standard_Integer result    = -1;
33
34   while(*tmpbuffer != '\0' && *tmpbuffer != aChar) {tmpbuffer++; result++;}
35
36   if(*tmpbuffer == '\0') return -1; //The searched symbol wasn't found
37
38   if (result >= 0) result++;
39
40   return result;
41 }
42 //=======================================================================
43 //function : Standard_GUID_GetValue32
44 //purpose  : 
45 //=======================================================================
46 Standard_PCharacter Standard_GUID_GetValue32(Standard_PCharacter tmpBuffer, 
47                                              Standard_Integer& my32b) 
48 {
49   Standard_Character strtmp[Standard_GUID_SIZE_ALLOC];
50   Standard_Integer   pos = 0;
51
52   pos = Standard_GUID_MatchChar(tmpBuffer,'-');
53   if (pos >= 0) {
54     strncpy(strtmp,tmpBuffer,pos);
55     strtmp[pos] = '\0';
56     my32b = (Standard_Integer) strtoul(strtmp, (char **)NULL, 16);
57   }
58   else return NULL;
59   return &tmpBuffer[pos+1];
60 }
61 //=======================================================================
62 //function : Standard_GUID_GetValue16
63 //purpose  : 
64 //=======================================================================
65 Standard_PCharacter Standard_GUID_GetValue16(Standard_PCharacter tmpBuffer, 
66                                              Standard_ExtCharacter& my32b) 
67 {
68   Standard_Character strtmp[Standard_GUID_SIZE_ALLOC];
69   Standard_Integer   pos = 0;
70
71   pos = Standard_GUID_MatchChar(tmpBuffer,'-');
72   if (pos >= 0) {
73     strncpy(strtmp,tmpBuffer,pos);
74     strtmp[pos] = '\0';
75     my32b = (Standard_ExtCharacter) strtoul(strtmp, (char **)NULL, 16);
76   }
77   else return NULL;
78 //  cout << "V16 :" << hex(my32b) << endl;
79   return &tmpBuffer[pos+1];
80 }
81 //=======================================================================
82 //function : Standard_GUID_GetValue8
83 //purpose  : 
84 //=======================================================================
85 Standard_PCharacter Standard_GUID_GetValue8(Standard_PCharacter tmpBuffer, 
86                                             Standard_Byte& my32b) 
87 {
88   Standard_Character strtmp[Standard_GUID_SIZE_ALLOC];
89
90   strncpy(strtmp,tmpBuffer,2);
91   strtmp[2] = '\0';
92   my32b = (Standard_Byte) strtoul(strtmp, (char **)NULL, 16);
93 //  cout << "V8 :" << hex(my32b) << endl;
94   return &tmpBuffer[2];
95 }
96 //=======================================================================
97 //function : CheckGUIDFormat
98 //purpose  : 
99 //=======================================================================
100 Standard_Boolean Standard_GUID::CheckGUIDFormat(const Standard_CString aGuid)
101 {
102   Standard_Boolean result = Standard_True;
103
104   if (aGuid == NULL) return Standard_False;
105
106   if (strlen(aGuid) == Standard_GUID_SIZE) {
107     Standard_Integer i;
108
109     for (i = 0; i < 8 && result; i++) {
110       if (!IsXDigit(aGuid[i])) {
111         return Standard_False;
112       }
113     }
114
115     if (aGuid[8] != '-') return Standard_False;
116
117     for (i = 9; i < 13 && result; i++) {
118       if (!IsXDigit(aGuid[i])) {
119         return Standard_False;
120       }
121     }
122
123     if (aGuid[13] != '-') return Standard_False;
124     
125     for (i = 14; i < 18 && result; i++) {
126       if (!IsXDigit(aGuid[i])) {
127         return Standard_False;
128       }
129     }
130
131     if (aGuid[18] != '-') return Standard_False;
132
133     for (i = 19; i < 23; i++) {
134       if (!IsXDigit(aGuid[i])) {
135         return Standard_False;
136       }
137     }
138
139     if (aGuid[23] != '-') return Standard_False;
140
141     for (i = 24; i < 36; i++) {
142       if (!IsXDigit(aGuid[i])) {
143         return Standard_False;
144       }
145     }
146   }
147   else result = Standard_False;
148
149   return result;
150 }
151
152 Standard_GUID::Standard_GUID() 
153 : my32b ( 0),
154   my16b1 ( 0),
155   my16b2 ( 0),
156   my16b3 ( 0),
157   my8b1 ( 0),
158   my8b2 ( 0),
159   my8b3 ( 0),
160   my8b4 ( 0),
161   my8b5 ( 0),
162   my8b6 ( 0)
163 {
164 }
165
166 Standard_GUID::Standard_GUID(const Standard_CString aGuid) 
167 : my32b ( 0),
168   my16b1 ( 0),
169   my16b2 ( 0),
170   my16b3 ( 0),
171   my8b1 ( 0),
172   my8b2 ( 0),
173   my8b3 ( 0),
174   my8b4 ( 0),
175   my8b5 ( 0),
176   my8b6 ( 0)
177 {
178   char* tmpBuffer =(char*) aGuid;
179
180   if(!CheckGUIDFormat(tmpBuffer)) Standard_RangeError::Raise("Invalid format of GUID");
181
182   if((tmpBuffer = Standard_GUID_GetValue32(tmpBuffer,my32b)) == NULL) 
183     Standard_RangeError::Raise("Invalid format of GUID");
184   if((tmpBuffer = Standard_GUID_GetValue16(tmpBuffer,my16b1)) == NULL) 
185     Standard_RangeError::Raise("Invalid format of GUID");
186   if((tmpBuffer = Standard_GUID_GetValue16(tmpBuffer,my16b2)) == NULL) 
187     Standard_RangeError::Raise("Invalid format of GUID");
188   if((tmpBuffer = Standard_GUID_GetValue16(tmpBuffer,my16b3)) == NULL) 
189     Standard_RangeError::Raise("Invalid format of GUID");
190   tmpBuffer = Standard_GUID_GetValue8(tmpBuffer,my8b1);
191   tmpBuffer = Standard_GUID_GetValue8(tmpBuffer,my8b2);
192   tmpBuffer = Standard_GUID_GetValue8(tmpBuffer,my8b3);
193   tmpBuffer = Standard_GUID_GetValue8(tmpBuffer,my8b4);
194   tmpBuffer = Standard_GUID_GetValue8(tmpBuffer,my8b5);
195   tmpBuffer = Standard_GUID_GetValue8(tmpBuffer,my8b6);
196 }
197
198 Standard_GUID::Standard_GUID(const Standard_ExtString aGuid) 
199 : my32b ( 0),
200   my16b1 ( 0),
201   my16b2 ( 0),
202   my16b3 ( 0),
203   my8b1 ( 0),
204   my8b2 ( 0),
205   my8b3 ( 0),
206   my8b4 ( 0),
207   my8b5 ( 0),
208   my8b6 ( 0)
209
210   char tpb[Standard_GUID_SIZE_ALLOC];
211   char *tmpBuffer = tpb;
212   Standard_Integer   i = 0;
213   while(i < Standard_GUID_SIZE) {
214     tmpBuffer[i] = (char ) aGuid[i];
215     i++;
216   }
217
218   tmpBuffer[i] = '\0';
219
220   if(!CheckGUIDFormat(tmpBuffer)) Standard_RangeError::Raise("Invalid format of GUID");
221
222   if((tmpBuffer = Standard_GUID_GetValue32(tmpBuffer,my32b)) == NULL) 
223     Standard_RangeError::Raise("Invalid format of GUID");
224   if((tmpBuffer = Standard_GUID_GetValue16(tmpBuffer,my16b1)) == NULL) 
225     Standard_RangeError::Raise("Invalid format of GUID");
226   if((tmpBuffer = Standard_GUID_GetValue16(tmpBuffer,my16b2)) == NULL) 
227     Standard_RangeError::Raise("Invalid format of GUID");
228   if((tmpBuffer = Standard_GUID_GetValue16(tmpBuffer,my16b3)) == NULL) 
229     Standard_RangeError::Raise("Invalid format of GUID");
230   tmpBuffer = Standard_GUID_GetValue8(tmpBuffer,my8b1);
231   tmpBuffer = Standard_GUID_GetValue8(tmpBuffer,my8b2);
232   tmpBuffer = Standard_GUID_GetValue8(tmpBuffer,my8b3);
233   tmpBuffer = Standard_GUID_GetValue8(tmpBuffer,my8b4);
234   tmpBuffer = Standard_GUID_GetValue8(tmpBuffer,my8b5);
235   tmpBuffer = Standard_GUID_GetValue8(tmpBuffer,my8b6);
236 }
237
238 Standard_GUID::Standard_GUID(const Standard_Integer a32b,
239         const Standard_ExtCharacter a16b1,
240         const Standard_ExtCharacter a16b2,
241         const Standard_ExtCharacter a16b3,
242         const Standard_Byte a8b1,
243         const Standard_Byte a8b2,
244         const Standard_Byte a8b3,
245         const Standard_Byte a8b4,
246         const Standard_Byte a8b5,
247         const Standard_Byte a8b6)
248 {
249         my32b = a32b;
250         my16b1 = a16b1;
251          my16b2 = a16b2;
252          my16b3 = a16b3;
253          my8b1 = a8b1;
254          my8b2 = a8b2;
255          my8b3 = a8b3;
256          my8b4 = a8b4;
257          my8b5 = a8b5;
258          my8b6 = a8b6;
259 }
260
261 Standard_GUID::Standard_GUID(const Standard_GUID& aGuid)
262 {
263          my32b  = aGuid.my32b;
264          my16b1 = aGuid.my16b1;
265          my16b2 = aGuid.my16b2;
266          my16b3 = aGuid.my16b3;
267          my8b1  = aGuid.my8b1;
268          my8b2  = aGuid.my8b2;
269          my8b3  = aGuid.my8b3;
270          my8b4  = aGuid.my8b4;
271          my8b5  = aGuid.my8b5;
272          my8b6  = aGuid.my8b6;
273 }
274 Standard_GUID::Standard_GUID(const Standard_UUID& aWntGuid)
275 {
276          my32b  = aWntGuid.Data1;
277          my16b1 = aWntGuid.Data2;
278          my16b2 = aWntGuid.Data3;
279          my16b3 = (aWntGuid.Data4[0] << 8) | (aWntGuid.Data4[1]) ;
280          my8b1  = aWntGuid.Data4[2] ;
281          my8b2  = aWntGuid.Data4[3] ;
282          my8b3  = aWntGuid.Data4[4] ;
283          my8b4  = aWntGuid.Data4[5] ;
284          my8b5  = aWntGuid.Data4[6] ;
285          my8b6  = aWntGuid.Data4[7] ;
286 }
287
288 //=======================================================================
289 //function : ToCString
290 //purpose  : 
291 //=======================================================================
292 void Standard_GUID::ToCString(const Standard_PCharacter aStrGuid) const
293 {
294   sprintf(aStrGuid,"%.8x-%.4x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x",
295           my32b,
296           (unsigned short) my16b1,
297           (unsigned short) my16b2,
298           (unsigned short) my16b3,
299           (unsigned char)my8b1,
300           (unsigned char)my8b2,
301           (unsigned char)my8b3,
302           (unsigned char)my8b4,
303           (unsigned char)my8b5,
304           (unsigned char)my8b6);
305 }
306
307 //=======================================================================
308 //function : ToExtString
309 //purpose  : 
310 //=======================================================================
311 void Standard_GUID::ToExtString(const Standard_PExtCharacter aStrGuid) const
312 {
313   Standard_Character sguid[Standard_GUID_SIZE_ALLOC];
314   ToCString(sguid);
315
316   for(Standard_Integer i = 0; i < Standard_GUID_SIZE; i++) {
317     aStrGuid[i] = (Standard_ExtCharacter)sguid[i];
318   }
319
320   aStrGuid[Standard_GUID_SIZE] = (Standard_ExtCharacter)0;
321 }
322
323 Standard_UUID Standard_GUID::ToUUID() const
324 {
325   Standard_UUID result ;
326
327   result.Data1 = my32b ;
328   result.Data2 = my16b1 ;
329   result.Data3 = my16b2 ;
330   result.Data4[0] = (unsigned char)(my16b3 >> 8);
331   result.Data4[1] = (char) my16b3;
332   result.Data4[2] = my8b1 ;
333   result.Data4[3] = my8b2 ;
334   result.Data4[4] = my8b3 ;
335   result.Data4[5] = my8b4 ;
336   result.Data4[6] = my8b5 ;
337   result.Data4[7] = my8b6 ;
338   return result ;
339 }       
340
341 Standard_Boolean Standard_GUID::IsSame(const Standard_GUID& uid) const
342 {
343   Standard_Boolean result = Standard_True;
344
345   if (my32b  != uid.my32b) result = Standard_False;
346   else if (my16b1 != uid.my16b1) result = Standard_False;
347   else if (my16b2 != uid.my16b2) result = Standard_False;
348   else if (my16b3 != uid.my16b3) result = Standard_False;
349   else if (my8b1  != uid.my8b1) result = Standard_False;
350   else if (my8b2  != uid.my8b2) result = Standard_False;
351   else if (my8b3  != uid.my8b3) result = Standard_False;
352   else if (my8b4  != uid.my8b4) result = Standard_False;
353   else if (my8b5  != uid.my8b5) result = Standard_False;
354   else if (my8b6  != uid.my8b6) result = Standard_False;
355
356   return result;
357 }
358
359 Standard_Boolean Standard_GUID::IsNotSame(const Standard_GUID& uid) const
360 {
361   return !IsSame(uid);
362 }
363
364 void Standard_GUID::Assign(const Standard_GUID& uid) 
365 {
366   my32b  = uid.my32b;
367   my16b1 = uid.my16b1;
368   my16b2 = uid.my16b2;
369   my16b3 = uid.my16b3;
370   my8b1  = uid.my8b1;
371   my8b2  = uid.my8b2;
372   my8b3  = uid.my8b3;
373   my8b4  = uid.my8b4;
374   my8b5  = uid.my8b5;
375   my8b6  = uid.my8b6;
376 }
377
378 void Standard_GUID::ShallowDump(Standard_OStream& aStream) const
379 {
380   Standard_Character sguid[Standard_GUID_SIZE_ALLOC];
381   ToCString(sguid);
382   aStream << sguid;
383 }
384
385 Standard_Integer Standard_GUID::HashCode(const Standard_GUID& aGuid,const Standard_Integer Upper)
386 {
387   return aGuid.Hash(Upper);
388 }
389
390 Standard_Integer Standard_GUID::Hash(const Standard_Integer Upper) const
391 {
392   if (Upper < 1){
393     Standard_RangeError::
394       Raise("Standard_GUID::Hash: Try to apply HashCode method with negative or null argument.");
395   }
396
397   char sguid[Standard_GUID_SIZE_ALLOC];
398   ToCString(sguid);
399
400   return ::HashCode(sguid,Upper);
401 }
402
403 Standard_Boolean Standard_GUID::IsEqual(const Standard_GUID& aGuid1,const Standard_GUID& aGuid2)
404 {
405   return (aGuid1 == aGuid2);
406 }
407