1 martin 1.40 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.41 //
|
3 martin 1.40 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.41 //
|
10 martin 1.40 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.41 //
|
17 martin 1.40 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.41 //
|
20 martin 1.40 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.41 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.40 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.41 //
|
28 martin 1.40 //////////////////////////////////////////////////////////////////////////
|
29 mike 1.8 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include <cctype>
33 #include "CIMName.h"
|
34 kumpf 1.39 #include "CIMNameCast.h"
|
35 david 1.19 #include "CommonUTF.h"
|
36 r.kieninger 1.31 #include "CharSet.h"
|
37 mike 1.8
38 PEGASUS_NAMESPACE_BEGIN
39
|
40 kumpf 1.14 ////////////////////////////////////////////////////////////////////////////////
41 //
42 // CIMName
43 //
44 ////////////////////////////////////////////////////////////////////////////////
45
46 #define PEGASUS_ARRAY_T CIMName
47 # include "ArrayImpl.h"
48 #undef PEGASUS_ARRAY_T
49
|
50 mike 1.38 Uint32 CIMNameLegalASCII(const char* str)
|
51 thilo.boehm 1.36 {
52 const Uint8* p = (const Uint8*)str;
53
54 if (!CharSet::isAlphaUnder(*p++))
55 return 0;
56
57 while (*p)
58 {
59 if (!CharSet::isAlNumUnder(*p++))
60 return 0;
61 }
62
|
63 dave.sudlik 1.37 return Uint32((char*)p - str);
|
64 thilo.boehm 1.36 }
65
|
66 r.kieninger 1.31 CIMName::CIMName(const String& name) : cimName(name)
|
67 kumpf 1.14 {
|
68 r.kieninger 1.31 if (!legal(name))
69 throw InvalidNameException(name);
|
70 kumpf 1.14 }
71
|
72 thilo.boehm 1.36 CIMName::CIMName(const char* name)
|
73 kumpf 1.14 {
|
74 mike 1.38 Uint32 size = CIMNameLegalASCII(name);
|
75 thilo.boehm 1.36
76 if (size == 0)
77 {
78 cimName.assign(name);
79
80 if (!legal(cimName))
|
81 kumpf 1.42 throw InvalidNameException(name);
|
82 thilo.boehm 1.36 }
83 else
84 {
85 AssignASCII(cimName, name, size);
86 }
|
87 kumpf 1.14 }
88
|
89 r.kieninger 1.31 CIMName& CIMName::operator=(const String& name)
|
90 kumpf 1.14 {
91 if (!legal(name))
|
92 kumpf 1.16 throw InvalidNameException(name);
|
93 kumpf 1.14
|
94 r.kieninger 1.31 cimName=name;
|
95 kumpf 1.14 return *this;
96 }
97
|
98 r.kieninger 1.31 CIMName& CIMName::operator=(const char* name)
|
99 kumpf 1.14 {
|
100 mike 1.38 Uint32 size = CIMNameLegalASCII(name);
|
101 thilo.boehm 1.36
102 if (size == 0)
103 {
104 String tmp(name);
|
105 r.kieninger 1.31
|
106 thilo.boehm 1.36 if (!legal(tmp))
107 throw InvalidNameException(name);
|
108 kumpf 1.42
|
109 thilo.boehm 1.36 cimName.assign(tmp);
110 }
111 else
112 {
113 AssignASCII(cimName, name, size);
114 }
|
115 kumpf 1.14 return *this;
116 }
117
|
118 r.kieninger 1.31 Boolean CIMName::legal(const String& name)
|
119 kumpf 1.14 {
|
120 r.kieninger 1.31 // Check first character.
|
121 kumpf 1.14
|
122 r.kieninger 1.31 const Uint16* p = (const Uint16*)name.getChar16Data();
|
123 kumpf 1.35 Uint32 n = name.size();
|
124 kumpf 1.14
|
125 r.kieninger 1.31 if (!(*p < 128 && CharSet::isAlphaUnder(*p)))
126 {
|
127 kumpf 1.33 if (!(*p >= 0x0080 && *p <= 0xFFEF))
|
128 r.kieninger 1.31 return false;
129 }
|
130 kumpf 1.14
|
131 r.kieninger 1.31 p++;
132 n--;
|
133 mike 1.8
|
134 r.kieninger 1.31 // Use loop unrolling to skip over good ASCII 7-bit characters.
|
135 mike 1.8
|
136 r.kieninger 1.31 while (n >= 4)
137 {
|
138 kumpf 1.33 if (p[0] < 128 && CharSet::isAlNumUnder(p[0]) &&
139 p[1] < 128 && CharSet::isAlNumUnder(p[1]) &&
140 p[2] < 128 && CharSet::isAlNumUnder(p[2]) &&
141 p[3] < 128 && CharSet::isAlNumUnder(p[3]))
142 {
143 p += 4;
144 n -= 4;
145 continue;
146 }
|
147 david 1.19
|
148 kumpf 1.33 break;
|
149 david 1.20 }
|
150 kumpf 1.21
|
151 r.kieninger 1.31 // Process remaining charcters.
152
153 while (n)
|
154 mike 1.8 {
|
155 kumpf 1.33 if (!(*p < 128 && CharSet::isAlNumUnder(*p)))
156 {
157 if (!(*p >= 0x0080 && *p <= 0xFFEF))
158 return false;
159 }
160 p++;
161 n--;
|
162 mike 1.8 }
163
164 return true;
|
165 kumpf 1.10 }
166
|
167 kumpf 1.14 ////////////////////////////////////////////////////////////////////////////////
168 //
169 // CIMNamespaceName
170 //
171 ////////////////////////////////////////////////////////////////////////////////
172
|
173 kumpf 1.17 #define PEGASUS_ARRAY_T CIMNamespaceName
174 # include "ArrayImpl.h"
175 #undef PEGASUS_ARRAY_T
176
|
177 r.kieninger 1.31 inline void _check_namespace_name(String& name)
|
178 kumpf 1.14 {
|
179 r.kieninger 1.31 if (!CIMNamespaceName::legal(name))
180 throw InvalidNamespaceNameException(name);
181
182 if (name[0] == '/')
183 name.remove(0, 1);
|
184 kumpf 1.14 }
185
|
186 kumpf 1.33 CIMNamespaceName::CIMNamespaceName(const String& name)
|
187 r.kieninger 1.31 : cimNamespaceName(name)
|
188 kumpf 1.14 {
|
189 r.kieninger 1.31 _check_namespace_name(cimNamespaceName);
|
190 kumpf 1.14 }
191
|
192 kumpf 1.33 CIMNamespaceName::CIMNamespaceName(const char* name)
|
193 r.kieninger 1.31 : cimNamespaceName(name)
|
194 kumpf 1.14 {
|
195 r.kieninger 1.31 _check_namespace_name(cimNamespaceName);
|
196 kumpf 1.14 }
197
198 CIMNamespaceName& CIMNamespaceName::operator=(const CIMNamespaceName& name)
199 {
|
200 r.kieninger 1.31 cimNamespaceName = name.cimNamespaceName;
|
201 kumpf 1.14 return *this;
202 }
203
204 CIMNamespaceName& CIMNamespaceName::operator=(const String& name)
205 {
|
206 r.kieninger 1.31 cimNamespaceName = name;
207 _check_namespace_name(cimNamespaceName);
|
208 kumpf 1.14 return *this;
209 }
210
|
211 r.kieninger 1.31 CIMNamespaceName& CIMNamespaceName::operator=(const char* name)
|
212 kumpf 1.14 {
|
213 r.kieninger 1.31 cimNamespaceName = name;
214 _check_namespace_name(cimNamespaceName);
215 return *this;
|
216 kumpf 1.14 }
217
|
218 kumpf 1.18 Boolean CIMNamespaceName::legal(const String& name)
|
219 kumpf 1.14 {
|
220 kumpf 1.21 Uint32 length = name.size();
221 Uint32 index = 0;
|
222 kumpf 1.14
|
223 kumpf 1.21 // Skip a leading '/' because the CIM specification is ambiguous
224 if (name[0] == '/')
|
225 david 1.19 {
|
226 kumpf 1.21 index++;
|
227 kumpf 1.14 }
228
|
229 kumpf 1.21 Boolean moreElements = true;
|
230 kumpf 1.14
|
231 kumpf 1.21 // Check each namespace element (delimited by '/' characters)
232 while (moreElements)
|
233 kumpf 1.14 {
|
234 kumpf 1.21 moreElements = false;
|
235 kumpf 1.14
|
236 kumpf 1.21 if (index == length)
237 {
238 return false;
239 }
|
240 kumpf 1.14
|
241 r.kieninger 1.31 Uint16 ch = name[index++];
|
242 kumpf 1.14
|
243 kumpf 1.21 // First character must be alphabetic or '_' if ASCII
|
244 r.kieninger 1.31
|
245 kumpf 1.34 if (!(ch < 128 && CharSet::isAlphaUnder(ch)))
246 {
247 if (!(ch >= 0x0080 && ch <= 0xFFEF))
248 return false;
249 }
|
250 kumpf 1.21
251 // Remaining characters must be alphanumeric or '_' if ASCII
252 while (index < length)
253 {
|
254 r.kieninger 1.31 ch = name[index++];
|
255 kumpf 1.21
256 // A '/' indicates another namespace element follows
|
257 r.kieninger 1.31 if (ch == '/')
|
258 kumpf 1.21 {
259 moreElements = true;
260 break;
261 }
262
|
263 kumpf 1.34 if (!(ch < 128 && CharSet::isAlNumUnder(ch)))
264 {
265 if (!(ch >= 0x0080 && ch <= 0xFFEF))
266 return false;
267 }
|
268 kumpf 1.21 }
|
269 kumpf 1.14 }
270
271 return true;
272 }
273
|
274 r.kieninger 1.31 Boolean operator==(const CIMNamespaceName& name1, const CIMNamespaceName& name2)
|
275 kumpf 1.14 {
|
276 r.kieninger 1.31 return name1.equal(name2);
|
277 kumpf 1.14 }
|
278 kumpf 1.17
|
279 r.kieninger 1.31 Boolean operator==(const CIMNamespaceName& name1, const char* name2)
|
280 kumpf 1.17 {
281 return name1.equal(name2);
282 }
|
283 mike 1.8
|
284 r.kieninger 1.31 Boolean operator==(const char* name1, const CIMNamespaceName& name2)
285 {
286 return name2.equal(name1);
287 }
288
|
289 david.dillard 1.29 Boolean operator!=(const CIMNamespaceName& name1, const CIMNamespaceName& name2)
290 {
291 return !name1.equal(name2);
292 }
293
|
294 r.kieninger 1.31 Boolean operator!=(const CIMNamespaceName& name1, const char* name2)
295 {
296 return !name1.equal(name2);
297 }
298
299 Boolean operator!=(const char* name1, const CIMNamespaceName& name2)
300 {
301 return !name2.equal(name1);
302 }
303
|
304 mike 1.8 PEGASUS_NAMESPACE_END
|
305 r.kieninger 1.31
306 /*
307 ================================================================================
308
309 Optimizations:
310
311 1. Optimized legal().
312 2. Implmented "char*" version of operator=().
313 3. Added conditional inlining (for Pegaus internal use).
314 4. Added comparison functions for "char*".
315 5. Implemented "unchecked" version of constructors and assignment operators
316 that take String or "char*".
317 6. Added loop unrolling to CIMName::legal()
318
319 ================================================================================
320 */
|