summaryrefslogtreecommitdiffstats
path: root/intl/icu/source/common/ustr_cnv.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
commit0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch)
treea31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /intl/icu/source/common/ustr_cnv.cpp
parentInitial commit. (diff)
downloadfirefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz
firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'intl/icu/source/common/ustr_cnv.cpp')
-rw-r--r--intl/icu/source/common/ustr_cnv.cpp256
1 files changed, 256 insertions, 0 deletions
diff --git a/intl/icu/source/common/ustr_cnv.cpp b/intl/icu/source/common/ustr_cnv.cpp
new file mode 100644
index 0000000000..abcc12f683
--- /dev/null
+++ b/intl/icu/source/common/ustr_cnv.cpp
@@ -0,0 +1,256 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+*******************************************************************************
+*
+* Copyright (C) 1998-2014, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+*******************************************************************************
+* file name: ustr_cnv.cpp
+* encoding: UTF-8
+* tab size: 8 (not used)
+* indentation:4
+*
+* created on: 2004aug24
+* created by: Markus W. Scherer
+*
+* Character conversion functions moved here from ustring.c
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_CONVERSION
+
+#include "unicode/ustring.h"
+#include "unicode/ucnv.h"
+#include "cstring.h"
+#include "cmemory.h"
+#include "umutex.h"
+#include "ustr_cnv.h"
+#include "ucnv_bld.h"
+
+/* mutexed access to a shared default converter ----------------------------- */
+
+static UConverter *gDefaultConverter = nullptr;
+
+U_CAPI UConverter* U_EXPORT2
+u_getDefaultConverter(UErrorCode *status)
+{
+ UConverter *converter = nullptr;
+
+ if (gDefaultConverter != nullptr) {
+ icu::umtx_lock(nullptr);
+
+ /* need to check to make sure it wasn't taken out from under us */
+ if (gDefaultConverter != nullptr) {
+ converter = gDefaultConverter;
+ gDefaultConverter = nullptr;
+ }
+ icu::umtx_unlock(nullptr);
+ }
+
+ /* if the cache was empty, create a converter */
+ if(converter == nullptr) {
+ converter = ucnv_open(nullptr, status);
+ if(U_FAILURE(*status)) {
+ ucnv_close(converter);
+ converter = nullptr;
+ }
+ }
+
+ return converter;
+}
+
+U_CAPI void U_EXPORT2
+u_releaseDefaultConverter(UConverter *converter)
+{
+ if(gDefaultConverter == nullptr) {
+ if (converter != nullptr) {
+ ucnv_reset(converter);
+ }
+ ucnv_enableCleanup();
+ icu::umtx_lock(nullptr);
+ if(gDefaultConverter == nullptr) {
+ gDefaultConverter = converter;
+ converter = nullptr;
+ }
+ icu::umtx_unlock(nullptr);
+ }
+
+ if(converter != nullptr) {
+ ucnv_close(converter);
+ }
+}
+
+U_CAPI void U_EXPORT2
+u_flushDefaultConverter()
+{
+ UConverter *converter = nullptr;
+
+ if (gDefaultConverter != nullptr) {
+ icu::umtx_lock(nullptr);
+
+ /* need to check to make sure it wasn't taken out from under us */
+ if (gDefaultConverter != nullptr) {
+ converter = gDefaultConverter;
+ gDefaultConverter = nullptr;
+ }
+ icu::umtx_unlock(nullptr);
+ }
+
+ /* if the cache was populated, flush it */
+ if(converter != nullptr) {
+ ucnv_close(converter);
+ }
+}
+
+
+/* conversions between char* and char16_t* ------------------------------------- */
+
+/* maximum string length for u_uastrcpy() and u_austrcpy() implementations */
+#define MAX_STRLEN 0x0FFFFFFF
+
+/*
+ returns the minimum of (the length of the null-terminated string) and n.
+*/
+static int32_t u_astrnlen(const char *s1, int32_t n)
+{
+ int32_t len = 0;
+
+ if (s1)
+ {
+ while (n-- && *(s1++))
+ {
+ len++;
+ }
+ }
+ return len;
+}
+
+U_CAPI char16_t* U_EXPORT2
+u_uastrncpy(char16_t *ucs1,
+ const char *s2,
+ int32_t n)
+{
+ char16_t *target = ucs1;
+ UErrorCode err = U_ZERO_ERROR;
+ UConverter *cnv = u_getDefaultConverter(&err);
+ if(U_SUCCESS(err) && cnv != nullptr) {
+ ucnv_reset(cnv);
+ ucnv_toUnicode(cnv,
+ &target,
+ ucs1+n,
+ &s2,
+ s2+u_astrnlen(s2, n),
+ nullptr,
+ true,
+ &err);
+ ucnv_reset(cnv); /* be good citizens */
+ u_releaseDefaultConverter(cnv);
+ if(U_FAILURE(err) && (err != U_BUFFER_OVERFLOW_ERROR) ) {
+ *ucs1 = 0; /* failure */
+ }
+ if(target < (ucs1+n)) { /* U_BUFFER_OVERFLOW_ERROR isn't an err, just means no termination will happen. */
+ *target = 0; /* terminate */
+ }
+ } else {
+ *ucs1 = 0;
+ }
+ return ucs1;
+}
+
+U_CAPI char16_t* U_EXPORT2
+u_uastrcpy(char16_t *ucs1,
+ const char *s2 )
+{
+ UErrorCode err = U_ZERO_ERROR;
+ UConverter *cnv = u_getDefaultConverter(&err);
+ if(U_SUCCESS(err) && cnv != nullptr) {
+ ucnv_toUChars(cnv,
+ ucs1,
+ MAX_STRLEN,
+ s2,
+ (int32_t)uprv_strlen(s2),
+ &err);
+ u_releaseDefaultConverter(cnv);
+ if(U_FAILURE(err)) {
+ *ucs1 = 0;
+ }
+ } else {
+ *ucs1 = 0;
+ }
+ return ucs1;
+}
+
+/*
+ returns the minimum of (the length of the null-terminated string) and n.
+*/
+static int32_t u_ustrnlen(const char16_t *ucs1, int32_t n)
+{
+ int32_t len = 0;
+
+ if (ucs1)
+ {
+ while (n-- && *(ucs1++))
+ {
+ len++;
+ }
+ }
+ return len;
+}
+
+U_CAPI char* U_EXPORT2
+u_austrncpy(char *s1,
+ const char16_t *ucs2,
+ int32_t n)
+{
+ char *target = s1;
+ UErrorCode err = U_ZERO_ERROR;
+ UConverter *cnv = u_getDefaultConverter(&err);
+ if(U_SUCCESS(err) && cnv != nullptr) {
+ ucnv_reset(cnv);
+ ucnv_fromUnicode(cnv,
+ &target,
+ s1+n,
+ &ucs2,
+ ucs2+u_ustrnlen(ucs2, n),
+ nullptr,
+ true,
+ &err);
+ ucnv_reset(cnv); /* be good citizens */
+ u_releaseDefaultConverter(cnv);
+ if(U_FAILURE(err) && (err != U_BUFFER_OVERFLOW_ERROR) ) {
+ *s1 = 0; /* failure */
+ }
+ if(target < (s1+n)) { /* U_BUFFER_OVERFLOW_ERROR isn't an err, just means no termination will happen. */
+ *target = 0; /* terminate */
+ }
+ } else {
+ *s1 = 0;
+ }
+ return s1;
+}
+
+U_CAPI char* U_EXPORT2
+u_austrcpy(char *s1,
+ const char16_t *ucs2 )
+{
+ UErrorCode err = U_ZERO_ERROR;
+ UConverter *cnv = u_getDefaultConverter(&err);
+ if(U_SUCCESS(err) && cnv != nullptr) {
+ int32_t len = ucnv_fromUChars(cnv,
+ s1,
+ MAX_STRLEN,
+ ucs2,
+ -1,
+ &err);
+ u_releaseDefaultConverter(cnv);
+ s1[len] = 0;
+ } else {
+ *s1 = 0;
+ }
+ return s1;
+}
+
+#endif