scuffed-code/icu4c/source/common/ustring.c

336 lines
6.6 KiB
C
Raw Normal View History

1999-08-16 21:50:52 +00:00
/*
*******************************************************************************
*
* Copyright (C) 1998-1999, International Business Machines
* Corporation and others. All Rights Reserved.
*
1999-08-16 21:50:52 +00:00
*******************************************************************************
*
* File ustring.h
*
* Modification History:
*
* Date Name Description
* 12/07/98 bertrand Creation.
*******************************************************************************
*/
#include "unicode/ustring.h"
#include "unicode/utypes.h"
1999-08-16 21:50:52 +00:00
#include "cstring.h"
#include "umutex.h"
#include "unicode/ucnv.h"
1999-08-16 21:50:52 +00:00
/* forward declaractions of definitions for the shared default converter */
1999-08-16 21:50:52 +00:00
static UConverter *fgDefaultConverter = NULL;
1999-08-16 21:50:52 +00:00
static UConverter*
getDefaultConverter(void);
static void
releaseDefaultConverter(UConverter *converter);
1999-08-16 21:50:52 +00:00
/* ANSI string.h - style functions ------------------------------------------ */
#define MAX_STRLEN 0x0FFFFFFF
1999-08-16 21:50:52 +00:00
UChar*
u_strcat(UChar *dst,
const UChar *src)
{
UChar *anchor = dst; /* save a pointer to start of dst */
while(*dst != 0) { /* To end of first string */
++dst;
}
while((*dst = *src) != 0) { /* copy string 2 over */
++dst;
++src;
}
1999-08-16 21:50:52 +00:00
return anchor;
}
UChar*
u_strncat(UChar *dst,
const UChar *src,
int32_t n )
{
if(n > 0) {
UChar *anchor = dst; /* save a pointer to start of dst */
while(*dst != 0) { /* To end of first string */
++dst;
}
while((*dst = *src) != 0) { /* copy string 2 over */
++dst;
if(--n == 0) {
*dst = 0;
break;
}
++src;
}
1999-08-16 21:50:52 +00:00
return anchor;
} else {
return dst;
}
1999-08-16 21:50:52 +00:00
}
UChar*
u_strchr(const UChar *s,
UChar c)
{
while(*s != 0) {
if(*s == c) {
return (UChar *)s;
}
++s;
}
1999-08-16 21:50:52 +00:00
return NULL;
}
U_CAPI UChar * U_EXPORT2
u_strstr(const UChar *s, const UChar *substring) {
if(*substring == 0) {
return (UChar *)s;
} else if(substring[1] == 0) {
return u_strchr(s, *substring);
} else {
/* ### TBD */
return NULL;
}
}
U_CAPI UChar * U_EXPORT2
u_strchr32(const UChar *s, UChar32 c) {
if(!UTF_NEED_MULTIPLE_UCHAR(c)) {
return u_strchr(s, (UChar)c);
} else {
UChar buffer[UTF_MAX_CHAR_LENGTH + 1];
UTextOffset i = 0;
UTF_APPEND_CHAR_UNSAFE(buffer, i, c);
buffer[i] = 0;
return u_strstr(s, buffer);
}
}
1999-08-16 21:50:52 +00:00
int32_t
u_strcmp(const UChar *s1,
const UChar *s2)
{
int32_t rc;
for(;;) {
rc = (int32_t)*s1 - (int32_t)*s2;
if(rc != 0 || *s1 == 0) {
return rc;
}
++s1;
++s2;
1999-08-16 21:50:52 +00:00
}
}
int32_t
u_strncmp(const UChar *s1,
const UChar *s2,
int32_t n)
{
if(n > 0) {
int32_t rc;
for(;;) {
rc = (int32_t)*s1 - (int32_t)*s2;
if(rc != 0 || *s1 == 0 || --n == 0) {
return rc;
}
++s1;
++s2;
}
} else {
return 0;
1999-08-16 21:50:52 +00:00
}
}
UChar*
u_strcpy(UChar *dst,
const UChar *src)
{
UChar *anchor = dst; /* save a pointer to start of dst */
while((*dst = *src) != 0) { /* copy string 2 over */
++dst;
++src;
}
1999-08-16 21:50:52 +00:00
return anchor;
}
UChar*
u_strncpy(UChar *dst,
const UChar *src,
int32_t n)
{
UChar *anchor = dst; /* save a pointer to start of dst */
if(n > 0) {
while((*dst = *src) != 0) { /* copy string 2 over */
++dst;
if(--n == 0) {
*dst = 0;
break;
}
++src;
}
} else {
*dst = 0;
}
1999-08-16 21:50:52 +00:00
return anchor;
}
int32_t
u_strlen(const UChar *s)
{
# if U_SIZEOF_WCHAR_T == U_SIZEOF_UCHAR
return uprv_wcslen(s);
# else
const UChar *t = s;
while(*t != 0) {
++t;
}
return t - s;
#endif
1999-08-16 21:50:52 +00:00
}
/* conversions between char* and UChar* ------------------------------------- */
1999-08-16 21:50:52 +00:00
UChar* u_uastrcpy(UChar *ucs1,
const char *s2 )
{
UConverter *cnv = getDefaultConverter();
if(cnv != NULL) {
UErrorCode err = U_ZERO_ERROR;
ucnv_toUChars(cnv,
ucs1,
MAX_STRLEN,
s2,
uprv_strlen(s2),
&err);
releaseDefaultConverter(cnv);
if(U_FAILURE(err)) {
*ucs1 = 0;
}
} else {
*ucs1 = 0;
}
1999-08-16 21:50:52 +00:00
return ucs1;
}
UChar* u_uastrncpy(UChar *ucs1,
const char *s2 ,
int32_t n)
{
UChar *target = ucs1;
UConverter *cnv = getDefaultConverter();
if(cnv != NULL) {
UErrorCode err = U_ZERO_ERROR;
ucnv_reset(cnv);
ucnv_toUnicode(cnv,
&target,
ucs1+n,
&s2,
s2+uprv_strlen(s2),
NULL,
TRUE,
&err);
ucnv_reset(cnv); /* be good citizens */
releaseDefaultConverter(cnv);
if(U_FAILURE(err) && (err != U_INDEX_OUTOFBOUNDS_ERROR) ) {
*ucs1 = 0; /* failure */
}
if(target < (ucs1+n)) { /* Indexoutofbounds isn't an err, just means no termination will happen. */
*target = 0; /* terminate */
}
} else {
*ucs1 = 0;
}
1999-08-16 21:50:52 +00:00
return ucs1;
}
char* u_austrcpy(char *s1,
const UChar *ucs2 )
{
UConverter *cnv = getDefaultConverter();
if(cnv != NULL) {
UErrorCode err = U_ZERO_ERROR;
int32_t len = ucnv_fromUChars(cnv,
s1,
MAX_STRLEN,
ucs2,
-1,
&err);
releaseDefaultConverter(cnv);
s1[len] = 0;
} else {
*s1 = 0;
}
1999-08-16 21:50:52 +00:00
return s1;
}
/* mutexed access to a shared default converter ----------------------------- */
/* this is the same implementation as in unistr.cpp */
static UConverter*
getDefaultConverter()
{
UConverter *converter = NULL;
if(fgDefaultConverter != NULL) {
umtx_lock(NULL);
/* need to check to make sure it wasn't taken out from under us */
if(fgDefaultConverter != NULL) {
converter = fgDefaultConverter;
fgDefaultConverter = NULL;
}
umtx_unlock(NULL);
}
/* if the cache was empty, create a converter */
if(converter == NULL) {
UErrorCode status = U_ZERO_ERROR;
converter = ucnv_open(NULL, &status);
if(U_FAILURE(status)) {
return NULL;
}
}
return converter;
}
static void
releaseDefaultConverter(UConverter *converter)
{
if(fgDefaultConverter == NULL) {
umtx_lock(NULL);
if(fgDefaultConverter == NULL) {
fgDefaultConverter = converter;
converter = NULL;
}
umtx_unlock(NULL);
}
if(converter != NULL) {
ucnv_close(converter);
}
}
U_CAPI int32_t U_EXPORT2
u_unescapeChars(const char *s,
UChar *dest, int32_t destSize) {
/* ### TBD */
return 0;
}