You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@etch.apache.org by fi...@apache.org on 2012/08/02 17:03:47 UTC

svn commit: r1368507 - in /incubator/etch/trunk/binding-cpp/runtime: include/common/ lib/capu/modules/capu/include/capu/os/arch/Windows/ src/main/common/ src/main/serialization/ src/test/common/ src/test/serialization/

Author: fitzner
Date: Thu Aug  2 15:03:46 2012
New Revision: 1368507

URL: http://svn.apache.org/viewvc?rev=1368507&view=rev
Log:
ETCH-149 Enhanced UTF8 Support

EtchString modifications for UTF8 support

Change-Id: Idacf1dd320ba9143b9bf32ba9072f7e11f55f75b

Modified:
    incubator/etch/trunk/binding-cpp/runtime/include/common/EtchString.h
    incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/os/arch/Windows/StringUtils.inc
    incubator/etch/trunk/binding-cpp/runtime/src/main/common/EtchString.cpp
    incubator/etch/trunk/binding-cpp/runtime/src/main/serialization/EtchBinaryTaggedDataInput.cpp
    incubator/etch/trunk/binding-cpp/runtime/src/main/serialization/EtchBinaryTaggedDataOutput.cpp
    incubator/etch/trunk/binding-cpp/runtime/src/test/common/EtchStringTest.cpp
    incubator/etch/trunk/binding-cpp/runtime/src/test/serialization/EtchBinaryTaggedDataInputOutputTest.cpp

Modified: incubator/etch/trunk/binding-cpp/runtime/include/common/EtchString.h
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-cpp/runtime/include/common/EtchString.h?rev=1368507&r1=1368506&r2=1368507&view=diff
==============================================================================
--- incubator/etch/trunk/binding-cpp/runtime/include/common/EtchString.h (original)
+++ incubator/etch/trunk/binding-cpp/runtime/include/common/EtchString.h Thu Aug  2 15:03:46 2012
@@ -19,9 +19,9 @@
 #ifndef __ETCHSTRING_H__
 #define __ETCHSTRING_H__
 
+#include "common/EtchError.h"
 #include "common/EtchObject.h"
 #include "common/EtchObjectType.h"
-#include "util/EtchUtil.h"
 
 /**
  * String type.
@@ -152,9 +152,15 @@ public:
    */
   capu::uint32_t getHashCode() const;
 
-private:
+  /**
+   * Returns number of bytes
+   */
+  capu::uint32_t getNumBytes() const;
 
+private:
   char* mData;
+  capu::uint32_t mDataSize;
+  capu::uint32_t mEncoding;
 };
 
 typedef capu::SmartPointer<EtchString> EtchStringPtr;

Modified: incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/os/arch/Windows/StringUtils.inc
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/os/arch/Windows/StringUtils.inc?rev=1368507&r1=1368506&r2=1368507&view=diff
==============================================================================
--- incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/os/arch/Windows/StringUtils.inc (original)
+++ incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/os/arch/Windows/StringUtils.inc Thu Aug  2 15:03:46 2012
@@ -32,7 +32,7 @@ private:
   inline void StringUtils::Strncpy(char* dst, uint_t dstSize, const char* src)
   {
 
-    strcpy_s(dst, dstSize, src);
+    memcpy(dst, src, dstSize);
   }
 
   inline uint_t StringUtils::Strlen(const char* str)

Modified: incubator/etch/trunk/binding-cpp/runtime/src/main/common/EtchString.cpp
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-cpp/runtime/src/main/common/EtchString.cpp?rev=1368507&r1=1368506&r2=1368507&view=diff
==============================================================================
--- incubator/etch/trunk/binding-cpp/runtime/src/main/common/EtchString.cpp (original)
+++ incubator/etch/trunk/binding-cpp/runtime/src/main/common/EtchString.cpp Thu Aug  2 15:03:46 2012
@@ -16,73 +16,135 @@
  * limitations under the License.
  */
 
+#include "capu/os/StringUtils.h"
 #include "common/EtchString.h"
+#include "util/EtchUtil.h"
+
+static capu::uint32_t ENCODING_ASCII = 0;
+static capu::uint32_t ENCODING_UTF8  = 1;
 
 const EtchObjectType* EtchString::TYPE() {
   const static EtchObjectType TYPE(EOTID_STRING, NULL);
   return &TYPE;
 }
 
