]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/common/uinvchar.c
ICU-461.12.tar.gz
[apple/icu.git] / icuSources / common / uinvchar.c
index 263c35fc014981bf6ed6740e970f7fb1ea6c0207..d465b2efd41efb1676f4c0b57d917e12a96213dd 100644 (file)
@@ -1,7 +1,7 @@
 /*
 *******************************************************************************
 *
-*   Copyright (C) 1999-2004, International Business Machines
+*   Copyright (C) 1999-2010, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
@@ -145,58 +145,49 @@ static const uint32_t invariantChars[4]={
 /* test signed types for invariant characters, adds test for positive values */
 #define SCHAR_IS_INVARIANT(c) ((0<=(c)) && UCHAR_IS_INVARIANT(c))
 
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+#define CHAR_TO_UCHAR(c) c
+#define UCHAR_TO_CHAR(c) c
+#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+#define CHAR_TO_UCHAR(u) asciiFromEbcdic[u]
+#define UCHAR_TO_CHAR(u) ebcdicFromAscii[u]
+#else
+#   error U_CHARSET_FAMILY is not valid
+#endif
+
+
 U_CAPI void U_EXPORT2
 u_charsToUChars(const char *cs, UChar *us, int32_t length) {
     UChar u;
     uint8_t c;
-    UBool onlyInvariantChars;
 
     /*
      * Allow the entire ASCII repertoire to be mapped _to_ Unicode.
      * For EBCDIC systems, this works for characters with codes from
      * codepages 37 and 1047 or compatible.
      */
-    onlyInvariantChars=TRUE;
     while(length>0) {
         c=(uint8_t)(*cs++);
-#if U_CHARSET_FAMILY==U_ASCII_FAMILY
-        u=(UChar)c;
-#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
-        u=(UChar)asciiFromEbcdic[c];
-#else
-#   error U_CHARSET_FAMILY is not valid
-#endif
-        if(u==0 && c!=0) {
-            onlyInvariantChars=FALSE;
-        }
+        u=(UChar)CHAR_TO_UCHAR(c);
+        U_ASSERT((u!=0 || c==0)); /* only invariant chars converted? */
         *us++=u;
         --length;
     }
-    U_ASSERT(onlyInvariantChars); /* only invariant chars? */
 }
 
 U_CAPI void U_EXPORT2
 u_UCharsToChars(const UChar *us, char *cs, int32_t length) {
     UChar u;
-    UBool onlyInvariantChars;
 
-    onlyInvariantChars=TRUE;
     while(length>0) {
         u=*us++;
         if(!UCHAR_IS_INVARIANT(u)) {
-            onlyInvariantChars=FALSE;
+            U_ASSERT(FALSE); /* Variant characters were used. These are not portable in ICU. */
             u=0;
         }
-#if U_CHARSET_FAMILY==U_ASCII_FAMILY
-        *cs++=(char)u;
-#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
-        *cs++=(char)ebcdicFromAscii[u];
-#else
-#   error U_CHARSET_FAMILY is not valid
-#endif
+        *cs++=(char)UCHAR_TO_CHAR(u);
         --length;
     }
-    U_ASSERT(onlyInvariantChars); /* only invariant chars? */
 }
 
 U_CAPI UBool U_EXPORT2
@@ -232,7 +223,7 @@ uprv_isInvariantString(const char *s, int32_t length) {
             return FALSE; /* found a variant char */
         }
 #elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
-        c=asciiFromEbcdic[c];
+        c=CHAR_TO_UCHAR(c);
         if(c==0 || !UCHAR_IS_INVARIANT(c)) {
             return FALSE; /* found a variant char */
         }
@@ -277,7 +268,7 @@ uprv_isInvariantUString(const UChar *s, int32_t length) {
 /* UDataSwapFn implementations used in udataswp.c ------- */
 
 /* convert ASCII to EBCDIC and verify that all characters are invariant */
-U_CFUNC int32_t
+U_CAPI int32_t U_EXPORT2
 uprv_ebcdicFromAscii(const UDataSwapper *ds,
                      const void *inData, int32_t length, void *outData,
                      UErrorCode *pErrorCode) {
@@ -462,7 +453,7 @@ uprv_compareInvAscii(const UDataSwapper *ds,
 
         c2=*localString++;
         if(!UCHAR_IS_INVARIANT(c2)) {
-            c1=-2;
+            c2=-2;
         }
 
         if((c1-=c2)!=0) {
@@ -509,7 +500,7 @@ uprv_compareInvEbcdic(const UDataSwapper *ds,
 
         c2=*localString++;
         if(!UCHAR_IS_INVARIANT(c2)) {
-            c1=-2;
+            c2=-2;
         }
 
         if((c1-=c2)!=0) {
@@ -522,3 +513,72 @@ uprv_compareInvEbcdic(const UDataSwapper *ds,
     /* strings start with same prefix, compare lengths */
     return outLength-localLength;
 }
+
+U_CAPI int32_t U_EXPORT2
+uprv_compareInvEbcdicAsAscii(const char *s1, const char *s2) {
+    int32_t c1, c2;
+
+    for(;; ++s1, ++s2) {
+        c1=(uint8_t)*s1;
+        c2=(uint8_t)*s2;
+        if(c1!=c2) {
+            if(c1!=0 && ((c1=asciiFromEbcdic[c1])==0 || !UCHAR_IS_INVARIANT(c1))) {
+                c1=-(int32_t)(uint8_t)*s1;
+            }
+            if(c2!=0 && ((c2=asciiFromEbcdic[c2])==0 || !UCHAR_IS_INVARIANT(c2))) {
+                c2=-(int32_t)(uint8_t)*s2;
+            }
+            return c1-c2;
+        } else if(c1==0) {
+            return 0;
+        }
+    }
+}
+
+
+U_INTERNAL uint8_t* U_EXPORT2
+uprv_aestrncpy(uint8_t *dst, const uint8_t *src, int32_t n)
+{
+  uint8_t *orig_dst = dst;
+
+  if(n==-1) { 
+    n = uprv_strlen((const char*)src)+1; /* copy NUL */
+  }
+  /* copy non-null */
+  while(*src && n>0) {
+    *(dst++) = asciiFromEbcdic[*(src++)];
+    n--;
+  }
+  /* pad */
+  while(n>0) {
+    *(dst++) = 0;
+    n--;
+  }
+  return orig_dst;
+}
+
+U_INTERNAL uint8_t* U_EXPORT2
+uprv_eastrncpy(uint8_t *dst, const uint8_t *src, int32_t n)
+{
+  uint8_t *orig_dst = dst;
+
+  if(n==-1) { 
+    n = uprv_strlen((const char*)src)+1; /* copy NUL */
+  }
+  /* copy non-null */
+  while(*src && n>0) {
+    char ch = ebcdicFromAscii[*(src++)];
+    if(ch == 0) {
+      ch = ebcdicFromAscii[0x3f]; /* questionmark (subchar) */
+    }
+    *(dst++) = ch;
+    n--;
+  }
+  /* pad */
+  while(n>0) {
+    *(dst++) = 0;
+    n--;
+  }
+  return orig_dst;
+}
+