Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 /* | |
5 * pkix_pl_string.c | |
6 * | |
7 * String Object Functions | |
8 * | |
9 */ | |
10 | |
11 #include "pkix_pl_string.h" | |
12 | |
13 /* --Private-String-Functions------------------------------------- */ | |
14 | |
15 /* | |
16 * FUNCTION: pkix_pl_String_Comparator | |
17 * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h) | |
18 * | |
19 * NOTE: | |
20 * This function is a utility function called by pkix_pl_String_Equals(). | |
21 * It is not officially registered as a comparator. | |
22 */ | |
23 static PKIX_Error * | |
24 pkix_pl_String_Comparator( | |
25 PKIX_PL_String *firstString, | |
26 PKIX_PL_String *secondString, | |
27 PKIX_Int32 *pResult, | |
28 void *plContext) | |
29 { | |
30 PKIX_UInt32 i; | |
31 PKIX_Int32 result; | |
32 unsigned char *p1 = NULL; | |
33 unsigned char *p2 = NULL; | |
34 | |
35 PKIX_ENTER(STRING, "pkix_pl_String_Comparator"); | |
36 PKIX_NULLCHECK_THREE(firstString, secondString, pResult); | |
37 | |
38 result = 0; | |
39 | |
40 p1 = (unsigned char*) firstString->utf16String; | |
41 p2 = (unsigned char*) secondString->utf16String; | |
42 | |
43 /* Compare characters until you find a difference */ | |
44 for (i = 0; ((i < firstString->utf16Length) && | |
45 (i < secondString->utf16Length) && | |
46 result == 0); i++, p1++, p2++) { | |
47 if (*p1 < *p2){ | |
48 result = -1; | |
49 } else if (*p1 > *p2){ | |
50 result = 1; | |
51 } | |
52 } | |
53 | |
54 /* If two arrays are identical so far, the longer one is greater */ | |
55 if (result == 0) { | |
56 if (firstString->utf16Length < secondString->utf16Length) { | |
57 result = -1; | |
58 } else if (firstString->utf16Length > | |
59 secondString->utf16Length) { | |
60 result = 1; | |
61 } | |
62 } | |
63 | |
64 *pResult = result; | |
65 | |
66 PKIX_RETURN(STRING); | |
67 } | |
68 | |
69 /* | |
70 * FUNCTION: pkix_pl_String_Destroy | |
71 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) | |
72 */ | |
73 static PKIX_Error * | |
74 pkix_pl_String_Destroy( | |
75 PKIX_PL_Object *object, | |
76 void *plContext) | |
77 { | |
78 PKIX_PL_String *string = NULL; | |
79 | |
80 PKIX_ENTER(STRING, "pkix_pl_String_Destroy"); | |
81 PKIX_NULLCHECK_ONE(object); | |
82 | |
83 PKIX_CHECK(pkix_CheckType(object, PKIX_STRING_TYPE, plContext), | |
84 PKIX_ARGUMENTNOTSTRING); | |
85 | |
86 string = (PKIX_PL_String*)object; | |
87 | |
88 /* XXX For debugging Destroy EscASCII String */ | |
89 if (string->escAsciiString != NULL) { | |
90 PKIX_FREE(string->escAsciiString); | |
91 string->escAsciiString = NULL; | |
92 string->escAsciiLength = 0; | |
93 } | |
94 | |
95 /* Destroy UTF16 String */ | |
96 if (string->utf16String != NULL) { | |
97 PKIX_FREE(string->utf16String); | |
98 string->utf16String = NULL; | |
99 string->utf16Length = 0; | |
100 } | |
101 | |
102 cleanup: | |
103 | |
104 PKIX_RETURN(STRING); | |
105 } | |
106 | |
107 /* | |
108 * FUNCTION: pkix_pl_String_ToString | |
109 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) | |
110 */ | |
111 static PKIX_Error * | |
112 pkix_pl_String_ToString( | |
113 PKIX_PL_Object *object, | |
114 PKIX_PL_String **pString, | |
115 void *plContext) | |
116 { | |
117 PKIX_PL_String *string = NULL; | |
118 char *ascii = NULL; | |
119 PKIX_UInt32 length; | |
120 | |
121 PKIX_ENTER(STRING, "pkix_pl_String_ToString"); | |
122 PKIX_NULLCHECK_TWO(object, pString); | |
123 | |
124 PKIX_CHECK(pkix_CheckType(object, PKIX_STRING_TYPE, plContext), | |
125 PKIX_ARGUMENTNOTSTRING); | |
126 | |
127 string = (PKIX_PL_String*)object; | |
128 | |
129 PKIX_CHECK(PKIX_PL_String_GetEncoded | |
130 (string, PKIX_ESCASCII, (void **)&ascii, &length, plContext), | |
131 PKIX_STRINGGETENCODEDFAILED); | |
132 | |
133 PKIX_CHECK(PKIX_PL_String_Create | |
134 (PKIX_ESCASCII, ascii, 0, pString, plContext), | |
135 PKIX_STRINGCREATEFAILED); | |
136 | |
137 goto cleanup; | |
138 | |
139 cleanup: | |
140 | |
141 PKIX_FREE(ascii); | |
142 | |
143 PKIX_RETURN(STRING); | |
144 } | |
145 | |
146 /* | |
147 * FUNCTION: pkix_pl_String_Equals | |
148 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h) | |
149 */ | |
150 static PKIX_Error * | |
151 pkix_pl_String_Equals( | |
152 PKIX_PL_Object *firstObject, | |
153 PKIX_PL_Object *secondObject, | |
154 PKIX_Boolean *pResult, | |
155 void *plContext) | |
156 { | |
157 PKIX_UInt32 secondType; | |
158 PKIX_Int32 cmpResult = 0; | |
159 | |
160 PKIX_ENTER(STRING, "pkix_pl_String_Equals"); | |
161 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); | |
162 | |
163 /* Sanity check: Test that "firstObject" is a Strings */ | |
164 PKIX_CHECK(pkix_CheckType(firstObject, PKIX_STRING_TYPE, plContext), | |
165 PKIX_FIRSTOBJECTNOTSTRING); | |
166 | |
167 /* "SecondObject" doesn't have to be a string */ | |
168 PKIX_CHECK(PKIX_PL_Object_GetType | |
169 (secondObject, &secondType, plContext), | |
170 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); | |
171 | |
172 /* If types differ, then we will return false */ | |
173 *pResult = PKIX_FALSE; | |
174 | |
175 if (secondType != PKIX_STRING_TYPE) goto cleanup; | |
176 | |
177 /* It's safe to cast here */ | |
178 PKIX_CHECK(pkix_pl_String_Comparator | |
179 ((PKIX_PL_String*)firstObject, | |
180 (PKIX_PL_String*)secondObject, | |
181 &cmpResult, | |
182 plContext), | |
183 PKIX_STRINGCOMPARATORFAILED); | |
184 | |
185 /* Strings are equal iff Comparator Result is 0 */ | |
186 *pResult = (cmpResult == 0); | |
187 | |
188 cleanup: | |
189 | |
190 PKIX_RETURN(STRING); | |
191 } | |
192 | |
193 /* | |
194 * FUNCTION: pkix_pl_String_Hashcode | |
195 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) | |
196 */ | |
197 static PKIX_Error * | |
198 pkix_pl_String_Hashcode( | |
199 PKIX_PL_Object *object, | |
200 PKIX_UInt32 *pHashcode, | |
201 void *plContext) | |
202 { | |
203 PKIX_PL_String *string = NULL; | |
204 | |
205 PKIX_ENTER(STRING, "pkix_pl_String_Hashcode"); | |
206 PKIX_NULLCHECK_TWO(object, pHashcode); | |
207 | |
208 PKIX_CHECK(pkix_CheckType(object, PKIX_STRING_TYPE, plContext), | |
209 PKIX_OBJECTNOTSTRING); | |
210 | |
211 string = (PKIX_PL_String*)object; | |
212 | |
213 PKIX_CHECK(pkix_hash | |
214 ((const unsigned char *)string->utf16String, | |
215 string->utf16Length, | |
216 pHashcode, | |
217 plContext), | |
218 PKIX_HASHFAILED); | |
219 | |
220 cleanup: | |
221 | |
222 PKIX_RETURN(STRING); | |
223 } | |
224 | |
225 /* | |
226 * FUNCTION: pkix_pl_String_RegisterSelf | |
227 * DESCRIPTION: | |
228 * Registers PKIX_STRING_TYPE and its related functions with systemClasses[] | |
229 * THREAD SAFETY: | |
230 * Not Thread Safe - for performance and complexity reasons | |
231 * | |
232 * Since this function is only called by PKIX_PL_Initialize, which should | |
233 * only be called once, it is acceptable that this function is not | |
234 * thread-safe. | |
235 */ | |
236 PKIX_Error * | |
237 pkix_pl_String_RegisterSelf( | |
238 void *plContext) | |
239 { | |
240 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; | |
241 pkix_ClassTable_Entry entry; | |
242 | |
243 PKIX_ENTER(STRING, "pkix_pl_String_RegisterSelf"); | |
244 | |
245 entry.description = "String"; | |
246 entry.objCounter = 0; | |
247 entry.typeObjectSize = sizeof(PKIX_PL_String); | |
248 entry.destructor = pkix_pl_String_Destroy; | |
249 entry.equalsFunction = pkix_pl_String_Equals; | |
250 entry.hashcodeFunction = pkix_pl_String_Hashcode; | |
251 entry.toStringFunction = pkix_pl_String_ToString; | |
252 entry.comparator = NULL; | |
253 entry.duplicateFunction = pkix_duplicateImmutable; | |
254 | |
255 systemClasses[PKIX_STRING_TYPE] = entry; | |
256 | |
257 PKIX_RETURN(STRING); | |
258 } | |
259 | |
260 | |
261 /* --Public-String-Functions----------------------------------------- */ | |
262 | |
263 /* | |
264 * FUNCTION: PKIX_PL_String_Create (see comments in pkix_pl_system.h) | |
265 */ | |
266 PKIX_Error * | |
267 PKIX_PL_String_Create( | |
268 PKIX_UInt32 fmtIndicator, | |
269 const void *stringRep, | |
270 PKIX_UInt32 stringLen, | |
271 PKIX_PL_String **pString, | |
272 void *plContext) | |
273 { | |
274 PKIX_PL_String *string = NULL; | |
275 unsigned char *utf16Char = NULL; | |
276 PKIX_UInt32 i; | |
277 | |
278 PKIX_ENTER(STRING, "PKIX_PL_String_Create"); | |
279 PKIX_NULLCHECK_TWO(pString, stringRep); | |
280 | |
281 PKIX_CHECK(PKIX_PL_Object_Alloc | |
282 (PKIX_STRING_TYPE, | |
283 sizeof (PKIX_PL_String), | |
284 (PKIX_PL_Object **)&string, | |
285 plContext), | |
286 PKIX_COULDNOTALLOCATENEWSTRINGOBJECT); | |
287 | |
288 string->utf16String = NULL; | |
289 string->utf16Length = 0; | |
290 | |
291 /* XXX For Debugging */ | |
292 string->escAsciiString = NULL; | |
293 string->escAsciiLength = 0; | |
294 | |
295 switch (fmtIndicator) { | |
296 case PKIX_ESCASCII: case PKIX_ESCASCII_DEBUG: | |
297 PKIX_STRING_DEBUG("\tCalling PL_strlen).\n"); | |
298 string->escAsciiLength = PL_strlen(stringRep); | |
299 | |
300 /* XXX Cache for Debugging */ | |
301 PKIX_CHECK(PKIX_PL_Malloc | |
302 ((string->escAsciiLength)+1, | |
303 (void **)&string->escAsciiString, | |
304 plContext), | |
305 PKIX_MALLOCFAILED); | |
306 | |
307 (void) PORT_Memcpy | |
308 (string->escAsciiString, | |
309 (void *)((char *)stringRep), | |
310 (string->escAsciiLength)+1); | |
311 | |
312 /* Convert the EscASCII string to UTF16 */ | |
313 PKIX_CHECK(pkix_EscASCII_to_UTF16 | |
314 (string->escAsciiString, | |
315 string->escAsciiLength, | |
316 (fmtIndicator == PKIX_ESCASCII_DEBUG), | |
317 &string->utf16String, | |
318 &string->utf16Length, | |
319 plContext), | |
320 PKIX_ESCASCIITOUTF16FAILED); | |
321 break; | |
322 case PKIX_UTF8: | |
323 /* Convert the UTF8 string to UTF16 */ | |
324 PKIX_CHECK(pkix_UTF8_to_UTF16 | |
325 (stringRep, | |
326 stringLen, | |
327 &string->utf16String, | |
328 &string->utf16Length, | |
329 plContext), | |
330 PKIX_UTF8TOUTF16FAILED); | |
331 break; | |
332 case PKIX_UTF16: | |
333 /* UTF16 Strings must be even in length */ | |
334 if (stringLen%2 == 1) { | |
335 PKIX_DECREF(string); | |
336 PKIX_ERROR(PKIX_UTF16ALIGNMENTERROR); | |
337 } | |
338 | |
339 utf16Char = (unsigned char *)stringRep; | |
340 | |
341 /* Make sure this is a valid UTF-16 String */ | |
342 for (i = 0; \ | |
343 (i < stringLen) && (pkixErrorResult == NULL); \ | |
344 i += 2) { | |
345 /* Check that surrogate pairs are valid */ | |
346 if ((utf16Char[i] >= 0xD8)&& | |
347 (utf16Char[i] <= 0xDB)) { | |
348 if ((i+2) >= stringLen) { | |
349 PKIX_ERROR(PKIX_UTF16HIGHZONEALIGNMENTERROR); | |
350 /* Second pair should be DC00-DFFF */ | |
351 } else if (!((utf16Char[i+2] >= 0xDC)&& | |
352 (utf16Char[i+2] <= 0xDF))) { | |
353 PKIX_ERROR(PKIX_UTF16LOWZONEERROR); | |
354 } else { | |
355 /* Surrogate quartet is valid. */ | |
356 i += 2; | |
357 } | |
358 } | |
359 } | |
360 | |
361 /* Create UTF16 String */ | |
362 string->utf16Length = stringLen; | |
363 | |
364 /* Alloc space for string */ | |
365 PKIX_CHECK(PKIX_PL_Malloc | |
366 (stringLen, &string->utf16String, plContext), | |
367 PKIX_MALLOCFAILED); | |
368 | |
369 PKIX_STRING_DEBUG("\tCalling PORT_Memcpy).\n"); | |
370 (void) PORT_Memcpy | |
371 (string->utf16String, stringRep, stringLen); | |
372 break; | |
373 | |
374 default: | |
375 PKIX_ERROR(PKIX_UNKNOWNFORMAT); | |
376 } | |
377 | |
378 *pString = string; | |
379 | |
380 cleanup: | |
381 | |
382 if (PKIX_ERROR_RECEIVED){ | |
383 PKIX_DECREF(string); | |
384 } | |
385 | |
386 PKIX_RETURN(STRING); | |
387 } | |
388 | |
389 /* | |
390 * FUNCTION: PKIX_PL_Sprintf (see comments in pkix_pl_system.h) | |
391 */ | |
392 PKIX_Error * | |
393 PKIX_PL_Sprintf( | |
394 PKIX_PL_String **pOut, | |
395 void *plContext, | |
396 const PKIX_PL_String *fmt, | |
397 ...) | |
398 { | |
399 PKIX_PL_String *tempString = NULL; | |
400 PKIX_UInt32 tempUInt = 0; | |
401 void *pArg = NULL; | |
402 char *asciiText = NULL; | |
403 char *asciiFormat = NULL; | |
404 char *convertedAsciiFormat = NULL; | |
405 char *convertedAsciiFormatBase = NULL; | |
406 va_list args; | |
407 PKIX_UInt32 length, i, j, dummyLen; | |
408 | |
409 PKIX_ENTER(STRING, "PKIX_PL_Sprintf"); | |
410 PKIX_NULLCHECK_TWO(pOut, fmt); | |
411 | |
412 PKIX_CHECK(PKIX_PL_String_GetEncoded | |
413 ((PKIX_PL_String *)fmt, | |
414 PKIX_ESCASCII, | |
415 (void **)&asciiFormat, | |
416 &length, | |
417 plContext), | |
418 PKIX_STRINGGETENCODEDFAILED); | |
419 | |
420 PKIX_STRING_DEBUG("\tCalling PR_Malloc).\n"); | |
421 convertedAsciiFormat = PR_Malloc(length + 1); | |
422 if (convertedAsciiFormat == NULL) | |
423 PKIX_ERROR_ALLOC_ERROR(); | |
424 | |
425 convertedAsciiFormatBase = convertedAsciiFormat; | |
426 | |
427 PKIX_STRING_DEBUG("\tCalling va_start).\n"); | |
428 va_start(args, fmt); | |
429 | |
430 i = 0; | |
431 j = 0; | |
432 while (i < length) { | |
433 if ((asciiFormat[i] == '%')&&((i+1) < length)) { | |
434 switch (asciiFormat[i+1]) { | |
435 case 's': | |
436 convertedAsciiFormat[j++] = asciiFormat[i++]; | |
437 convertedAsciiFormat[j++] = asciiFormat[i++]; | |
438 convertedAsciiFormat[j] = '\0'; | |
439 | |
440 tempString = va_arg(args, PKIX_PL_String *); | |
441 if (tempString != NULL) { | |
442 PKIX_CHECK(PKIX_PL_String_GetEncoded | |
443 ((PKIX_PL_String*) | |
444 tempString, | |
445 PKIX_ESCASCII, | |
446 &pArg, | |
447 &dummyLen, | |
448 plContext), | |
449 PKIX_STRINGGETENCODEDFAILED); | |
450 } else { | |
451 /* there may be a NULL in var_args */ | |
452 pArg = NULL; | |
453 } | |
454 if (asciiText != NULL) { | |
455 asciiText = PR_sprintf_append(asciiText, | |
456 (const char *)convertedAsciiFormat, | |
457 pArg); | |
458 } else { | |
459 asciiText = PR_smprintf | |
460 ((const char *)convertedAsciiFormat, | |
461 pArg); | |
462 } | |
463 if (pArg != NULL) { | |
464 PKIX_PL_Free(pArg, plContext); | |
465 pArg = NULL; | |
466 } | |
467 convertedAsciiFormat += j; | |
468 j = 0; | |
469 break; | |
470 case 'd': | |
471 case 'i': | |
472 case 'o': | |
473 case 'u': | |
474 case 'x': | |
475 case 'X': | |
476 convertedAsciiFormat[j++] = asciiFormat[i++]; | |
477 convertedAsciiFormat[j++] = asciiFormat[i++]; | |
478 convertedAsciiFormat[j] = '\0'; | |
479 | |
480 tempUInt = va_arg(args, PKIX_UInt32); | |
481 if (asciiText != NULL) { | |
482 asciiText = PR_sprintf_append(asciiText, | |
483 (const char *)convertedAsciiFormat, | |
484 tempUInt); | |
485 } else { | |
486 asciiText = PR_smprintf | |
487 ((const char *)convertedAsciiFormat, | |
488 tempUInt); | |
489 } | |
490 convertedAsciiFormat += j; | |
491 j = 0; | |
492 break; | |
493 default: | |
494 convertedAsciiFormat[j++] = asciiFormat[i++]; | |
495 convertedAsciiFormat[j++] = asciiFormat[i++]; | |
496 break; | |
497 } | |
498 } else { | |
499 convertedAsciiFormat[j++] = asciiFormat[i++]; | |
500 } | |
501 } | |
502 | |
503 /* for constant string value at end of fmt */ | |
504 if (j > 0) { | |
505 convertedAsciiFormat[j] = '\0'; | |
506 if (asciiText != NULL) { | |
507 asciiText = PR_sprintf_append(asciiText, | |
508 (const char *)convertedAsciiFormat); | |
509 } else { | |
510 asciiText = PR_smprintf((const char *)convertedAsciiFormat); | |
511 } | |
512 } | |
513 | |
514 va_end(args); | |
515 | |
516 /* Copy temporary char * into a string object */ | |
517 PKIX_CHECK(PKIX_PL_String_Create | |
518 (PKIX_ESCASCII, (void *)asciiText, 0, pOut, plContext), | |
519 PKIX_STRINGCREATEFAILED); | |
520 | |
521 cleanup: | |
522 | |
523 PKIX_FREE(asciiFormat); | |
524 | |
525 if (convertedAsciiFormatBase){ | |
526 PR_Free(convertedAsciiFormatBase); | |
527 } | |
528 | |
529 if (asciiText){ | |
530 PKIX_STRING_DEBUG("\tCalling PR_smprintf_free).\n"); | |
531 PR_smprintf_free(asciiText); | |
532 } | |
533 | |
534 PKIX_RETURN(STRING); | |
535 } | |
536 | |
537 /* | |
538 * FUNCTION: PKIX_PL_GetString (see comments in pkix_pl_system.h) | |
539 */ | |
540 PKIX_Error * | |
541 PKIX_PL_GetString( | |
542 /* ARGSUSED */ PKIX_UInt32 stringID, | |
543 char *defaultString, | |
544 PKIX_PL_String **pString, | |
545 void *plContext) | |
546 { | |
547 PKIX_ENTER(STRING, "PKIX_PL_GetString"); | |
548 PKIX_NULLCHECK_TWO(pString, defaultString); | |
549 | |
550 /* XXX Optimization - use stringID for caching */ | |
551 PKIX_CHECK(PKIX_PL_String_Create | |
552 (PKIX_ESCASCII, defaultString, 0, pString, plContext), | |
553 PKIX_STRINGCREATEFAILED); | |
554 | |
555 cleanup: | |
556 | |
557 PKIX_RETURN(STRING); | |
558 } | |
559 | |
560 /* | |
561 * FUNCTION: PKIX_PL_String_GetEncoded (see comments in pkix_pl_system.h) | |
562 */ | |
563 PKIX_Error * | |
564 PKIX_PL_String_GetEncoded( | |
565 PKIX_PL_String *string, | |
566 PKIX_UInt32 fmtIndicator, | |
567 void **pStringRep, | |
568 PKIX_UInt32 *pLength, | |
569 void *plContext) | |
570 { | |
571 PKIX_ENTER(STRING, "PKIX_PL_String_GetEncoded"); | |
572 PKIX_NULLCHECK_THREE(string, pStringRep, pLength); | |
573 | |
574 switch (fmtIndicator) { | |
575 case PKIX_ESCASCII: case PKIX_ESCASCII_DEBUG: | |
576 PKIX_CHECK(pkix_UTF16_to_EscASCII | |
577 (string->utf16String, | |
578 string->utf16Length, | |
579 (fmtIndicator == PKIX_ESCASCII_DEBUG), | |
580 (char **)pStringRep, | |
581 pLength, | |
582 plContext), | |
583 PKIX_UTF16TOESCASCIIFAILED); | |
584 break; | |
585 case PKIX_UTF8: | |
586 PKIX_CHECK(pkix_UTF16_to_UTF8 | |
587 (string->utf16String, | |
588 string->utf16Length, | |
589 PKIX_FALSE, | |
590 pStringRep, | |
591 pLength, | |
592 plContext), | |
593 PKIX_UTF16TOUTF8FAILED); | |
594 break; | |
595 case PKIX_UTF8_NULL_TERM: | |
596 PKIX_CHECK(pkix_UTF16_to_UTF8 | |
597 (string->utf16String, | |
598 string->utf16Length, | |
599 PKIX_TRUE, | |
600 pStringRep, | |
601 pLength, | |
602 plContext), | |
603 PKIX_UTF16TOUTF8FAILED); | |
604 break; | |
605 case PKIX_UTF16: | |
606 *pLength = string->utf16Length; | |
607 | |
608 PKIX_CHECK(PKIX_PL_Malloc(*pLength, pStringRep, plContext), | |
609 PKIX_MALLOCFAILED); | |
610 | |
611 PKIX_STRING_DEBUG("\tCalling PORT_Memcpy).\n"); | |
612 (void) PORT_Memcpy(*pStringRep, string->utf16String, *pLength); | |
613 break; | |
614 default: | |
615 PKIX_ERROR(PKIX_UNKNOWNFORMAT); | |
616 } | |
617 | |
618 cleanup: | |
619 | |
620 PKIX_RETURN(STRING); | |
621 } |