| OLD | NEW |
| (Empty) |
| 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 } | |
| OLD | NEW |