]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/common/uniset.cpp
ICU-59173.0.1.tar.gz
[apple/icu.git] / icuSources / common / uniset.cpp
index 676c855d1f0f8a649b36f7199e441a4bdab3d027..fe5a157aa6bf51e0abde864b6caad3fe3c31fac2 100644 (file)
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 1999-2012, International Business Machines
+*   Copyright (C) 1999-2015, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   Date        Name        Description
@@ -234,7 +236,7 @@ UnicodeSet::UnicodeSet(const UnicodeSet& o, UBool /* asThawed */) :
     if(list!=NULL){
         // *this = o except for bmpSet and stringSpan
         len = o.len;
-        uprv_memcpy(list, o.list, len*sizeof(UChar32));
+        uprv_memcpy(list, o.list, (size_t)len*sizeof(UChar32));
         if (strings != NULL && o.strings != NULL) {
             strings->assign(*o.strings, cloneUnicodeString, status);
         } else { // Invalid strings.
@@ -286,7 +288,7 @@ UnicodeSet& UnicodeSet::operator=(const UnicodeSet& o) {
         return *this; // There is no way to report this error :-(
     }
     len = o.len;
-    uprv_memcpy(list, o.list, len*sizeof(UChar32));
+    uprv_memcpy(list, o.list, (size_t)len*sizeof(UChar32));
     if (o.bmpSet == NULL) {
         bmpSet = NULL;
     } else {
@@ -1253,14 +1255,14 @@ UnicodeSet& UnicodeSet::complement(void) {
         if (U_FAILURE(status)) {
             return *this;
         }
-        uprv_memcpy(buffer, list + 1, (len-1)*sizeof(UChar32));
+        uprv_memcpy(buffer, list + 1, (size_t)(len-1)*sizeof(UChar32));
         --len;
     } else {
         ensureBufferCapacity(len+1, status);
         if (U_FAILURE(status)) {
             return *this;
         }
-        uprv_memcpy(buffer + 1, list, len*sizeof(UChar32));
+        uprv_memcpy(buffer + 1, list, (size_t)len*sizeof(UChar32));
         buffer[0] = UNICODESET_LOW;
         ++len;
     }
@@ -1468,6 +1470,72 @@ UnicodeSet& UnicodeSet::compact() {
     return *this;
 }
 
+#ifdef DEBUG_SERIALIZE
+#include <stdio.h>
+#endif
+
+/**
+ * Deserialize constructor.
+ */
+UnicodeSet::UnicodeSet(const uint16_t data[], int32_t dataLen, ESerialization serialization, UErrorCode &ec)
+  : len(1), capacity(1+START_EXTRA), list(0), bmpSet(0), buffer(0),
+    bufferCapacity(0), patLen(0), pat(NULL), strings(NULL), stringSpan(NULL),
+    fFlags(0) {
+
+  if(U_FAILURE(ec)) {
+    setToBogus();
+    return;
+  }
+
+  if( (serialization != kSerialized)
+      || (data==NULL)
+      || (dataLen < 1)) {
+    ec = U_ILLEGAL_ARGUMENT_ERROR;
+    setToBogus();
+    return;
+  }
+
+  allocateStrings(ec);
+  if (U_FAILURE(ec)) {
+    setToBogus();
+    return;
+  }
+
+  // bmp?
+  int32_t headerSize = ((data[0]&0x8000)) ?2:1;
+  int32_t bmpLength = (headerSize==1)?data[0]:data[1];
+
+  len = (((data[0]&0x7FFF)-bmpLength)/2)+bmpLength;
+#ifdef DEBUG_SERIALIZE
+  printf("dataLen %d headerSize %d bmpLen %d len %d. data[0]=%X/%X/%X/%X\n", dataLen,headerSize,bmpLength,len, data[0],data[1],data[2],data[3]);
+#endif
+  capacity = len+1;
+  list = (UChar32*) uprv_malloc(sizeof(UChar32) * capacity);
+  if(!list || U_FAILURE(ec)) {
+    setToBogus();
+    return;
+  }
+  // copy bmp
+  int32_t i;
+  for(i = 0; i< bmpLength;i++) {
+    list[i] = data[i+headerSize];
+#ifdef DEBUG_SERIALIZE
+    printf("<<16@%d[%d] %X\n", i+headerSize, i, list[i]);
+#endif
+  }
+  // copy smp
+  for(i=bmpLength;i<len;i++) {
+    list[i] = ((UChar32)data[headerSize+bmpLength+(i-bmpLength)*2+0] << 16) +
+              ((UChar32)data[headerSize+bmpLength+(i-bmpLength)*2+1]);
+#ifdef DEBUG_SERIALIZE
+    printf("<<32@%d+[%d] %lX\n", headerSize+bmpLength+i, i, list[i]);
+#endif
+  }
+  // terminator
+  list[len++]=UNICODESET_HIGH;
+}
+
+
 int32_t UnicodeSet::serialize(uint16_t *dest, int32_t destCapacity, UErrorCode& ec) const {
     int32_t bmpLength, length, destLength;
 
@@ -1506,7 +1574,9 @@ int32_t UnicodeSet::serialize(uint16_t *dest, int32_t destCapacity, UErrorCode&
         for (bmpLength=0; bmpLength<length && this->list[bmpLength]<=0xffff; ++bmpLength) {}
         length=bmpLength+2*(length-bmpLength);
     }
-
+#ifdef DEBUG_SERIALIZE
+    printf(">> bmpLength%d length%d len%d\n", bmpLength, length, len);
+#endif
     /* length: number of 16-bit array units */
     if (length>0x7fff) {
         /* there are only 15 bits for the length in the first serialized word */
@@ -1525,6 +1595,9 @@ int32_t UnicodeSet::serialize(uint16_t *dest, int32_t destCapacity, UErrorCode&
         const UChar32 *p;
         int32_t i;
 
+#ifdef DEBUG_SERIALIZE
+        printf("writeHdr\n");
+#endif
         *dest=(uint16_t)length;
         if (length>bmpLength) {
             *dest|=0x8000;
@@ -1535,11 +1608,17 @@ int32_t UnicodeSet::serialize(uint16_t *dest, int32_t destCapacity, UErrorCode&
         /* write the BMP part of the array */
         p=this->list;
         for (i=0; i<bmpLength; ++i) {
+#ifdef DEBUG_SERIALIZE
+          printf("writebmp: %x\n", (int)*p);
+#endif
             *dest++=(uint16_t)*p++;
         }
 
         /* write the supplementary part of the array */
         for (; i<length; i+=2) {
+#ifdef DEBUG_SERIALIZE
+          printf("write32: %x\n", (int)*p);
+#endif
             *dest++=(uint16_t)(*p>>16);
             *dest++=(uint16_t)*p++;
         }