+// TODO: String should support UTF-8 by default
+
 EtchString::EtchString()
 : EtchObject(EtchString::TYPE())
-, mData(NULL) {
-  //ETCH_LOG("EtchString: ", EtchLogLevel::Error, "dies ist ein Test");
+, mData(NULL), mDataSize(0), mEncoding(ENCODING_ASCII) {
 }
 
 EtchString::EtchString(const char* string)
 : EtchObject(EtchString::TYPE())
-, mData(NULL) {
+, mData(NULL), mDataSize(0), mEncoding(ENCODING_ASCII) {
   if (string != NULL) {
-    capu::int32_t len = strlen(string);
+    capu::uint32_t len = capu::StringUtils::Strlen(string);
     mData = new char[len + 1];
+    // TODO: refactor this to use capu
     etch_strcpy_s(mData, len + 1, string);
   }
 }
 
 EtchString::EtchString(const capu::int8_t* buffer, const capu::int32_t bufferSize, EtchString encoding)
 : EtchObject(EtchString::TYPE())
-, mData(NULL) {
-  if (buffer != NULL) {
-    mData = new char[bufferSize + 1];
-    etch_strcpy_s(mData, bufferSize + 1, (char*)buffer);
+, mData(NULL), mDataSize(0), mEncoding(ENCODING_ASCII) {
+
+  EtchString enc("utf-8");
+  if (encoding.equals(&enc)) {
+    mEncoding = ENCODING_UTF8;
+    mDataSize = bufferSize;
+    if (buffer != NULL) {
+      //utf8
+      // TODO: refactor this an use a utf-8 strncpy function from capu
+      mData = new char[bufferSize + 1];
+      capu::StringUtils::Strncpy(mData, bufferSize, (const char*)buffer);
+      mData [bufferSize] = 0x0;
+    }
+  } else {
+    if (buffer != NULL) {
+      //ascii
+      capu::uint32_t len = capu::StringUtils::Strlen((const char*) buffer);
+      mData = new char[len + 1];
+      // TODO: refactor this to use capu
+      etch_strcpy_s(mData, len + 1, (const char*) buffer);
+    }
   }
 }
 
-
 EtchString::EtchString(const EtchString &copy)
-: EtchObject(EtchString::TYPE()) {
+: EtchObject(EtchString::TYPE()), mDataSize(copy.mDataSize), mEncoding(copy.mEncoding) {
   if (copy.mData == NULL)
     return;
-  capu::int32_t len = strlen(copy.mData);
-  mData = new char [len + 1];
-  etch_strcpy_s(mData, len + 1, copy.mData);
+  if (mEncoding != ENCODING_UTF8) {
+    //ascii
+    capu::int32_t len = capu::StringUtils::Strlen(copy.mData);
+    mData = new char [len + 1];
+    // TODO: refactor this to use capu
+    etch_strcpy_s(mData, len + 1, copy.mData);
+  } else {
+    //utf8
+    // TODO: refactor this to use capu utf-8 strncpy
+    mData = new char [copy.mDataSize + 1];
+    capu::StringUtils::Strncpy(mData, copy.mDataSize, copy.mData);
+    mData[copy.mDataSize] = 0x0;
+  }
 }
 
+
 EtchString& EtchString::operator=(const char *str) {
+  // TODO: refactor this
   if (this->mData != str) {
-    set(str);
+    if (mEncoding == ENCODING_UTF8) {
+      //utf8
+      if (mData != NULL) {
+        delete[] mData;
+        mData = NULL;
+      }
+      if (str != NULL) {
+        mDataSize = capu::StringUtils::Strlen(str);
+        mData = new char[mDataSize + 1];
+        capu::StringUtils::Strncpy(mData, mDataSize, str);
+        mData[mDataSize] = 0x0;
+      }
+    } else {
+      set(str);
+    }
   }
   return *this;
 }
 
 void EtchString::set(const char* string, capu::uint32_t len) {
+  // TODO: refactor this
   if (mData != NULL) {
     delete[] mData;
     mData = NULL;
   }
   if (string != NULL) {
-    if (strlen(string) < len)
+    if (capu::StringUtils::Strlen(string) < len)
       return;
     capu::int32_t length = len;
     mData = new char[length + 1];
     etch_strcpy_s(mData, length + 1, string);
   }
-
 }
 
 EtchString& EtchString::operator=(const EtchString &str) {
+  // TODO: refactor this
   if (this != &str) {
-    set(str.mData);
+    if (mEncoding == ENCODING_UTF8) {
+      //utf8
+      if (mData != NULL) {
+        delete[] mData;
+        mData = NULL;
+      }
+      mData = new char [str.mDataSize];
+      capu::StringUtils::Strncpy(mData, str.mDataSize, str.mData);
+      mDataSize = str.mDataSize;
+    } else {
+      //ascii
+      set(str.mData);
+    }
   }
   return *this;
 }
@@ -100,31 +162,51 @@ void EtchString::set(const char* string)
     mData = NULL;
   }
   if (string != NULL) {
-    capu::int32_t len = strlen(string);
+    capu::int32_t len = capu::StringUtils::Strlen(string);
     mData = new char[len + 1];
     etch_strcpy_s(mData, len + 1, string);
   }
 }
 
 capu::int32_t EtchString::length() const {
-  return strlen(mData);
+  // TODO: refactor this
+  if (mEncoding != ENCODING_UTF8) {
+    return capu::StringUtils::Strlen(mData);
+  } else {
+    capu::int32_t result = 0;
+    etch_strlen_utf8(mData, result);
+    return result;
+  }
 }
 
-const char* EtchString::c_str() const{
+const char* EtchString::c_str() const {
   return mData;
 }
 
-capu::bool_t EtchString::equals(const EtchObject* other) const{
+capu::bool_t EtchString::equals(const EtchObject * other) const {
+  // TODO: refactor this
   if (other == NULL)
     return false;
   else if (!other->getObjectType()->equals(EtchString::TYPE()))
     return false;
-  if (strcmp(((EtchString*) other)->mData, this->mData) == 0)
-    return true;
+  if (mEncoding != ENCODING_UTF8 && (((EtchString*)other)->mEncoding != ENCODING_UTF8)) {
+    //ascii
+    if (capu::StringUtils::Strcmp(((EtchString*) other)->mData, this->mData) == 0)
+      return true;
+  } else if (mEncoding == ENCODING_UTF8 && (((EtchString*)other)->mEncoding == ENCODING_UTF8)) {
+    //utf8
+    if (strncmp(((EtchString*) other)->mData, this->mData, mDataSize) == 0)
+      return true;
+  }
   return false;
 }
 
 capu::int32_t EtchString::rightFind(const char c) {
+  if (mEncoding == ENCODING_UTF8) {
+    //utf8
+    //TODO: Implementation needed
+    return -1;
+  }
   const char * str = this->c_str();
   capu::int32_t index = -1;
   char* ch = strchr((char *) str, c);
@@ -136,6 +218,11 @@ capu::int32_t EtchString::rightFind(cons
 }
 
 capu::int32_t EtchString::leftFind(const char c) {
+  if (mEncoding == ENCODING_UTF8) {
+    //utf8
+    //TODO: Implementation needed
+    return -1;
+  }
   const char * str = this->c_str();
   capu::int32_t index = -1;
   char* ch = strchr((char*) str, c);
@@ -146,8 +233,13 @@ capu::int32_t EtchString::leftFind(const
   return index;
 }
 
-status_t EtchString::substring(capu::uint32_t start, capu::uint32_t length, EtchString *dest) {
-  capu::uint32_t len = strlen(this->mData);
+status_t EtchString::substring(capu::uint32_t start, capu::uint32_t length, EtchString * dest) {
+  if (mEncoding == ENCODING_UTF8) {
+    //utf8
+    //TODO: Implementation needed
+    return ETCH_EUNIMPL;
+  }
+  capu::uint32_t len = capu::StringUtils::Strlen(this->mData);
   if (start >= len || len < (start + length) || dest == NULL) {
     return ETCH_EINVAL;
   } else {
@@ -156,9 +248,17 @@ status_t EtchString::substring(capu::uin
   }
 }
 
-capu::uint32_t EtchString::getHashCode() const{
+capu::uint32_t EtchString::getHashCode() const {
   capu::uint32_t result = 0;
-  capu::uint32_t len = strlen(mData);
+  capu::uint32_t len = 0;
+  if (mEncoding != ENCODING_UTF8) {
+    //ascii
+    len = capu::StringUtils::Strlen(mData);
+  } else {
+    //utf8
+    len = mDataSize;
+  }
+
   for (capu::uint32_t i = 0; i < len; i++) {
     result = (result + static_cast<capu::uint32_t> (mData[i]) * 13);
   }
@@ -172,8 +272,16 @@ status_t EtchString::getBytes(capu::int8
   }
 
   *buffer = new capu::int8_t[length() + 1];
-  memcpy(*buffer,mData,length() + 1);
+  memcpy(*buffer, mData, length() + 1);
   *bufferSize = length() + 1;
 
   return ETCH_OK;
 }
+
+capu::uint32_t EtchString::getNumBytes() const {
+  if (mEncoding == ENCODING_UTF8) {
+    return mDataSize;
+  } else {
+    return capu::StringUtils::Strlen(mData);
+  }
+}

Modified: incubator/etch/trunk/binding-cpp/runtime/src/main/serialization/EtchBinaryTaggedDataInput.cpp
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-cpp/runtime/src/main/serialization/EtchBinaryTaggedDataInput.cpp?rev=1368507&r1=1368506&r2=1368507&view=diff
==============================================================================
--- incubator/etch/trunk/binding-cpp/runtime/src/main/serialization/EtchBinaryTaggedDataInput.cpp (original)
+++ incubator/etch/trunk/binding-cpp/runtime/src/main/serialization/EtchBinaryTaggedDataInput.cpp Thu Aug  2 15:03:46 2012
@@ -249,8 +249,8 @@ status_t EtchBinaryTaggedDataInput::read
   if (obj->getObjectType()->equals(EtchInt32::TYPE())) {
     EtchInt32* id = (EtchInt32*) obj.get();
     if (mVf->getType(id->get(), type) != ETCH_OK) {
-      char num[11];
-      capu::StringUtils::Sprintf(num, 11, "%d", id->get());
+      char num[100];
+      capu::StringUtils::Sprintf(num, 100, "%d", id->get());
       EtchString str(num);
       type = new EtchType(id->get(), str);
       //TODO: Enhance memory management. We need smartpointers here because we create new object sometimes
@@ -284,8 +284,8 @@ status_t EtchBinaryTaggedDataInput::read
     EtchInt32* id = (EtchInt32*) obj.get();
 
     if (type->getField(id->get(), &field) != ETCH_OK) {
-      char num[11];
-      capu::StringUtils::Sprintf(num, 11, "%d", id->get());
+      char num[100];
+      capu::StringUtils::Sprintf(num, 100, "%d", id->get());
       EtchString str(num);
       EtchField f(id->get(), str);
       //TODO: Create field on heap and use smartpointers
@@ -549,7 +549,7 @@ status_t EtchBinaryTaggedDataInput::read
     }
     case EtchTypeCode::EMPTY_STRING:
     {
-      EtchString *str = new EtchString("");
+      EtchString *str = new EtchString(NULL, 0, mVf->getStringEncoding());
       if (validateValue(v, str, result) != ETCH_OK) {
         delete str;
         return ETCH_ERROR;
@@ -570,6 +570,7 @@ status_t EtchBinaryTaggedDataInput::read
         return ETCH_ERROR;
 
       capu::SmartPointer<EtchString> str = new EtchString(buffer, bufferSize, mVf->getStringEncoding());
+      delete [] buffer;
       ret = validateValue(v, str, result);
       if (ret != ETCH_OK) {
         return ETCH_ERROR;
@@ -624,4 +625,4 @@ status_t EtchBinaryTaggedDataInput::read
     return ETCH_ERROR;
   }
   return ETCH_OK;
-}
\ No newline at end of file
+}

Modified: incubator/etch/trunk/binding-cpp/runtime/src/main/serialization/EtchBinaryTaggedDataOutput.cpp
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-cpp/runtime/src/main/serialization/EtchBinaryTaggedDataOutput.cpp?rev=1368507&r1=1368506&r2=1368507&view=diff
==============================================================================
--- incubator/etch/trunk/binding-cpp/runtime/src/main/serialization/EtchBinaryTaggedDataOutput.cpp (original)
+++ incubator/etch/trunk/binding-cpp/runtime/src/main/serialization/EtchBinaryTaggedDataOutput.cpp Thu Aug  2 15:03:46 2012
@@ -327,19 +327,8 @@ status_t EtchBinaryTaggedDataOutput::wri
     }
     case EtchTypeCode::STRING:
     {
-      status_t ret;
-      //UTF-8 SUPPORT IS NOT IMPLEMENTED YET
-      capu::int8_t *buffer = NULL;
-      capu::int32_t bufferSize = 0;
-      EtchString *tmp = (EtchString*) value.get();
-      ret = tmp->getBytes(&buffer,&bufferSize);
-      if (ret != ETCH_OK) {
-        delete[] buffer;
-        return ret;
-      }
-      ret = writeBytes(buffer,bufferSize);
-      delete[] buffer;
-      return ret;
+      capu::SmartPointer<EtchString> str = capu::smartpointer_cast<EtchString > (value);
+      return writeBytes((capu::int8_t*)str->c_str(), str->getNumBytes());
     }
     case EtchTypeCode::CUSTOM:
     {

Modified: incubator/etch/trunk/binding-cpp/runtime/src/test/common/EtchStringTest.cpp
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-cpp/runtime/src/test/common/EtchStringTest.cpp?rev=1368507&r1=1368506&r2=1368507&view=diff
==============================================================================
--- incubator/etch/trunk/binding-cpp/runtime/src/test/common/EtchStringTest.cpp (original)
+++ incubator/etch/trunk/binding-cpp/runtime/src/test/common/EtchStringTest.cpp Thu Aug  2 15:03:46 2012
@@ -135,4 +135,67 @@ TEST(EtchStringTest, substringTest) {
   result = str1.substring(str1.length() - 1, 1, &tmp);
   EXPECT_TRUE(result == ETCH_OK);
   EXPECT_TRUE(strcmp("3", tmp.c_str()) == 0);
+}
+
+TEST(EtchStringTest, UTF8_Constructor_Default) {
+  const capu::uint8_t utf8 [] = {0xF0, 0xA4, 0xAD, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA2, 0x24};
+  EtchString* s1 = new EtchString((capu::int8_t*)utf8, 10, "utf-8");
+  EXPECT_TRUE(s1->getObjectType()->equals(EtchString::TYPE()));
+  EXPECT_TRUE(s1->c_str() != NULL);
+  delete s1;
+}
+
+TEST(EtchStringTest, UTF8_Assignment_Test) {
+  const capu::uint8_t utf8 [] = {0xF0, 0xA4, 0xAD, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA2, 0x24};
+  EtchString* s1 = new EtchString(NULL, 0, "utf-8");
+  *s1 = (const char*)utf8;
+  EXPECT_TRUE(s1->c_str() != NULL);
+  EXPECT_TRUE(strncmp(s1->c_str(), (const char*)utf8, 10) == 0);
+  delete s1;
+}
+//
+
+TEST(EtchStringTest, UTF8_len_test) {
+  const capu::uint8_t utf8 [] = {0xF0, 0xA4, 0xAD, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA2, 0x24};
+  EtchString *s = new EtchString((capu::int8_t*)utf8, 10, "utf-8");
+  EXPECT_TRUE(s->getNumBytes() == 10);
+  EXPECT_TRUE(s->length() == 4);
+  delete s;
+}
+
+TEST(EtchStringTest, UTF8_equalsTest) {
+  const capu::uint8_t utf8_1 [] = {0xF0, 0xA4, 0xAD, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA2, 0x24};
+  const capu::uint8_t utf8_2 [] = {0xF0, 0xA4, 0xAD, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA2, 0x24};
+  const capu::uint8_t utf8_3 [] = {0xF0, 0xA4, 0xAD, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA2, 0x25};
+  EtchString str1((capu::int8_t*)utf8_1, 10, "utf-8");
+  EtchString str2((capu::int8_t*)utf8_2, 10, "utf-8");
+  EtchString str3((capu::int8_t*)utf8_3, 10, "utf-8");
+
+  EXPECT_TRUE(str1.equals(&str2));
+  EXPECT_FALSE(str1.equals(&str3));
+}
+
+TEST(EtchStringTest, UTF8_leftFindTest) {
+  //not supported
+  const capu::uint8_t utf8_1 [] = {0xF0, 0xA4, 0xAD, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA2, 0x24};
+  EtchString str1((capu::int8_t*)utf8_1, 10, "utf-8");
+  capu::int32_t index = str1.leftFind(':');
+  EXPECT_TRUE(index == -1);
+}
+
+TEST(EtchStringTest, UTF8_rightFindTest) {
+  const capu::uint8_t utf8_1 [] = {0xF0, 0xA4, 0xAD, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA2, 0x24};
+  EtchString str1((capu::int8_t*)utf8_1, 10, "utf-8");
+  capu::int32_t index = str1.rightFind(':');
+  EXPECT_TRUE(index == -1);
+}
+
+TEST(EtchStringTest, UTF8_substringTest) {
+  const capu::uint8_t utf8_1 [] = {0xF0, 0xA4, 0xAD, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA2, 0x24};
+  EtchString str1((capu::int8_t*)utf8_1, 10, "utf-8");
+
+  EtchString tmp;
+  status_t result;
+  result = str1.substring(0, 5, &tmp);
+  EXPECT_TRUE(result == ETCH_EUNIMPL);
 }
\ No newline at end of file

Modified: incubator/etch/trunk/binding-cpp/runtime/src/test/serialization/EtchBinaryTaggedDataInputOutputTest.cpp
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-cpp/runtime/src/test/serialization/EtchBinaryTaggedDataInputOutputTest.cpp?rev=1368507&r1=1368506&r2=1368507&view=diff
==============================================================================
--- incubator/etch/trunk/binding-cpp/runtime/src/test/serialization/EtchBinaryTaggedDataInputOutputTest.cpp (original)
+++ incubator/etch/trunk/binding-cpp/runtime/src/test/serialization/EtchBinaryTaggedDataInputOutputTest.cpp Thu Aug  2 15:03:46 2012
@@ -433,6 +433,31 @@ TEST(EtchBinaryTaggedDataInputTest, int_
   Utility::test(content4, val, false);
 }
 
+TEST(EtchBinaryTaggedDataInputTest, string_serialization) {
+  const capu::uint8_t utf8_1 [] = {0xF0, 0xA4, 0xAD, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA2, 0x24, 0x0};
+  const capu::uint8_t utf8_2 [] = {0xF0, 0xA4, 0xAD, 0xA2, 0xE2, 0x82, 0xAC, 0xC2, 0xA2, 0x25, 0x0};
+  capu::SmartPointer<EtchNativeArray<capu::SmartPointer<EtchString> > > carray1 = new EtchNativeArray<capu::SmartPointer<EtchString> > (2, 2);
+  carray1->createArray(0, 2);
+  carray1->createArray(1, 2);
+  capu::SmartPointer<EtchString> content1 = new EtchString((capu::int8_t*)utf8_1, 11, "utf-8");
+  capu::SmartPointer<EtchString> content2 = new EtchString((capu::int8_t*)utf8_2, 11, "utf-8");
+  capu::SmartPointer<EtchString> content3 = new EtchString((capu::int8_t*)utf8_1, 11, "utf-8");
+  capu::SmartPointer<EtchString> content4 = new EtchString((capu::int8_t*)utf8_2, 11, "utf-8");
+  carray1->set(Pos(0, 0), content1);
+  carray1->set(Pos(0, 1), content2);
+  carray1->set(Pos(1, 0), content3);
+  carray1->set(Pos(1, 1), content4);
+
+  capu::SmartPointer<EtchValidator> val = NULL;
+  EtchValidatorString::Get(2, val);
+  Utility::test(carray1, val, false);
+  EtchValidatorString::Get(0, val);
+  Utility::test(content1, val, false);
+  Utility::test(content2, val, false);
+  Utility::test(content3, val, false);
+  Utility::test(content4, val, false);
+}
+
 TEST(EtchBinaryTaggedDataInputTest, long_serialization) {
   capu::SmartPointer<EtchNativeArray<capu::SmartPointer<EtchLong> > > carray1 = new EtchNativeArray<capu::SmartPointer<EtchLong> > (2, 2);
   carray1->createArray(0, 2);
@@ -535,7 +560,7 @@ TEST(EtchBinaryTaggedDataInputTest, doub
 }
 
 TEST(EtchBinaryTaggedDataInputTest, empty_string_serialization) {
-  capu::SmartPointer<EtchString> str = new EtchString("");
+  capu::SmartPointer<EtchString> str = new EtchString(NULL, 0, "utf-8");
   capu::SmartPointer<EtchValidator> val = NULL;
   EtchValidatorString::Get(0, val);
   Utility::test(str, val, false);
@@ -777,9 +802,7 @@ TEST(EtchBinaryTaggedDataInputTest, btdo
 
 TEST(EtchBinaryTaggedDataInputTest, null_write) {
   capu::int8_t byte_pos[] = {3, 1, 0, -127};
-
   capu::SmartPointer<EtchValidator> val = NULL;
-
   EtchValidatorObject::Get(0, val);
   Utility::test_bto_write(NULL, byte_pos, val);
 }