summaryrefslogtreecommitdiffstats
path: root/intl/icu/source/tools/genrb/ustr.c
diff options
context:
space:
mode:
Diffstat (limited to 'intl/icu/source/tools/genrb/ustr.c')
-rw-r--r--intl/icu/source/tools/genrb/ustr.c219
1 files changed, 219 insertions, 0 deletions
diff --git a/intl/icu/source/tools/genrb/ustr.c b/intl/icu/source/tools/genrb/ustr.c
new file mode 100644
index 000000000..07e9b1538
--- /dev/null
+++ b/intl/icu/source/tools/genrb/ustr.c
@@ -0,0 +1,219 @@
+// Copyright (C) 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+*******************************************************************************
+*
+* Copyright (C) 1998-2012, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+*******************************************************************************
+*
+* File ustr.c
+*
+* Modification History:
+*
+* Date Name Description
+* 05/28/99 stephen Creation.
+*******************************************************************************
+*/
+
+#include "ustr.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "unicode/ustring.h"
+#include "unicode/putil.h"
+#include "unicode/utf16.h"
+
+/* Protos */
+static void ustr_resize(struct UString *s, int32_t len, UErrorCode *status);
+
+/* Macros */
+#define ALLOCATION(minSize) (minSize < 0x80 ? 0x80 : (2 * minSize + 0x80) & ~(0x80 - 1))
+
+U_CFUNC void
+ustr_init(struct UString *s)
+{
+ s->fChars = 0;
+ s->fLength = s->fCapacity = 0;
+}
+
+U_CFUNC void
+ustr_initChars(struct UString *s, const char* source, int32_t length, UErrorCode *status)
+{
+ int i = 0;
+ if (U_FAILURE(*status)) return;
+ s->fChars = 0;
+ s->fLength = s->fCapacity = 0;
+ if (length == -1) {
+ length = (int32_t)uprv_strlen(source);
+ }
+ if(s->fCapacity < length) {
+ ustr_resize(s, ALLOCATION(length), status);
+ if(U_FAILURE(*status)) return;
+ }
+ for (; i < length; i++)
+ {
+ UChar charToAppend;
+ u_charsToUChars(source+i, &charToAppend, 1);
+ ustr_ucat(s, charToAppend, status);
+ /*
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+ ustr_ucat(s, (UChar)(uint8_t)(source[i]), status);
+#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+ ustr_ucat(s, (UChar)asciiFromEbcdic[(uint8_t)(*cs++)], status);
+#else
+# error U_CHARSET_FAMILY is not valid
+#endif
+ */
+ }
+}
+
+U_CFUNC void
+ustr_deinit(struct UString *s)
+{
+ if (s) {
+ uprv_free(s->fChars);
+ s->fChars = 0;
+ s->fLength = s->fCapacity = 0;
+ }
+}
+
+U_CFUNC void
+ustr_cpy(struct UString *dst,
+ const struct UString *src,
+ UErrorCode *status)
+{
+ if(U_FAILURE(*status) || dst == src)
+ return;
+
+ if(dst->fCapacity < src->fLength) {
+ ustr_resize(dst, ALLOCATION(src->fLength), status);
+ if(U_FAILURE(*status))
+ return;
+ }
+ if(src->fChars == NULL || dst->fChars == NULL){
+ return;
+ }
+ u_memcpy(dst->fChars, src->fChars, src->fLength);
+ dst->fLength = src->fLength;
+ dst->fChars[dst->fLength] = 0x0000;
+}
+
+U_CFUNC void
+ustr_setlen(struct UString *s,
+ int32_t len,
+ UErrorCode *status)
+{
+ if(U_FAILURE(*status))
+ return;
+
+ if(s->fCapacity < (len + 1)) {
+ ustr_resize(s, ALLOCATION(len), status);
+ if(U_FAILURE(*status))
+ return;
+ }
+
+ s->fLength = len;
+ s->fChars[len] = 0x0000;
+}
+
+U_CFUNC void
+ustr_cat(struct UString *dst,
+ const struct UString *src,
+ UErrorCode *status)
+{
+ ustr_ncat(dst, src, src->fLength, status);
+}
+
+U_CFUNC void
+ustr_ncat(struct UString *dst,
+ const struct UString *src,
+ int32_t n,
+ UErrorCode *status)
+{
+ if(U_FAILURE(*status) || dst == src)
+ return;
+
+ if(dst->fCapacity < (dst->fLength + n)) {
+ ustr_resize(dst, ALLOCATION(dst->fLength + n), status);
+ if(U_FAILURE(*status))
+ return;
+ }
+
+ uprv_memcpy(dst->fChars + dst->fLength, src->fChars,
+ sizeof(UChar) * n);
+ dst->fLength += src->fLength;
+ dst->fChars[dst->fLength] = 0x0000;
+}
+
+U_CFUNC void
+ustr_ucat(struct UString *dst,
+ UChar c,
+ UErrorCode *status)
+{
+ if(U_FAILURE(*status))
+ return;
+
+ if(dst->fCapacity < (dst->fLength + 1)) {
+ ustr_resize(dst, ALLOCATION(dst->fLength + 1), status);
+ if(U_FAILURE(*status))
+ return;
+ }
+
+ uprv_memcpy(dst->fChars + dst->fLength, &c,
+ sizeof(UChar) * 1);
+ dst->fLength += 1;
+ dst->fChars[dst->fLength] = 0x0000;
+}
+U_CFUNC void
+ustr_u32cat(struct UString *dst, UChar32 c, UErrorCode *status){
+ if(c > 0x10FFFF){
+ *status = U_ILLEGAL_CHAR_FOUND;
+ return;
+ }
+ if(c >0xFFFF){
+ ustr_ucat(dst, U16_LEAD(c), status);
+ ustr_ucat(dst, U16_TRAIL(c), status);
+ }else{
+ ustr_ucat(dst, (UChar) c, status);
+ }
+}
+U_CFUNC void
+ustr_uscat(struct UString *dst,
+ const UChar* src,int len,
+ UErrorCode *status)
+{
+ if(U_FAILURE(*status))
+ return;
+
+ if(dst->fCapacity < (dst->fLength + len)) {
+ ustr_resize(dst, ALLOCATION(dst->fLength + len), status);
+ if(U_FAILURE(*status))
+ return;
+ }
+
+ uprv_memcpy(dst->fChars + dst->fLength, src,
+ sizeof(UChar) * len);
+ dst->fLength += len;
+ dst->fChars[dst->fLength] = 0x0000;
+}
+
+/* Destroys data in the string */
+static void
+ustr_resize(struct UString *s,
+ int32_t len,
+ UErrorCode *status)
+{
+ if(U_FAILURE(*status))
+ return;
+
+ /* +1 for trailing 0x0000 */
+ s->fChars = (UChar*) uprv_realloc(s->fChars, sizeof(UChar) * (len + 1));
+ if(s->fChars == 0) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ s->fLength = s->fCapacity = 0;
+ return;
+ }
+
+ s->fCapacity = len;
+}