327 return result; |
327 return result; |
328 } |
328 } |
329 |
329 |
330 char* UNICODE::as_utf8(jchar* base, int length) { |
330 char* UNICODE::as_utf8(jchar* base, int length) { |
331 int utf8_len = utf8_length(base, length); |
331 int utf8_len = utf8_length(base, length); |
332 u_char* result = NEW_RESOURCE_ARRAY(u_char, utf8_len + 1); |
332 u_char* buf = NEW_RESOURCE_ARRAY(u_char, utf8_len + 1); |
333 u_char* p = result; |
333 char* result = as_utf8(base, length, (char*) buf, utf8_len + 1); |
334 for (int index = 0; index < length; index++) { |
334 assert((int) strlen(result) == utf8_len, "length prediction must be correct"); |
335 p = utf8_write(p, base[index]); |
335 return result; |
336 } |
|
337 *p = '\0'; |
|
338 assert(p == &result[utf8_len], "length prediction must be correct"); |
|
339 return (char*) result; |
|
340 } |
336 } |
341 |
337 |
342 char* UNICODE::as_utf8(jchar* base, int length, char* buf, int buflen) { |
338 char* UNICODE::as_utf8(jchar* base, int length, char* buf, int buflen) { |
343 u_char* p = (u_char*)buf; |
339 u_char* p = (u_char*)buf; |
344 u_char* end = (u_char*)buf + buflen; |
|
345 for (int index = 0; index < length; index++) { |
340 for (int index = 0; index < length; index++) { |
346 jchar c = base[index]; |
341 jchar c = base[index]; |
347 if (p + utf8_size(c) >= end) break; // string is truncated |
342 buflen -= utf8_size(c); |
348 p = utf8_write(p, base[index]); |
343 if (buflen <= 0) break; // string is truncated |
|
344 p = utf8_write(p, c); |
349 } |
345 } |
350 *p = '\0'; |
346 *p = '\0'; |
351 return buf; |
347 return buf; |
352 } |
348 } |
353 |
349 |
387 p += 6; |
383 p += 6; |
388 } |
384 } |
389 } |
385 } |
390 *p = '\0'; |
386 *p = '\0'; |
391 } |
387 } |
|
388 |
|
389 #ifndef PRODUCT |
|
390 void TestAsUtf8() { |
|
391 char res[60]; |
|
392 jchar str[20]; |
|
393 |
|
394 for (int i = 0; i < 20; i++) { |
|
395 str[i] = 0x0800; // char that is 2B in UTF-16 but 3B in UTF-8 |
|
396 } |
|
397 str[19] = (jchar)'\0'; |
|
398 |
|
399 // The resulting string in UTF-8 is 3*19 bytes long, but should be truncated |
|
400 UNICODE::as_utf8(str, 19, res, 10); |
|
401 assert(strlen(res) == 9, "string should be truncated here"); |
|
402 |
|
403 UNICODE::as_utf8(str, 19, res, 18); |
|
404 assert(strlen(res) == 15, "string should be truncated here"); |
|
405 |
|
406 UNICODE::as_utf8(str, 19, res, 20); |
|
407 assert(strlen(res) == 18, "string should be truncated here"); |
|
408 |
|
409 // Test with an "unbounded" buffer |
|
410 UNICODE::as_utf8(str, 19, res, INT_MAX); |
|
411 assert(strlen(res) == 3*19, "string should end here"); |
|
412 } |
|
413 #endif |