// // © 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 = NULL;

// U_CAPI UConverter* U_EXPORT2
// u_getDefaultConverter(UErrorCode *status)
// {
//     UConverter *converter = NULL;

//     if (gDefaultConverter != NULL) {
//         icu::umtx_lock(NULL);

//         /* need to check to make sure it wasn't taken out from under us */
//         if (gDefaultConverter != NULL) {
//             converter = gDefaultConverter;
//             gDefaultConverter = NULL;
//         }
//         icu::umtx_unlock(NULL);
//     }

//     /* if the cache was empty, create a converter */
//     if(converter == NULL) {
//         converter = ucnv_open(NULL, status);
//         if(U_FAILURE(*status)) {
//             ucnv_close(converter);
//             converter = NULL;
//         }
//     }

//     return converter;
// }

// U_CAPI void U_EXPORT2
// u_releaseDefaultConverter(UConverter *converter)
// {
//     if(gDefaultConverter == NULL) {
//         if (converter != NULL) {
//             ucnv_reset(converter);
//         }
//         ucnv_enableCleanup();
//         icu::umtx_lock(NULL);
//         if(gDefaultConverter == NULL) {
//             gDefaultConverter = converter;
//             converter = NULL;
//         }
//         icu::umtx_unlock(NULL);
//     }

//     if(converter != NULL) {
//         ucnv_close(converter);
//     }
// }

// U_CAPI void U_EXPORT2
// u_flushDefaultConverter()
// {
//     UConverter *converter = NULL;

//     if (gDefaultConverter != NULL) {
//         icu::umtx_lock(NULL);

//         /* need to check to make sure it wasn't taken out from under us */
//         if (gDefaultConverter != NULL) {
//             converter = gDefaultConverter;
//             gDefaultConverter = NULL;
//         }
//         icu::umtx_unlock(NULL);
//     }

//     /* if the cache was populated, flush it */
//     if(converter != NULL) {
//          ucnv_close(converter);
//     }
// }


// /* conversions between char* and UChar* ------------------------------------- */

// /* 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 UChar*  U_EXPORT2
// u_uastrncpy(UChar *ucs1,
//            const char *s2,
//            int32_t n)
// {
//   UChar *target = ucs1;
//   UErrorCode err = U_ZERO_ERROR;
//   UConverter *cnv = u_getDefaultConverter(&err);
//   if(U_SUCCESS(err) && cnv != NULL) {
//     ucnv_reset(cnv);
//     ucnv_toUnicode(cnv,
//                    &target,
//                    ucs1+n,
//                    &s2,
//                    s2+u_astrnlen(s2, n),
//                    NULL,
//                    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 UChar*  U_EXPORT2
// u_uastrcpy(UChar *ucs1,
//           const char *s2 )
// {
//   UErrorCode err = U_ZERO_ERROR;
//   UConverter *cnv = u_getDefaultConverter(&err);
//   if(U_SUCCESS(err) && cnv != NULL) {
//     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 UChar *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 UChar *ucs2,
//         int32_t n)
// {
//   char *target = s1;
//   UErrorCode err = U_ZERO_ERROR;
//   UConverter *cnv = u_getDefaultConverter(&err);
//   if(U_SUCCESS(err) && cnv != NULL) {
//     ucnv_reset(cnv);
//     ucnv_fromUnicode(cnv,
//                   &target,
//                   s1+n,
//                   &ucs2,
//                   ucs2+u_ustrnlen(ucs2, n),
//                   NULL,
//                   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 UChar *ucs2 )
// {
//   UErrorCode err = U_ZERO_ERROR;
//   UConverter *cnv = u_getDefaultConverter(&err);
//   if(U_SUCCESS(err) && cnv != NULL) {
//     int32_t len = ucnv_fromUChars(cnv,
//                   s1,
//                   MAX_STRLEN,
//                   ucs2,
//                   -1,
//                   &err);
//     u_releaseDefaultConverter(cnv);
//     s1[len] = 0;
//   } else {
//     *s1 = 0;
//   }
//   return s1;
// }

// #endif
