| Index: icu51/source/common/ustr_cnv.c
|
| ===================================================================
|
| --- icu51/source/common/ustr_cnv.c (revision 0)
|
| +++ icu51/source/common/ustr_cnv.c (revision 0)
|
| @@ -0,0 +1,253 @@
|
| +/*
|
| +*******************************************************************************
|
| +*
|
| +* Copyright (C) 1998-2010, International Business Machines
|
| +* Corporation and others. All Rights Reserved.
|
| +*
|
| +*******************************************************************************
|
| +* file name: ustr_cnv.c
|
| +* encoding: US-ASCII
|
| +* 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"
|
| +
|
| +/* 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) {
|
| + umtx_lock(NULL);
|
| +
|
| + /* need to check to make sure it wasn't taken out from under us */
|
| + if (gDefaultConverter != NULL) {
|
| + converter = gDefaultConverter;
|
| + gDefaultConverter = NULL;
|
| + }
|
| + 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);
|
| + }
|
| + umtx_lock(NULL);
|
| +
|
| + if(gDefaultConverter == NULL) {
|
| + gDefaultConverter = converter;
|
| + converter = NULL;
|
| + }
|
| + umtx_unlock(NULL);
|
| + }
|
| +
|
| + if(converter != NULL) {
|
| + ucnv_close(converter);
|
| + }
|
| +}
|
| +
|
| +U_CAPI void U_EXPORT2
|
| +u_flushDefaultConverter()
|
| +{
|
| + UConverter *converter = NULL;
|
| +
|
| + if (gDefaultConverter != NULL) {
|
| + umtx_lock(NULL);
|
| +
|
| + /* need to check to make sure it wasn't taken out from under us */
|
| + if (gDefaultConverter != NULL) {
|
| + converter = gDefaultConverter;
|
| + gDefaultConverter = NULL;
|
| + }
|
| + 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
|
|
|
| Property changes on: icu51/source/common/ustr_cnv.c
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|