Просмотр исходного кода

Adds create and free interface for CipString2 and CipStringN

Also adds tests accordingly

Signed-off-by: Martin Melik Merkumians <melik-merkumians@acin.tuwien.ac.at>
Martin Melik Merkumians 5 лет назад
Родитель
Сommit
35f64595b0

+ 190 - 22
source/src/cip/cipstring.c

@@ -17,9 +17,138 @@
 #include "trace.h"
 #include "opener_api.h"
 
-CipString *FreeCipString(CipString *const cip_string) {
-  if (NULL != cip_string) {
-    if (NULL != cip_string->string) {
+CipStringN *ClearCipStringN(CipStringN *const cip_string) {
+  if(NULL != cip_string) {
+    if(NULL != cip_string->string) {
+      CipFree(cip_string->string);
+    }
+    cip_string->string = NULL;
+    cip_string->length = 0;
+    cip_string->size = 0;
+  } else {
+    OPENER_TRACE_ERR("Trying to free NULL CipString2!\n");
+  }
+  return cip_string;
+}
+
+void FreeCipStringN(CipStringN *const cip_string) {
+  if(NULL != cip_string) {
+    ClearCipStringN(cip_string);
+    CipFree(cip_string);
+  } else {
+    OPENER_TRACE_ERR("Trying to free NULL CipString2!\n");
+  }
+}
+
+/** @brief Sets length and data for a CipStringN based on an octet stream, symbol length, and symbol width
+ *
+ * @param cip_string The string to be set
+ * @param str_len Amount of CipStringN symbols
+ * @param size Width of the CipStringN symbols
+ * @param data The octet stream
+ *
+ * @return The CipStringN address
+ */
+CipStringN *SetCipStringNByData(CipStringN *const cip_string,
+                                size_t str_len,
+                                size_t size,
+                                const CipOctet *const data) {
+  CipStringN *result = cip_string;
+
+  (void) ClearCipStringN(cip_string);
+
+  if(0 != str_len) {
+    /* No trailing '\0' character! */
+    cip_string->length = str_len;
+    cip_string->size = size;
+    cip_string->string = CipCalloc(cip_string->length,
+                                   cip_string->size * sizeof(CipOctet) );
+    if(NULL == cip_string->string) {
+      result = NULL;
+      cip_string->length = 0;
+      cip_string->size = 0;
+    } else {
+      memcpy(cip_string->string,
+             data,
+             cip_string->length * cip_string->size * sizeof(CipOctet) );
+    }
+  }
+  return result;
+}
+
+CipStringN *SetCipStringNByCstr(CipStringN *const cip_string,
+                                const char *const string,
+                                const size_t symbol_size) {
+  if(0 != strlen(string) % symbol_size) {
+    OPENER_TRACE_ERR("Not enough octets for %d width StringN\n", size);
+    return cip_string;
+  }
+  /* We expect here, that the length of the string is the total length in Octets */
+  return SetCipStringNByData(cip_string,
+                             strlen(string) / symbol_size,
+                             symbol_size,
+                             (const CipOctet *) string);
+}
+
+void FreeCipString2(CipString2 *const cip_string) {
+  if(NULL != cip_string) {
+    ClearCipString2(cip_string);
+    CipFree(cip_string);
+  } else {
+    OPENER_TRACE_ERR("Trying to free NULL CipString2!\n");
+  }
+}
+
+/** @brief Frees a CipString2 structure
+ *
+ * @param cip_string The CipString2 structure to be freed
+ *
+ * @return Freed CipString2 structure
+ *
+ */
+CipString2 *ClearCipString2(CipString2 *const cip_string) {
+  if(NULL != cip_string) {
+    if(NULL != cip_string->string) {
+      CipFree(cip_string->string);
+      cip_string->string = NULL;
+      cip_string->length = 0;
+    }
+  } else {
+    OPENER_TRACE_ERR("Trying to free NULL CipString2!\n");
+  }
+  return cip_string;
+}
+
+CipString2 *SetCipString2ByData(CipString2 *const cip_string,
+                                size_t str_len,
+                                const CipOctet *const data) {
+  CipString2 *result = cip_string;
+
+  (void) ClearCipString2(cip_string);
+
+  if(0 != str_len) {
+    /* No trailing '\0' character! */
+    cip_string->string = CipCalloc(str_len, 2 * sizeof(CipOctet) );
+    if(NULL == cip_string->string) {
+      result = NULL;
+    } else {
+      cip_string->length = str_len;
+      memcpy(cip_string->string, data, str_len * 2 * sizeof(CipOctet) );
+    }
+  }
+  return result;
+}
+
+CipString2 *SetCipString2ByCstr(CipString2 *const cip_string,
+                                const char *const string) {
+  return SetCipString2ByData(cip_string,
+                             strlen(string) / 2,
+                             (const CipOctet *) string);
+}
+
+CipString *ClearCipString(CipString *const cip_string) {
+  if(NULL != cip_string) {
+    if(NULL != cip_string->string) {
       CipFree(cip_string->string);
       cip_string->string = NULL;
       cip_string->length = 0;
@@ -30,18 +159,26 @@ CipString *FreeCipString(CipString *const cip_string) {
   return cip_string;
 }
 
+void FreeCipString(CipString *const cip_string) {
+  if(NULL != cip_string) {
+    ClearCipString(cip_string);
+    CipFree(cip_string);
+  } else {
+    OPENER_TRACE_ERR("Trying to free NULL CipString2!\n");
+  }
+}
 
 CipString *SetCipStringByData(CipString *const cip_string,
                               size_t str_len,
                               const CipOctet *const data) {
   CipString *result = cip_string;
 
-  (void) FreeCipString(cip_string);
+  (void) ClearCipString(cip_string);
 
-  if (0 != str_len) {
-    /* Allocate & clear +1 bytes for the trailing '\0' character. */
-    cip_string->string = CipCalloc(str_len + 1, sizeof (CipOctet));
-    if (NULL == cip_string->string) {
+  if(0 != str_len) {
+    /* No trailing '\0' character. */
+    cip_string->string = CipCalloc(str_len, sizeof(CipOctet) );
+    if(NULL == cip_string->string) {
       result = NULL;
     } else {
       cip_string->length = str_len;
@@ -51,16 +188,16 @@ CipString *SetCipStringByData(CipString *const cip_string,
   return result;
 }
 
-
 CipString *SetCipStringByCstr(CipString *const cip_string,
                               const char *const string) {
-    return SetCipStringByData(cip_string, strlen(string), (const CipOctet*)string);
+  return SetCipStringByData(cip_string,
+                            strlen(string),
+                            (const CipOctet *) string);
 }
 
-
-CipShortString *FreeCipShortString(CipShortString *const cip_string) {
-  if (NULL != cip_string) {
-    if (NULL != cip_string->string) {
+CipShortString *ClearCipShortString(CipShortString *const cip_string) {
+  if(NULL != cip_string) {
+    if(NULL != cip_string->string) {
       CipFree(cip_string->string);
       cip_string->string = NULL;
       cip_string->length = 0;
@@ -71,18 +208,41 @@ CipShortString *FreeCipShortString(CipShortString *const cip_string) {
   return cip_string;
 }
 
+/** @brief Frees a CipShortString structure
+ *
+ * @param cip_string The CipShortString structure to be freed
+ *
+ * @return Freed CipShortString structure
+ *
+ */
+void FreeCipShortString(CipShortString *const cip_string) {
+  if(NULL != cip_string) {
+    ClearCipShortString(cip_string);
+    CipFree(cip_string);
+  } else {
+    OPENER_TRACE_ERR("Trying to free NULL CipString2!\n");
+  }
+}
 
+/** @brief Sets length and data for a CipShortString based on an octet stream and symbol length
+ *
+ * @param cip_string The CipShortString to be set
+ * @param str_len Amount of CipShortString symbols
+ * @param data The octet stream
+ *
+ * @return The CipShortString address
+ */
 CipShortString *SetCipShortStringByData(CipShortString *const cip_string,
                                         size_t str_len,
                                         const CipOctet *const data) {
   CipShortString *result = cip_string;
 
-  (void) FreeCipShortString(cip_string);
+  (void) ClearCipShortString(cip_string);
 
-  if (0 != str_len) {
-    /* Allocate & clear +1 bytes for the trailing '\0' character. */
-    cip_string->string = CipCalloc(str_len + 1, sizeof (CipOctet));
-    if (NULL == cip_string->string) {
+  if(0 != str_len) {
+    /* No trailing '\0' character. */
+    cip_string->string = CipCalloc(str_len, sizeof(CipOctet) );
+    if(NULL == cip_string->string) {
       result = NULL;
     } else {
       cip_string->length = str_len;
@@ -92,9 +252,17 @@ CipShortString *SetCipShortStringByData(CipShortString *const cip_string,
   return result;
 }
 
-
+/** @brief Copies the content of C-string to a CipShortString under the expectation, that each C-String element is a CipShortString octet
+ *
+ * @param cip_string Target CipShortString
+ * @param string Source C-string
+ *
+ * @return Target CipShortString
+ *
+ */
 CipShortString *SetCipShortStringByCstr(CipShortString *const cip_string,
                                         const char *const string) {
-  return SetCipShortStringByData(cip_string, strlen(string),
-                                 (const CipOctet*)string);
+  return SetCipShortStringByData(cip_string,
+                                 strlen(string),
+                                 (const CipOctet *) string);
 }

+ 137 - 3
source/src/cip/cipstring.h

@@ -16,22 +16,156 @@
 #include "typedefs.h"
 #include "ciptypes.h"
 
+CipStringN *SetCipStringNByData(CipStringN *const cip_string,
+                                size_t str_len,
+                                size_t size,
+                                const CipOctet *const data);
 
-CipString *FreeCipString(CipString *const cip_string);
+/** @brief Copies the content of C-string to a CipStringN under the expectation, that each C-String element is a StringN octet
+ *
+ * @param cip_string Target CipStringN
+ * @param string Source C-string
+ * @param symbol_size Size of a symbol in CipStringN instance
+ *
+ * @return Target CipStringN
+ *
+ */
+CipStringN *SetCipStringNByCstr(CipStringN *const cip_string,
+                                const char *const string,
+                                const size_t symbol_size);
+
+/** @brief Clears the internal structure of a CipStringN
+ *
+ * @param cip_string The CipStringN to be freed
+ *
+ * @return Returns the address of the cleared CipStringN
+ *
+ */
+CipStringN *ClearCipStringN(CipStringN *const cip_string);
+
+/** @brief Frees the memory of a CipStringN
+ *
+ * @param cip_string The CipStringN to be freed
+ *
+ */
+void FreeCipStringN(CipStringN *const cip_string);
+
+/** @brief Sets length and data for a CipString2 based on an octet stream and symbol length
+ *
+ * @param cip_string The CipString2 to be set
+ * @param str_len Amount of CipString2 symbols
+ * @param data The octet stream
+ *
+ * @return The CipString2 address
+ */
+CipString2 *SetCipString2ByData(CipString2 *const cip_string,
+                                size_t str_len,
+                                const CipOctet *const data);
+
+/** @brief Copies the content of C-string to a CipString2 under the expectation, that each C-String element is a CipString2 octet
+ *
+ * @param cip_string Target CipString2
+ * @param string Source C-string
+ *
+ * @return Target CipString2
+ *
+ */
+CipString2 *SetCipString2ByCstr(CipString2 *const cip_string,
+                                const char *const string);
+
+/** @brief Clears the internal structure of a CipString2
+ *
+ * @param cip_string The CipString2 to be cleared
+ *
+ * @return Returns the address of the cleared CipString2
+ *
+ */
+CipString2 *ClearCipString2(CipString2 *const cip_string);
+
+/** @brief Frees a CipString2 structure
+ *
+ * @param cip_string The CipString2 structure to be freed
+ *
+ * @return Freed CipString2 structure
+ *
+ */
+void FreeCipString2(CipString2 *const cip_string);
 
+/** @brief Clears the internal CipString structure
+ *
+ * @param cip_string The CipString structure to be cleared
+ *
+ * @return Cleared CipString structure
+ *
+ */
+CipString *ClearCipString(CipString *const cip_string);
+
+/** @brief Frees a CipString structure
+ *
+ * @param cip_string The CipString structure to be freed
+ *
+ */
+void FreeCipString(CipString *const cip_string);
+
+/** @brief Sets length and data for a CipString based on an octet stream and symbol length
+ *
+ * @param cip_string The string to be set
+ * @param str_len Amount of CipString symbols
+ * @param data The octet stream
+ *
+ * @return The CipString address
+ */
 CipString *SetCipStringByData(CipString *const cip_string,
                               size_t str_len,
-                              const EipUint8 *const data);
+                              const CipOctet *const data);
 
+/** @brief Copies the content of C-string to a CipString under the expectation, that each C-String element is a CipString octet
+ *
+ * @param cip_string Target CipString
+ * @param string Source C-string
+ *
+ * @return Target CipString
+ *
+ */
 CipString *SetCipStringByCstr(CipString *const cip_string,
                               const char *const string);
 
-CipShortString *FreeCipShortString(CipShortString *const cip_string);
+/** @brief Clears the internal CipShortString structure
+ *
+ * @param cip_string The CipShortString structure to be cleared
+ *
+ * @return Cleared CipShortString structure
+ *
+ */
+CipShortString *ClearCipShortString(CipShortString *const cip_string);
+
+/** @brief Frees a CipShortString structure
+ *
+ * @param cip_string The CipShortString structure to be freed
+ *
+ */
+void FreeCipShortString(CipShortString *const cip_string);
 
+/** @brief Sets length and data for a CipShortString based on an octet stream and symbol length
+ *
+ * @param cip_string The string to be set
+ * @param str_len Amount of CipString symbols
+ * @param data The octet stream
+ *
+ * @return The CipShortString address
+ */
 CipShortString *SetCipShortStringByData(CipShortString *const cip_string,
                                         size_t str_len,
                                         const CipOctet *const data);
 
+/** @brief Copies the content of C-string to a CipShortString under the expectation, that each C-String element is a CipShortString octet
+ *
+ * @param cip_string Target CipShortString
+ * @param string Source C-string
+ *
+ * @return Target CipShortString
+ *
+ */
 CipShortString *SetCipShortStringByCstr(CipShortString *const cip_string,
                                         const char *const string);
 

+ 12 - 12
source/tests/OpENerTests.h

@@ -1,14 +1,14 @@
 #include "CppUTest/CommandLineTestRunner.h"
 
-IMPORT_TEST_GROUP(RandomClass);
-IMPORT_TEST_GROUP(XorShiftRandom);
-IMPORT_TEST_GROUP(EndianConversion);
-IMPORT_TEST_GROUP(CipCommon);
-IMPORT_TEST_GROUP(CipEpath);
-IMPORT_TEST_GROUP(CipElectronicKey);
-IMPORT_TEST_GROUP(CipConnectionManager);
-IMPORT_TEST_GROUP(CipConnectionObject);
-IMPORT_TEST_GROUP(SocketTimer);
-IMPORT_TEST_GROUP(DoublyLinkedList);
-IMPORT_TEST_GROUP(EncapsulationProtocol);
-IMPORT_TEST_GROUP(UdpProtocol);
+IMPORT_TEST_GROUP (RandomClass);
+IMPORT_TEST_GROUP (XorShiftRandom);
+IMPORT_TEST_GROUP (EndianConversion);
+IMPORT_TEST_GROUP (CipCommon);
+IMPORT_TEST_GROUP (CipEpath);
+IMPORT_TEST_GROUP (CipElectronicKey);
+IMPORT_TEST_GROUP (CipConnectionManager);
+IMPORT_TEST_GROUP (CipConnectionObject);
+IMPORT_TEST_GROUP (SocketTimer);
+IMPORT_TEST_GROUP (DoublyLinkedList);
+IMPORT_TEST_GROUP (EncapsulationProtocol);
+IMPORT_TEST_GROUP (CipString);

+ 1 - 1
source/tests/cip/CMakeLists.txt

@@ -8,7 +8,7 @@ opener_common_includes()
 #######################################
 opener_platform_support("INCLUDES")
 
-set( CipTestSrc cipepathtest.cpp cipelectronickeytest.cpp cipconnectionmanagertest.cpp cipconnectionobjecttest.cpp cipcommontests.cpp)
+set( CipTestSrc cipepathtest.cpp cipelectronickeytest.cpp cipconnectionmanagertest.cpp cipconnectionobjecttest.cpp cipcommontests.cpp cipstringtests.cpp)
 
 include_directories( ${SRC_DIR}/cip )
 

+ 216 - 0
source/tests/cip/cipstringtests.cpp

@@ -0,0 +1,216 @@
+/*******************************************************************************
+* Copyright (c) 2020, Rockwell Automation, Inc.
+* All rights reserved.
+*
+*****************************************************I*************************/
+
+#include <CppUTest/TestHarness.h>
+#include <stdint.h>
+#include <string.h>
+
+extern "C" {
+
+#include "opener_api.h"
+#include "cipstring.h"
+
+}
+
+TEST_GROUP (CipString) {
+
+};
+
+TEST (CipString, CipStringNClearNullPointer) {
+  CipStringN *null_ptr = NULL;
+  ClearCipStringN(null_ptr);
+};
+
+TEST (CipString, CipStringNFreeNullPointer) {
+  CipStringN *null_ptr = NULL;
+  FreeCipStringN(null_ptr);
+};
+
+TEST (CipString, ClearCipStringNWithContent) {
+  CipStringN *string;
+  string = (CipStringN *) CipCalloc(sizeof(CipStringN),1);
+  string->size = 3;
+  string->length = 10;
+  string->string = (EipByte *) CipCalloc(10, 3);
+  CipStringN *returned_ptr = ClearCipStringN(string);
+  POINTERS_EQUAL(string, returned_ptr);
+  CHECK_EQUAL(0, string->size);
+  CHECK_EQUAL(0, string->length);
+  POINTERS_EQUAL(NULL, string->string);
+};
+
+TEST (CipString, FreeCipStringNWithContent) {
+  CipStringN *string;
+  string = (CipStringN *) CipCalloc(sizeof(CipStringN),1);
+  string->size = 3;
+  string->length = 10;
+  string->string = (EipByte *) CipCalloc(10, 3);
+  FreeCipStringN(string);
+};
+
+TEST (CipString, CreateStringNFromData) {
+  const CipOctet data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+  CipStringN *string;
+  string = (CipStringN *) CipCalloc(1, sizeof(CipStringN) );
+  SetCipStringNByData(string, 4, 3, data);
+  CHECK_EQUAL(3, string->size);
+  CHECK_EQUAL(4, string->length);
+  MEMCMP_EQUAL(data, string->string, sizeof(data) );
+}
+
+TEST (CipString, CreateStringNFromCString) {
+  const char data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0};
+  CipStringN *string;
+  string = (CipStringN *) CipCalloc(1, sizeof(CipStringN) );
+  SetCipStringNByCstr(string, data, 3);
+  CHECK_EQUAL(3, string->size);
+  CHECK_EQUAL(4, string->length);
+  MEMCMP_EQUAL(data, string->string, sizeof(data) );
+}
+
+/*** CipString2 ***/
+TEST (CipString, CipString2ClearNullPointer) {
+  CipString2 *null_ptr = NULL;
+  ClearCipString2(null_ptr);
+};
+
+TEST (CipString, CipString2FreeNullPointer) {
+  CipString2 *null_ptr = NULL;
+  FreeCipString2(null_ptr);
+};
+
+TEST (CipString, ClearCipString2WithContent) {
+  CipString2 *string;
+  string = (CipString2 *) CipCalloc(sizeof(CipString2),1);
+  string->length = 10;
+  string->string = (CipWord *) CipCalloc(10, 2);
+  CipString2 *returned_ptr = ClearCipString2(string);
+  POINTERS_EQUAL(string, returned_ptr);
+  CHECK_EQUAL(0, string->length);
+  POINTERS_EQUAL(NULL, string->string);
+};
+
+TEST (CipString, FreeCipString2WithContent) {
+  CipString2 *string;
+  string = (CipString2 *) CipCalloc(sizeof(CipString2),1);
+  string->length = 10;
+  string->string = (CipWord *) CipCalloc(10, 2);
+  FreeCipString2(string);
+};
+
+TEST (CipString, CreateString2FromData) {
+  const CipOctet data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+  CipString2 *string;
+  string = (CipString2 *) CipCalloc(1, sizeof(CipString2) );
+  SetCipString2ByData(string, 6, data);
+  CHECK_EQUAL(6, string->length);
+  MEMCMP_EQUAL(data, string->string, sizeof(data) );
+}
+
+TEST (CipString, CreateString2FromCString) {
+  const char data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0};
+  CipString2 *string;
+  string = (CipString2 *) CipCalloc(1, sizeof(CipString2) );
+  SetCipString2ByCstr(string, data);
+  CHECK_EQUAL(6, string->length);
+  MEMCMP_EQUAL(data, string->string, sizeof(data) );
+}
+
+/*** CipString ***/
+TEST (CipString, CipStringClearNullPointer) {
+  CipString *null_ptr = NULL;
+  ClearCipString(null_ptr);
+};
+
+TEST (CipString, CipStringFreeNullPointer) {
+  CipString *null_ptr = NULL;
+  FreeCipString(null_ptr);
+};
+
+TEST (CipString, ClearCipStringWithContent) {
+  CipString *string;
+  string = (CipString *) CipCalloc(sizeof(CipString),1);
+  string->length = 10;
+  string->string = (CipByte *) CipCalloc(10, 1);
+  CipString *returned_ptr = ClearCipString(string);
+  POINTERS_EQUAL(string, returned_ptr);
+  CHECK_EQUAL(0, string->length);
+  POINTERS_EQUAL(NULL, string->string);
+};
+
+TEST (CipString, FreeCipStringWithContent) {
+  CipString *string;
+  string = (CipString *) CipCalloc(sizeof(CipString),1);
+  string->length = 10;
+  string->string = (CipByte *) CipCalloc(10, 1);
+  FreeCipString(string);
+};
+
+TEST (CipString, CreateStringFromData) {
+  const CipOctet data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+  CipString *string;
+  string = (CipString *) CipCalloc(1, sizeof(CipString) );
+  SetCipStringByData(string, sizeof(data), data);
+  CHECK_EQUAL(12, string->length);
+  MEMCMP_EQUAL(data, string->string, sizeof(data) );
+}
+
+TEST (CipString, CreateStringFromCString) {
+  const char data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0};
+  CipString *string;
+  string = (CipString *) CipCalloc(1, sizeof(CipString) );
+  SetCipStringByCstr(string, data);
+  CHECK_EQUAL(12, string->length);
+  MEMCMP_EQUAL(data, string->string, sizeof(data) );
+}
+
+/*** CipShortString ***/
+TEST (CipString, CipShortStringClearNullPointer) {
+  CipShortString *null_ptr = NULL;
+  ClearCipShortString(null_ptr);
+};
+
+TEST (CipString, CipShortStringFreeNullPointer) {
+  CipShortString *null_ptr = NULL;
+  FreeCipShortString(null_ptr);
+};
+
+TEST (CipString, ClearCipShortStringWithContent) {
+  CipShortString *string;
+  string = (CipShortString *) CipCalloc(sizeof(CipShortString),1);
+  string->length = 10;
+  string->string = (CipByte *) CipCalloc(10, 1);
+  CipShortString *returned_ptr = ClearCipShortString(string);
+  POINTERS_EQUAL(string, returned_ptr);
+  CHECK_EQUAL(0, string->length);
+  POINTERS_EQUAL(NULL, string->string);
+};
+
+TEST (CipString, FreeCipShortStringWithContent) {
+  CipShortString *string;
+  string = (CipShortString *) CipCalloc(sizeof(CipShortString),1);
+  string->length = 10;
+  string->string = (CipByte *) CipCalloc(10, 1);
+  FreeCipShortString(string);
+};
+
+TEST (CipString, CreateShortStringFromData) {
+  const CipOctet data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+  CipShortString *string;
+  string = (CipShortString *) CipCalloc(1, sizeof(CipShortString) );
+  SetCipShortStringByData(string, sizeof(data), data);
+  CHECK_EQUAL(12, string->length);
+  MEMCMP_EQUAL(data, string->string, sizeof(data) );
+}
+
+TEST (CipString, CreateShortStringFromCString) {
+  const char data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0};
+  CipShortString *string;
+  string = (CipShortString *) CipCalloc(1, sizeof(CipShortString) );
+  SetCipShortStringByCstr(string, data);
+  CHECK_EQUAL(12, string->length);
+  MEMCMP_EQUAL(data, string->string, sizeof(data) );
+}