/*
******************************************************************************
*
-* Copyright (C) 1998-2003, International Business Machines
+* Copyright (C) 1998-2004, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
*/
#include "unicode/utypes.h"
-#include "unicode/uchar.h"
-#include "unicode/uiter.h"
-#include "unicode/ustring.h"
#include "unicode/putil.h"
-#include "unicode/ucnv.h"
+#include "unicode/ustring.h"
#include "cstring.h"
#include "cwchar.h"
#include "cmemory.h"
-#include "umutex.h"
#include "ustr_imp.h"
-/* forward declaractions of definitions for the shared default converter */
-
-static UConverter *gDefaultConverter = NULL;
-
/* ANSI string.h - style functions ------------------------------------------ */
-/* maximum string length for u_uastrcpy() and u_austrcpy() implementations */
-#define MAX_STRLEN 0x0FFFFFFF
-
/* U+ffff is the highest BMP code point, the highest one that fits into a 16-bit UChar */
#define U_BMP_MAX 0xffff
u_strlen(const UChar *s)
{
#if U_SIZEOF_WCHAR_T == U_SIZEOF_UCHAR
- return uprv_wcslen(s);
+ return (int32_t)uprv_wcslen(s);
#else
const UChar *t = s;
while(*t != 0) {
return uprv_strCompare(s1, count, s2, count, FALSE, TRUE);
}
-/* conversions between char* and UChar* ------------------------------------- */
-
-/*
- returns the minimum of (the length of the null-terminated string) and n.
-*/
-static int32_t u_astrnlen(const char *s1, int32_t n)
-{
- int32_t len = 0;
-
- if (s1)
- {
- while (n-- && *(s1++))
- {
- len++;
- }
- }
- return len;
-}
-
-U_CAPI UChar* U_EXPORT2
-u_uastrncpy(UChar *ucs1,
- const char *s2,
- int32_t n)
-{
- UChar *target = ucs1;
- UErrorCode err = U_ZERO_ERROR;
- UConverter *cnv = u_getDefaultConverter(&err);
- if(U_SUCCESS(err) && cnv != NULL) {
- ucnv_reset(cnv);
- ucnv_toUnicode(cnv,
- &target,
- ucs1+n,
- &s2,
- s2+u_astrnlen(s2, n),
- NULL,
- TRUE,
- &err);
- ucnv_reset(cnv); /* be good citizens */
- u_releaseDefaultConverter(cnv);
- if(U_FAILURE(err) && (err != U_BUFFER_OVERFLOW_ERROR) ) {
- *ucs1 = 0; /* failure */
- }
- if(target < (ucs1+n)) { /* U_BUFFER_OVERFLOW_ERROR isn't an err, just means no termination will happen. */
- *target = 0; /* terminate */
- }
- } else {
- *ucs1 = 0;
- }
- return ucs1;
-}
-
-U_CAPI UChar* U_EXPORT2
-u_uastrcpy(UChar *ucs1,
- const char *s2 )
-{
- UErrorCode err = U_ZERO_ERROR;
- UConverter *cnv = u_getDefaultConverter(&err);
- if(U_SUCCESS(err) && cnv != NULL) {
- ucnv_toUChars(cnv,
- ucs1,
- MAX_STRLEN,
- s2,
- uprv_strlen(s2),
- &err);
- u_releaseDefaultConverter(cnv);
- if(U_FAILURE(err)) {
- *ucs1 = 0;
- }
- } else {
- *ucs1 = 0;
- }
- return ucs1;
-}
-
-/*
- returns the minimum of (the length of the null-terminated string) and n.
-*/
-static int32_t u_ustrnlen(const UChar *ucs1, int32_t n)
-{
- int32_t len = 0;
-
- if (ucs1)
- {
- while (n-- && *(ucs1++))
- {
- len++;
- }
- }
- return len;
-}
-
-U_CAPI char* U_EXPORT2
-u_austrncpy(char *s1,
- const UChar *ucs2,
- int32_t n)
-{
- char *target = s1;
- UErrorCode err = U_ZERO_ERROR;
- UConverter *cnv = u_getDefaultConverter(&err);
- if(U_SUCCESS(err) && cnv != NULL) {
- ucnv_reset(cnv);
- ucnv_fromUnicode(cnv,
- &target,
- s1+n,
- &ucs2,
- ucs2+u_ustrnlen(ucs2, n),
- NULL,
- TRUE,
- &err);
- ucnv_reset(cnv); /* be good citizens */
- u_releaseDefaultConverter(cnv);
- if(U_FAILURE(err) && (err != U_BUFFER_OVERFLOW_ERROR) ) {
- *s1 = 0; /* failure */
- }
- if(target < (s1+n)) { /* U_BUFFER_OVERFLOW_ERROR isn't an err, just means no termination will happen. */
- *target = 0; /* terminate */
- }
- } else {
- *s1 = 0;
- }
- return s1;
-}
-
-U_CAPI char* U_EXPORT2
-u_austrcpy(char *s1,
- const UChar *ucs2 )
-{
- UErrorCode err = U_ZERO_ERROR;
- UConverter *cnv = u_getDefaultConverter(&err);
- if(U_SUCCESS(err) && cnv != NULL) {
- int32_t len = ucnv_fromUChars(cnv,
- s1,
- MAX_STRLEN,
- ucs2,
- -1,
- &err);
- u_releaseDefaultConverter(cnv);
- s1[len] = 0;
- } else {
- *s1 = 0;
- }
- return s1;
-}
-
-/* mutexed access to a shared default converter ----------------------------- */
-
-U_CAPI UConverter* U_EXPORT2
-u_getDefaultConverter(UErrorCode *status)
-{
- UConverter *converter = NULL;
-
- if (gDefaultConverter != NULL) {
- umtx_lock(NULL);
-
- /* need to check to make sure it wasn't taken out from under us */
- if (gDefaultConverter != NULL) {
- converter = gDefaultConverter;
- gDefaultConverter = NULL;
- }
- umtx_unlock(NULL);
- }
-
- /* if the cache was empty, create a converter */
- if(converter == NULL) {
- converter = ucnv_open(NULL, status);
- if(U_FAILURE(*status)) {
- return NULL;
- }
- }
-
- return converter;
-}
-
-U_CAPI void U_EXPORT2
-u_releaseDefaultConverter(UConverter *converter)
-{
- if(gDefaultConverter == NULL) {
- if (converter != NULL) {
- ucnv_reset(converter);
- }
- umtx_lock(NULL);
-
- if(gDefaultConverter == NULL) {
- gDefaultConverter = converter;
- converter = NULL;
- }
- umtx_unlock(NULL);
- }
-
- if(converter != NULL) {
- ucnv_close(converter);
- }
-}
-
/* u_unescape & support fns ------------------------------------------------- */
/* This map must be in ASCENDING ORDER OF THE ESCAPE CODE */
}
++(*offset);
}
+ if (result < 0 || result >= 0x110000) {
+ goto err;
+ }
+ /* If an escape sequence specifies a lead surrogate, see if
+ * there is a trail surrogate after it, either as an escape or
+ * as a literal. If so, join them up into a supplementary.
+ */
+ if (*offset < length && U16_IS_LEAD(result)) {
+ int32_t ahead = *offset + 1;
+ c = charAt(*offset, context);
+ if (c == 0x5C /*'\\'*/ && ahead < length) {
+ c = (UChar) u_unescapeAt(charAt, &ahead, length, context);
+ }
+ if (U16_IS_TRAIL(c)) {
+ *offset = ahead;
+ result = U16_GET_SUPPLEMENTARY(result, c);
+ }
+ }
return result;
}