1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "nsID.h"
8 #include "nsMemory.h"
9 #include "mozilla/Sprintf.h"
10
Clear()11 void nsID::Clear()
12 {
13 m0 = 0;
14 m1 = 0;
15 m2 = 0;
16 for (int i = 0; i < 8; ++i) {
17 m3[i] = 0;
18 }
19 }
20
21 /**
22 * Multiplies the_int_var with 16 (0x10) and adds the value of the
23 * hexadecimal digit the_char. If it fails it returns false from
24 * the function it's used in.
25 */
26
27 #define ADD_HEX_CHAR_TO_INT_OR_RETURN_FALSE(the_char, the_int_var) \
28 the_int_var = (the_int_var << 4) + the_char; \
29 if(the_char >= '0' && the_char <= '9') the_int_var -= '0'; \
30 else if(the_char >= 'a' && the_char <= 'f') the_int_var -= 'a'-10; \
31 else if(the_char >= 'A' && the_char <= 'F') the_int_var -= 'A'-10; \
32 else return false
33
34
35 /**
36 * Parses number_of_chars characters from the char_pointer pointer and
37 * puts the number in the dest_variable. The pointer is moved to point
38 * at the first character after the parsed ones. If it fails it returns
39 * false from the function the macro is used in.
40 */
41
42 #define PARSE_CHARS_TO_NUM(char_pointer, dest_variable, number_of_chars) \
43 do { int32_t _i=number_of_chars; \
44 dest_variable = 0; \
45 while(_i) { \
46 ADD_HEX_CHAR_TO_INT_OR_RETURN_FALSE(*char_pointer, dest_variable); \
47 char_pointer++; \
48 _i--; \
49 } } while(0)
50
51
52 /**
53 * Parses a hyphen from the char_pointer string. If there is no hyphen there
54 * the function returns false from the function it's used in. The
55 * char_pointer is advanced one step.
56 */
57
58 #define PARSE_HYPHEN(char_pointer) if (*(char_pointer++) != '-') return false
59
60 /*
61 * Turns a {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} string into
62 * an nsID. It can also handle the old format without the { and }.
63 */
64
65 bool
Parse(const char * aIDStr)66 nsID::Parse(const char* aIDStr)
67 {
68 /* Optimized for speed */
69 if (!aIDStr) {
70 return false;
71 }
72
73 bool expectFormat1 = (aIDStr[0] == '{');
74 if (expectFormat1) {
75 ++aIDStr;
76 }
77
78 PARSE_CHARS_TO_NUM(aIDStr, m0, 8);
79 PARSE_HYPHEN(aIDStr);
80 PARSE_CHARS_TO_NUM(aIDStr, m1, 4);
81 PARSE_HYPHEN(aIDStr);
82 PARSE_CHARS_TO_NUM(aIDStr, m2, 4);
83 PARSE_HYPHEN(aIDStr);
84 int i;
85 for (i = 0; i < 2; ++i) {
86 PARSE_CHARS_TO_NUM(aIDStr, m3[i], 2);
87 }
88 PARSE_HYPHEN(aIDStr);
89 while (i < 8) {
90 PARSE_CHARS_TO_NUM(aIDStr, m3[i], 2);
91 i++;
92 }
93
94 return expectFormat1 ? *aIDStr == '}' : true;
95 }
96
97 #ifndef XPCOM_GLUE_AVOID_NSPR
98
99 static const char gIDFormat[] =
100 "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}";
101
102 /*
103 * Returns an allocated string in {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
104 * format. The string is allocated with NS_Alloc and should be freed by
105 * the caller.
106 */
107
108 char*
ToString() const109 nsID::ToString() const
110 {
111 char* res = (char*)NS_Alloc(NSID_LENGTH);
112
113 if (res) {
114 snprintf(res, NSID_LENGTH, gIDFormat,
115 m0, (uint32_t)m1, (uint32_t)m2,
116 (uint32_t)m3[0], (uint32_t)m3[1], (uint32_t)m3[2],
117 (uint32_t)m3[3], (uint32_t)m3[4], (uint32_t)m3[5],
118 (uint32_t)m3[6], (uint32_t)m3[7]);
119 }
120 return res;
121 }
122
123 void
ToProvidedString(char (& aDest)[NSID_LENGTH]) const124 nsID::ToProvidedString(char (&aDest)[NSID_LENGTH]) const
125 {
126 SprintfLiteral(aDest, gIDFormat,
127 m0, (uint32_t)m1, (uint32_t)m2,
128 (uint32_t)m3[0], (uint32_t)m3[1], (uint32_t)m3[2],
129 (uint32_t)m3[3], (uint32_t)m3[4], (uint32_t)m3[5],
130 (uint32_t)m3[6], (uint32_t)m3[7]);
131 }
132
133 #endif // XPCOM_GLUE_AVOID_NSPR
134