]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/common/ustring.c
ICU-8.11.4.tar.gz
[apple/icu.git] / icuSources / common / ustring.c
index a8fef5b111398cbe39d0be84dfb44dd8a75899c6..cb7fd706309ec93c0481508f170175a4ae239db1 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ******************************************************************************
 *
-*   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
 
@@ -1001,7 +990,7 @@ U_CAPI int32_t   U_EXPORT2
 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) {
@@ -1166,200 +1155,6 @@ u_memcmpCodePointOrder(const UChar *s1, const UChar *s2, int32_t count) {
     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 */
@@ -1478,6 +1273,24 @@ u_unescapeAt(UNESCAPE_CHAR_AT charAt,
             }
             ++(*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;
     }