mirror of https://github.com/lukechilds/node.git
Browse Source
The previous commit removed the dependency on the code in that directory. This commit removes the directory itself and shrinks the source tarball by about 200 kB. PR-URL: https://github.com/nodejs/node/pull/13656 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com>v6
21 changed files with 0 additions and 7291 deletions
@ -1,109 +0,0 @@ |
|||
// Do not edit with Microsoft Developer Studio Resource Editor. |
|||
// It will permanently substitute version numbers that are intended to be |
|||
// picked up by the pre-processor during each build. |
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others. |
|||
// License & terms of use: http://www.unicode.org/copyright.html |
|||
// Copyright (c) 2001-2010 International Business Machines |
|||
// Corporation and others. All Rights Reserved. |
|||
// |
|||
#include "../common/msvcres.h" |
|||
|
|||
#define APSTUDIO_READONLY_SYMBOLS |
|||
///////////////////////////////////////////////////////////////////////////// |
|||
// |
|||
// Generated from the TEXTINCLUDE 2 resource. |
|||
// |
|||
#include <winresrc.h> |
|||
///////////////////////////////////////////////////////////////////////////// |
|||
#undef APSTUDIO_READONLY_SYMBOLS |
|||
|
|||
///////////////////////////////////////////////////////////////////////////// |
|||
// |
|||
|
|||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL |
|||
#pragma code_page(1252) |
|||
|
|||
#ifdef APSTUDIO_INVOKED |
|||
///////////////////////////////////////////////////////////////////////////// |
|||
// |
|||
// TEXTINCLUDE |
|||
// |
|||
|
|||
1 TEXTINCLUDE |
|||
BEGIN |
|||
"../../common/msvcres.h\0" |
|||
END |
|||
|
|||
2 TEXTINCLUDE |
|||
BEGIN |
|||
"#include <winresrc.h>\0" |
|||
END |
|||
|
|||
3 TEXTINCLUDE |
|||
BEGIN |
|||
"\r\n" |
|||
"\0" |
|||
END |
|||
|
|||
#endif // APSTUDIO_INVOKED |
|||
|
|||
|
|||
///////////////////////////////////////////////////////////////////////////// |
|||
// |
|||
// Version |
|||
// |
|||
#define STR(s) #s |
|||
#define CommaVersionString(a, b, c, d) STR(a) ", " STR(b) ", " STR(c) ", " STR(d) "\0" |
|||
|
|||
VS_VERSION_INFO VERSIONINFO |
|||
FILEVERSION U_ICU_VERSION_MAJOR_NUM, U_ICU_VERSION_MINOR_NUM, U_ICU_VERSION_PATCHLEVEL_NUM, U_ICU_VERSION_BUILDLEVEL_NUM |
|||
PRODUCTVERSION U_ICU_VERSION_MAJOR_NUM, U_ICU_VERSION_MINOR_NUM, U_ICU_VERSION_PATCHLEVEL_NUM, U_ICU_VERSION_BUILDLEVEL_NUM |
|||
FILEFLAGSMASK 0x3fL |
|||
#ifdef _DEBUG |
|||
FILEFLAGS 0x1L |
|||
#else |
|||
FILEFLAGS 0x0L |
|||
#endif |
|||
FILEOS VOS__WINDOWS32 |
|||
FILETYPE VFT_DLL |
|||
FILESUBTYPE 0x0L |
|||
BEGIN |
|||
BLOCK "StringFileInfo" |
|||
BEGIN |
|||
BLOCK "00000000" |
|||
BEGIN |
|||
VALUE "Comments", ICU_WEBSITE "\0" |
|||
VALUE "CompanyName", ICU_COMPANY "\0" |
|||
VALUE "FileDescription", ICU_PRODUCT_PREFIX " I/O DLL\0" |
|||
VALUE "FileVersion", CommaVersionString(U_ICU_VERSION_MAJOR_NUM, U_ICU_VERSION_MINOR_NUM, U_ICU_VERSION_PATCHLEVEL_NUM, U_ICU_VERSION_BUILDLEVEL_NUM) |
|||
VALUE "LegalCopyright", U_COPYRIGHT_STRING "\0" |
|||
#ifdef _DEBUG |
|||
VALUE "OriginalFilename", "icuio" U_ICU_VERSION_SHORT "d.dll\0" |
|||
#else |
|||
VALUE "OriginalFilename", "icuio" U_ICU_VERSION_SHORT ".dll\0" |
|||
#endif |
|||
VALUE "PrivateBuild", "\0" |
|||
VALUE "ProductName", ICU_PRODUCT "\0" |
|||
VALUE "ProductVersion", CommaVersionString(U_ICU_VERSION_MAJOR_NUM, U_ICU_VERSION_MINOR_NUM, U_ICU_VERSION_PATCHLEVEL_NUM, U_ICU_VERSION_BUILDLEVEL_NUM) |
|||
VALUE "SpecialBuild", "\0" |
|||
END |
|||
END |
|||
BLOCK "VarFileInfo" |
|||
BEGIN |
|||
VALUE "Translation", 0x000, 0000 |
|||
END |
|||
END |
|||
|
|||
///////////////////////////////////////////////////////////////////////////// |
|||
|
|||
|
|||
|
|||
#ifndef APSTUDIO_INVOKED |
|||
///////////////////////////////////////////////////////////////////////////// |
|||
// |
|||
// Generated from the TEXTINCLUDE 3 resource. |
|||
// |
|||
|
|||
|
|||
///////////////////////////////////////////////////////////////////////////// |
|||
#endif // not APSTUDIO_INVOKED |
@ -1,185 +0,0 @@ |
|||
// © 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 locbund.cpp |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 11/18/98 stephen Creation. |
|||
* 12/10/1999 bobbyr(at)optiosoftware.com Fix for memory leak + string allocation bugs |
|||
******************************************************************************* |
|||
*/ |
|||
|
|||
#include "unicode/utypes.h" |
|||
|
|||
#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_CONVERSION |
|||
|
|||
#include "locbund.h" |
|||
|
|||
#include "cmemory.h" |
|||
#include "cstring.h" |
|||
#include "ucln_io.h" |
|||
#include "mutex.h" |
|||
#include "umutex.h" |
|||
#include "unicode/ustring.h" |
|||
#include "unicode/uloc.h" |
|||
|
|||
static UNumberFormat *gPosixNumberFormat[ULOCALEBUNDLE_NUMBERFORMAT_COUNT]; |
|||
|
|||
U_CDECL_BEGIN |
|||
static UBool U_CALLCONV locbund_cleanup(void) { |
|||
int32_t style; |
|||
for (style = 0; style < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; style++) { |
|||
unum_close(gPosixNumberFormat[style]); |
|||
gPosixNumberFormat[style] = NULL; |
|||
} |
|||
return TRUE; |
|||
} |
|||
U_CDECL_END |
|||
|
|||
static UMutex gLock = U_MUTEX_INITIALIZER; |
|||
static inline UNumberFormat * copyInvariantFormatter(ULocaleBundle *result, UNumberFormatStyle style) { |
|||
U_NAMESPACE_USE |
|||
Mutex lock(&gLock); |
|||
if (result->fNumberFormat[style-1] == NULL) { |
|||
if (gPosixNumberFormat[style-1] == NULL) { |
|||
UErrorCode status = U_ZERO_ERROR; |
|||
UNumberFormat *formatAlias = unum_open(style, NULL, 0, "en_US_POSIX", NULL, &status); |
|||
if (U_SUCCESS(status)) { |
|||
gPosixNumberFormat[style-1] = formatAlias; |
|||
ucln_io_registerCleanup(UCLN_IO_LOCBUND, locbund_cleanup); |
|||
} |
|||
} |
|||
/* Copy the needed formatter. */ |
|||
if (gPosixNumberFormat[style-1] != NULL) { |
|||
UErrorCode status = U_ZERO_ERROR; |
|||
result->fNumberFormat[style-1] = unum_clone(gPosixNumberFormat[style-1], &status); |
|||
} |
|||
} |
|||
return result->fNumberFormat[style-1]; |
|||
} |
|||
|
|||
U_CAPI ULocaleBundle * |
|||
u_locbund_init(ULocaleBundle *result, const char *loc) |
|||
{ |
|||
int32_t len; |
|||
|
|||
if(result == 0) |
|||
return 0; |
|||
|
|||
if (loc == NULL) { |
|||
loc = uloc_getDefault(); |
|||
} |
|||
|
|||
uprv_memset(result, 0, sizeof(ULocaleBundle)); |
|||
|
|||
len = (int32_t)strlen(loc); |
|||
result->fLocale = (char*) uprv_malloc(len + 1); |
|||
if(result->fLocale == 0) { |
|||
return 0; |
|||
} |
|||
|
|||
uprv_strcpy(result->fLocale, loc); |
|||
|
|||
result->isInvariantLocale = uprv_strcmp(result->fLocale, "en_US_POSIX") == 0; |
|||
|
|||
return result; |
|||
} |
|||
|
|||
/*U_CAPI ULocaleBundle *
|
|||
u_locbund_new(const char *loc) |
|||
{ |
|||
ULocaleBundle *result = (ULocaleBundle*) uprv_malloc(sizeof(ULocaleBundle)); |
|||
return u_locbund_init(result, loc); |
|||
} |
|||
|
|||
U_CAPI ULocaleBundle * |
|||
u_locbund_clone(const ULocaleBundle *bundle) |
|||
{ |
|||
ULocaleBundle *result = (ULocaleBundle*)uprv_malloc(sizeof(ULocaleBundle)); |
|||
UErrorCode status = U_ZERO_ERROR; |
|||
int32_t styleIdx; |
|||
|
|||
if(result == 0) |
|||
return 0; |
|||
|
|||
result->fLocale = (char*) uprv_malloc(strlen(bundle->fLocale) + 1); |
|||
if(result->fLocale == 0) { |
|||
uprv_free(result); |
|||
return 0; |
|||
} |
|||
|
|||
strcpy(result->fLocale, bundle->fLocale ); |
|||
|
|||
for (styleIdx = 0; styleIdx < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; styleIdx++) { |
|||
status = U_ZERO_ERROR; |
|||
if (result->fNumberFormat[styleIdx]) { |
|||
result->fNumberFormat[styleIdx] = unum_clone(bundle->fNumberFormat[styleIdx], &status); |
|||
if (U_FAILURE(status)) { |
|||
result->fNumberFormat[styleIdx] = NULL; |
|||
} |
|||
} |
|||
else { |
|||
result->fNumberFormat[styleIdx] = NULL; |
|||
} |
|||
} |
|||
result->fDateFormat = (bundle->fDateFormat == 0 ? 0 : |
|||
udat_clone(bundle->fDateFormat, &status)); |
|||
result->fTimeFormat = (bundle->fTimeFormat == 0 ? 0 : |
|||
udat_clone(bundle->fTimeFormat, &status)); |
|||
|
|||
return result; |
|||
}*/ |
|||
|
|||
U_CAPI void |
|||
u_locbund_close(ULocaleBundle *bundle) |
|||
{ |
|||
int32_t styleIdx; |
|||
|
|||
uprv_free(bundle->fLocale); |
|||
|
|||
for (styleIdx = 0; styleIdx < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; styleIdx++) { |
|||
if (bundle->fNumberFormat[styleIdx]) { |
|||
unum_close(bundle->fNumberFormat[styleIdx]); |
|||
} |
|||
} |
|||
|
|||
uprv_memset(bundle, 0, sizeof(ULocaleBundle)); |
|||
/* uprv_free(bundle);*/ |
|||
} |
|||
|
|||
U_CAPI UNumberFormat * |
|||
u_locbund_getNumberFormat(ULocaleBundle *bundle, UNumberFormatStyle style) |
|||
{ |
|||
UNumberFormat *formatAlias = NULL; |
|||
if (style > UNUM_IGNORE) { |
|||
formatAlias = bundle->fNumberFormat[style-1]; |
|||
if (formatAlias == NULL) { |
|||
if (bundle->isInvariantLocale) { |
|||
formatAlias = copyInvariantFormatter(bundle, style); |
|||
} |
|||
else { |
|||
UErrorCode status = U_ZERO_ERROR; |
|||
formatAlias = unum_open(style, NULL, 0, bundle->fLocale, NULL, &status); |
|||
if (U_FAILURE(status)) { |
|||
unum_close(formatAlias); |
|||
formatAlias = NULL; |
|||
} |
|||
else { |
|||
bundle->fNumberFormat[style-1] = formatAlias; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return formatAlias; |
|||
} |
|||
|
|||
#endif /* #if !UCONFIG_NO_FORMATTING */ |
@ -1,82 +0,0 @@ |
|||
// © 2016 and later: Unicode, Inc. and others.
|
|||
// License & terms of use: http://www.unicode.org/copyright.html
|
|||
/*
|
|||
******************************************************************************* |
|||
* |
|||
* Copyright (C) 1998-2011, International Business Machines |
|||
* Corporation and others. All Rights Reserved. |
|||
* |
|||
******************************************************************************* |
|||
* |
|||
* File locbund.h |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 10/16/98 stephen Creation. |
|||
* 02/25/99 stephen Modified for new C API. |
|||
******************************************************************************* |
|||
*/ |
|||
|
|||
#ifndef LOCBUND_H |
|||
#define LOCBUND_H |
|||
|
|||
#include "unicode/utypes.h" |
|||
|
|||
#if !UCONFIG_NO_FORMATTING |
|||
|
|||
#include "unicode/unum.h" |
|||
|
|||
#define ULOCALEBUNDLE_NUMBERFORMAT_COUNT ((int32_t)UNUM_SPELLOUT) |
|||
|
|||
typedef struct ULocaleBundle { |
|||
char *fLocale; |
|||
|
|||
UNumberFormat *fNumberFormat[ULOCALEBUNDLE_NUMBERFORMAT_COUNT]; |
|||
UBool isInvariantLocale; |
|||
} ULocaleBundle; |
|||
|
|||
|
|||
/**
|
|||
* Initialize a ULocaleBundle, initializing all formatters to 0. |
|||
* @param result A ULocaleBundle to initialize. |
|||
* @param loc The locale of the ULocaleBundle. |
|||
* @return A pointer to a ULocaleBundle, or 0 if <TT>loc</TT> was invalid. |
|||
*/ |
|||
U_CAPI ULocaleBundle * |
|||
u_locbund_init(ULocaleBundle *result, const char *loc); |
|||
|
|||
/**
|
|||
* Create a new ULocaleBundle, initializing all formatters to 0. |
|||
* @param loc The locale of the ULocaleBundle. |
|||
* @return A pointer to a ULocaleBundle, or 0 if <TT>loc</TT> was invalid. |
|||
*/ |
|||
/*U_CAPI ULocaleBundle *
|
|||
u_locbund_new(const char *loc);*/ |
|||
|
|||
/**
|
|||
* Create a deep copy of this ULocaleBundle; |
|||
* @param bundle The ULocaleBundle to clone. |
|||
* @return A new ULocaleBundle. |
|||
*/ |
|||
/*U_CAPI ULocaleBundle *
|
|||
u_locbund_clone(const ULocaleBundle *bundle);*/ |
|||
|
|||
/**
|
|||
* Delete the specified ULocaleBundle, freeing all associated memory. |
|||
* @param bundle The ULocaleBundle to delete |
|||
*/ |
|||
U_CAPI void |
|||
u_locbund_close(ULocaleBundle *bundle); |
|||
|
|||
/**
|
|||
* Get the NumberFormat used to format and parse numbers in a ULocaleBundle. |
|||
* @param bundle The ULocaleBundle to use |
|||
* @return A pointer to the NumberFormat used for number formatting and parsing. |
|||
*/ |
|||
U_CAPI UNumberFormat * |
|||
u_locbund_getNumberFormat(ULocaleBundle *bundle, UNumberFormatStyle style); |
|||
|
|||
#endif /* #if !UCONFIG_NO_FORMATTING */ |
|||
|
|||
#endif |
@ -1,261 +0,0 @@ |
|||
// © 2016 and later: Unicode, Inc. and others.
|
|||
// License & terms of use: http://www.unicode.org/copyright.html
|
|||
/*
|
|||
****************************************************************************** |
|||
* |
|||
* Copyright (C) 2001-2014, International Business Machines |
|||
* Corporation and others. All Rights Reserved. |
|||
* |
|||
****************************************************************************** |
|||
* |
|||
* File sprintf.c |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 02/08/2001 george Creation. Copied from uprintf.c |
|||
* 03/27/2002 Mark Schneckloth Many fixes regarding alignment, null termination |
|||
* (mschneckloth@atomz.com) and other various problems. |
|||
* 08/07/2003 george Reunify printf implementations |
|||
******************************************************************************* |
|||
*/ |
|||
|
|||
#include "unicode/utypes.h" |
|||
|
|||
#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_CONVERSION |
|||
|
|||
#include "unicode/ustdio.h" |
|||
#include "unicode/ustring.h" |
|||
#include "unicode/putil.h" |
|||
|
|||
#include "uprintf.h" |
|||
#include "locbund.h" |
|||
|
|||
#include "cmemory.h" |
|||
#include <ctype.h> |
|||
|
|||
/* u_minstrncpy copies the minimum number of code units of (count or output->available) */ |
|||
static int32_t |
|||
u_sprintf_write(void *context, |
|||
const UChar *str, |
|||
int32_t count) |
|||
{ |
|||
u_localized_print_string *output = (u_localized_print_string *)context; |
|||
int32_t size = ufmt_min(count, output->available); |
|||
|
|||
u_strncpy(output->str + (output->len - output->available), str, size); |
|||
output->available -= size; |
|||
return size; |
|||
} |
|||
|
|||
static int32_t |
|||
u_sprintf_pad_and_justify(void *context, |
|||
const u_printf_spec_info *info, |
|||
const UChar *result, |
|||
int32_t resultLen) |
|||
{ |
|||
u_localized_print_string *output = (u_localized_print_string *)context; |
|||
int32_t written = 0; |
|||
int32_t lengthOfResult = resultLen; |
|||
|
|||
resultLen = ufmt_min(resultLen, output->available); |
|||
|
|||
/* pad and justify, if needed */ |
|||
if(info->fWidth != -1 && resultLen < info->fWidth) { |
|||
int32_t paddingLeft = info->fWidth - resultLen; |
|||
int32_t outputPos = output->len - output->available; |
|||
|
|||
if (paddingLeft + resultLen > output->available) { |
|||
paddingLeft = output->available - resultLen; |
|||
if (paddingLeft < 0) { |
|||
paddingLeft = 0; |
|||
} |
|||
/* paddingLeft = output->available - resultLen;*/ |
|||
} |
|||
written += paddingLeft; |
|||
|
|||
/* left justify */ |
|||
if(info->fLeft) { |
|||
written += u_sprintf_write(output, result, resultLen); |
|||
u_memset(&output->str[outputPos + resultLen], info->fPadChar, paddingLeft); |
|||
output->available -= paddingLeft; |
|||
} |
|||
/* right justify */ |
|||
else { |
|||
u_memset(&output->str[outputPos], info->fPadChar, paddingLeft); |
|||
output->available -= paddingLeft; |
|||
written += u_sprintf_write(output, result, resultLen); |
|||
} |
|||
} |
|||
/* just write the formatted output */ |
|||
else { |
|||
written = u_sprintf_write(output, result, resultLen); |
|||
} |
|||
|
|||
if (written >= 0 && lengthOfResult > written) { |
|||
return lengthOfResult; |
|||
} |
|||
|
|||
return written; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 |
|||
u_sprintf(UChar *buffer, |
|||
const char *patternSpecification, |
|||
... ) |
|||
{ |
|||
va_list ap; |
|||
int32_t written; |
|||
|
|||
va_start(ap, patternSpecification); |
|||
written = u_vsnprintf(buffer, INT32_MAX, patternSpecification, ap); |
|||
va_end(ap); |
|||
|
|||
return written; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 |
|||
u_sprintf_u(UChar *buffer, |
|||
const UChar *patternSpecification, |
|||
... ) |
|||
{ |
|||
va_list ap; |
|||
int32_t written; |
|||
|
|||
va_start(ap, patternSpecification); |
|||
written = u_vsnprintf_u(buffer, INT32_MAX, patternSpecification, ap); |
|||
va_end(ap); |
|||
|
|||
return written; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_vsprintf(UChar *buffer, |
|||
const char *patternSpecification, |
|||
va_list ap) |
|||
{ |
|||
return u_vsnprintf(buffer, INT32_MAX, patternSpecification, ap); |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 |
|||
u_snprintf(UChar *buffer, |
|||
int32_t count, |
|||
const char *patternSpecification, |
|||
... ) |
|||
{ |
|||
va_list ap; |
|||
int32_t written; |
|||
|
|||
va_start(ap, patternSpecification); |
|||
written = u_vsnprintf(buffer, count, patternSpecification, ap); |
|||
va_end(ap); |
|||
|
|||
return written; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 |
|||
u_snprintf_u(UChar *buffer, |
|||
int32_t count, |
|||
const UChar *patternSpecification, |
|||
... ) |
|||
{ |
|||
va_list ap; |
|||
int32_t written; |
|||
|
|||
va_start(ap, patternSpecification); |
|||
written = u_vsnprintf_u(buffer, count, patternSpecification, ap); |
|||
va_end(ap); |
|||
|
|||
return written; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_vsnprintf(UChar *buffer, |
|||
int32_t count, |
|||
const char *patternSpecification, |
|||
va_list ap) |
|||
{ |
|||
int32_t written; |
|||
UChar *pattern; |
|||
UChar patBuffer[UFMT_DEFAULT_BUFFER_SIZE]; |
|||
int32_t size = (int32_t)strlen(patternSpecification) + 1; |
|||
|
|||
/* convert from the default codepage to Unicode */ |
|||
if (size >= (int32_t)MAX_UCHAR_BUFFER_SIZE(patBuffer)) { |
|||
pattern = (UChar *)uprv_malloc(size * sizeof(UChar)); |
|||
if(pattern == 0) { |
|||
return 0; |
|||
} |
|||
} |
|||
else { |
|||
pattern = patBuffer; |
|||
} |
|||
u_charsToUChars(patternSpecification, pattern, size); |
|||
|
|||
/* do the work */ |
|||
written = u_vsnprintf_u(buffer, count, pattern, ap); |
|||
|
|||
/* clean up */ |
|||
if (pattern != patBuffer) { |
|||
uprv_free(pattern); |
|||
} |
|||
|
|||
return written; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 |
|||
u_vsprintf_u(UChar *buffer, |
|||
const UChar *patternSpecification, |
|||
va_list ap) |
|||
{ |
|||
return u_vsnprintf_u(buffer, INT32_MAX, patternSpecification, ap); |
|||
} |
|||
|
|||
static const u_printf_stream_handler g_sprintf_stream_handler = { |
|||
u_sprintf_write, |
|||
u_sprintf_pad_and_justify |
|||
}; |
|||
|
|||
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_vsnprintf_u(UChar *buffer, |
|||
int32_t count, |
|||
const UChar *patternSpecification, |
|||
va_list ap) |
|||
{ |
|||
int32_t written = 0; /* haven't written anything yet */ |
|||
int32_t result = 0; /* test the return value of u_printf_parse */ |
|||
|
|||
u_localized_print_string outStr; |
|||
|
|||
if (count < 0) { |
|||
count = INT32_MAX; |
|||
} |
|||
|
|||
outStr.str = buffer; |
|||
outStr.len = count; |
|||
outStr.available = count; |
|||
|
|||
if(u_locbund_init(&outStr.fBundle, "en_US_POSIX") == 0) { |
|||
return 0; |
|||
} |
|||
|
|||
/* parse and print the whole format string */ |
|||
result = u_printf_parse(&g_sprintf_stream_handler, patternSpecification, &outStr, &outStr, &outStr.fBundle, &written, ap); |
|||
|
|||
/* Terminate the buffer, if there's room. */ |
|||
if (outStr.available > 0) { |
|||
buffer[outStr.len - outStr.available] = 0x0000; |
|||
} |
|||
|
|||
/* Release the cloned bundle, if we cloned it. */ |
|||
u_locbund_close(&outStr.fBundle); |
|||
|
|||
/* parsing error */ |
|||
if (result < 0) { |
|||
return result; |
|||
} |
|||
/* return # of UChars written */ |
|||
return written; |
|||
} |
|||
|
|||
#endif /* #if !UCONFIG_NO_FORMATTING */ |
@ -1,129 +0,0 @@ |
|||
// © 2016 and later: Unicode, Inc. and others.
|
|||
// License & terms of use: http://www.unicode.org/copyright.html
|
|||
/*
|
|||
****************************************************************************** |
|||
* |
|||
* Copyright (C) 2000-2014, International Business Machines |
|||
* Corporation and others. All Rights Reserved. |
|||
* |
|||
****************************************************************************** |
|||
* |
|||
* File sscanf.c |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 02/08/00 george Creation. Copied from uscanf.c |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
#include "unicode/utypes.h" |
|||
|
|||
#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_CONVERSION |
|||
|
|||
#include "unicode/putil.h" |
|||
#include "unicode/ustdio.h" |
|||
#include "unicode/ustring.h" |
|||
#include "uscanf.h" |
|||
#include "ufile.h" |
|||
#include "ufmt_cmn.h" |
|||
|
|||
#include "cmemory.h" |
|||
#include "cstring.h" |
|||
|
|||
|
|||
U_CAPI int32_t U_EXPORT2 |
|||
u_sscanf(const UChar *buffer, |
|||
const char *patternSpecification, |
|||
... ) |
|||
{ |
|||
va_list ap; |
|||
int32_t converted; |
|||
|
|||
va_start(ap, patternSpecification); |
|||
converted = u_vsscanf(buffer, patternSpecification, ap); |
|||
va_end(ap); |
|||
|
|||
return converted; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 |
|||
u_sscanf_u(const UChar *buffer, |
|||
const UChar *patternSpecification, |
|||
... ) |
|||
{ |
|||
va_list ap; |
|||
int32_t converted; |
|||
|
|||
va_start(ap, patternSpecification); |
|||
converted = u_vsscanf_u(buffer, patternSpecification, ap); |
|||
va_end(ap); |
|||
|
|||
return converted; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_vsscanf(const UChar *buffer, |
|||
const char *patternSpecification, |
|||
va_list ap) |
|||
{ |
|||
int32_t converted; |
|||
UChar *pattern; |
|||
UChar patBuffer[UFMT_DEFAULT_BUFFER_SIZE]; |
|||
int32_t size = (int32_t)uprv_strlen(patternSpecification) + 1; |
|||
|
|||
/* convert from the default codepage to Unicode */ |
|||
if (size >= (int32_t)MAX_UCHAR_BUFFER_SIZE(patBuffer)) { |
|||
pattern = (UChar *)uprv_malloc(size * sizeof(UChar)); |
|||
if(pattern == 0) { |
|||
return 0; |
|||
} |
|||
} |
|||
else { |
|||
pattern = patBuffer; |
|||
} |
|||
u_charsToUChars(patternSpecification, pattern, size); |
|||
|
|||
/* do the work */ |
|||
converted = u_vsscanf_u(buffer, pattern, ap); |
|||
|
|||
/* clean up */ |
|||
if (pattern != patBuffer) { |
|||
uprv_free(pattern); |
|||
} |
|||
|
|||
return converted; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_vsscanf_u(const UChar *buffer, |
|||
const UChar *patternSpecification, |
|||
va_list ap) |
|||
{ |
|||
int32_t converted; |
|||
UFILE inStr; |
|||
|
|||
inStr.fConverter = NULL; |
|||
inStr.fFile = NULL; |
|||
inStr.fOwnFile = FALSE; |
|||
#if !UCONFIG_NO_TRANSLITERATION |
|||
inStr.fTranslit = NULL; |
|||
#endif |
|||
inStr.fUCBuffer[0] = 0; |
|||
inStr.str.fBuffer = (UChar *)buffer; |
|||
inStr.str.fPos = (UChar *)buffer; |
|||
inStr.str.fLimit = buffer + u_strlen(buffer); |
|||
|
|||
if(u_locbund_init(&inStr.str.fBundle, "en_US_POSIX") == 0) { |
|||
return 0; |
|||
} |
|||
|
|||
converted = u_scanf_parse(&inStr, patternSpecification, ap); |
|||
|
|||
u_locbund_close(&inStr.str.fBundle); |
|||
|
|||
/* return # of items converted */ |
|||
return converted; |
|||
} |
|||
|
|||
#endif /* #if !UCONFIG_NO_FORMATTING */ |
@ -1,70 +0,0 @@ |
|||
// © 2016 and later: Unicode, Inc. and others.
|
|||
// License & terms of use: http://www.unicode.org/copyright.html
|
|||
/*
|
|||
****************************************************************************** |
|||
* * |
|||
* Copyright (C) 2001-2014, International Business Machines * |
|||
* Corporation and others. All Rights Reserved. * |
|||
* * |
|||
****************************************************************************** |
|||
* file name: ucln_io.cpp |
|||
* encoding: UTF-8 |
|||
* tab size: 8 (not used) |
|||
* indentation:4 |
|||
* |
|||
* created on: 2006August11 |
|||
* created by: George Rhoten |
|||
*/ |
|||
|
|||
#include "mutex.h" |
|||
#include "ucln.h" |
|||
#include "ucln_io.h" |
|||
#include "uassert.h" |
|||
|
|||
#ifndef U_IO_IMPLEMENTATION |
|||
#error U_IO_IMPLEMENTATION not set - must be set for all ICU source files in io/ - see http://userguide.icu-project.org/howtouseicu
|
|||
#endif |
|||
|
|||
|
|||
/** Auto-client */ |
|||
#define UCLN_TYPE UCLN_IO |
|||
#include "ucln_imp.h" |
|||
|
|||
/* Leave this copyright notice here! It needs to go somewhere in this library. */ |
|||
static const char copyright[] = U_COPYRIGHT_STRING; |
|||
|
|||
static cleanupFunc *gCleanupFunctions[UCLN_IO_COUNT]; |
|||
|
|||
static UBool U_CALLCONV io_cleanup(void) |
|||
{ |
|||
int32_t libType = UCLN_IO_START; |
|||
|
|||
(void)copyright; // Suppress unused variable warning.
|
|||
while (++libType<UCLN_IO_COUNT) { |
|||
if (gCleanupFunctions[libType]) |
|||
{ |
|||
gCleanupFunctions[libType](); |
|||
gCleanupFunctions[libType] = NULL; |
|||
} |
|||
} |
|||
#if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL)) |
|||
ucln_unRegisterAutomaticCleanup(); |
|||
#endif |
|||
return TRUE; |
|||
} |
|||
|
|||
void ucln_io_registerCleanup(ECleanupIOType type, |
|||
cleanupFunc *func) { |
|||
U_ASSERT(UCLN_IO_START < type && type < UCLN_IO_COUNT); |
|||
{ |
|||
icu::Mutex m; // See ticket 10295 for discussion.
|
|||
ucln_registerCleanup(UCLN_IO, io_cleanup); |
|||
if (UCLN_IO_START < type && type < UCLN_IO_COUNT) { |
|||
gCleanupFunctions[type] = func; |
|||
} |
|||
} |
|||
|
|||
#if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL)) |
|||
ucln_registerAutomaticCleanup(); |
|||
#endif |
|||
} |
@ -1,40 +0,0 @@ |
|||
// © 2016 and later: Unicode, Inc. and others.
|
|||
// License & terms of use: http://www.unicode.org/copyright.html
|
|||
/*
|
|||
****************************************************************************** |
|||
* * |
|||
* Copyright (C) 2001-2011, International Business Machines * |
|||
* Corporation and others. All Rights Reserved. * |
|||
* * |
|||
****************************************************************************** |
|||
* file name: ucln_io.h |
|||
* encoding: UTF-8 |
|||
* tab size: 8 (not used) |
|||
* indentation:4 |
|||
* |
|||
* created on: 2006August11 |
|||
* created by: George Rhoten |
|||
*/ |
|||
|
|||
#ifndef __UCLN_IO_H__ |
|||
#define __UCLN_IO_H__ |
|||
|
|||
#include "unicode/utypes.h" |
|||
#include "ucln.h" |
|||
|
|||
/*
|
|||
Please keep the order of enums declared in same order |
|||
as the functions are suppose to be called. */ |
|||
typedef enum ECleanupIOType { |
|||
UCLN_IO_START = -1, |
|||
UCLN_IO_LOCBUND, |
|||
UCLN_IO_PRINTF, |
|||
UCLN_IO_COUNT /* This must be last */ |
|||
} ECleanupIOType; |
|||
|
|||
/* Main library cleanup registration function. */ |
|||
/* See common/ucln.h for details on adding a cleanup function. */ |
|||
U_CFUNC void U_EXPORT2 ucln_io_registerCleanup(ECleanupIOType type, |
|||
cleanupFunc *func); |
|||
|
|||
#endif |
@ -1,343 +0,0 @@ |
|||
// © 2016 and later: Unicode, Inc. and others.
|
|||
// License & terms of use: http://www.unicode.org/copyright.html
|
|||
/*
|
|||
****************************************************************************** |
|||
* |
|||
* Copyright (C) 1998-2015, International Business Machines |
|||
* Corporation and others. All Rights Reserved. |
|||
* |
|||
****************************************************************************** |
|||
* |
|||
* File ufile.cpp |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 11/19/98 stephen Creation. |
|||
* 03/12/99 stephen Modified for new C API. |
|||
* 06/16/99 stephen Changed T_LocaleBundle to u_locbund |
|||
* 07/19/99 stephen Fixed to use ucnv's default codepage. |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
#include "unicode/platform.h" |
|||
#if defined(__GNUC__) && !defined(__clang__) && defined(__STRICT_ANSI__) |
|||
// g++, fileno isn't defined if __STRICT_ANSI__ is defined.
|
|||
// clang fails to compile the <string> header unless __STRICT_ANSI__ is defined.
|
|||
// __GNUC__ is set by both gcc and clang.
|
|||
#undef __STRICT_ANSI__ |
|||
#endif |
|||
|
|||
#include "locmap.h" |
|||
#include "unicode/ustdio.h" |
|||
|
|||
#if !UCONFIG_NO_CONVERSION |
|||
|
|||
#include <stdlib.h> |
|||
|
|||
#include "ufile.h" |
|||
#include "unicode/uloc.h" |
|||
#include "unicode/ures.h" |
|||
#include "unicode/ucnv.h" |
|||
#include "unicode/ustring.h" |
|||
#include "cstring.h" |
|||
#include "cmemory.h" |
|||
|
|||
#if U_PLATFORM_USES_ONLY_WIN32_API && !defined(fileno) |
|||
/* Windows likes to rename Unix-like functions */ |
|||
#define fileno _fileno |
|||
#endif |
|||
|
|||
static UFILE* |
|||
finit_owner(FILE *f, |
|||
const char *locale, |
|||
const char *codepage, |
|||
UBool takeOwnership |
|||
) |
|||
{ |
|||
UErrorCode status = U_ZERO_ERROR; |
|||
UFILE *result; |
|||
if(f == NULL) { |
|||
return 0; |
|||
} |
|||
result = (UFILE*) uprv_malloc(sizeof(UFILE)); |
|||
if(result == NULL) { |
|||
return 0; |
|||
} |
|||
|
|||
uprv_memset(result, 0, sizeof(UFILE)); |
|||
result->fFileno = fileno(f); |
|||
result->fFile = f; |
|||
|
|||
result->str.fBuffer = result->fUCBuffer; |
|||
result->str.fPos = result->fUCBuffer; |
|||
result->str.fLimit = result->fUCBuffer; |
|||
|
|||
#if !UCONFIG_NO_FORMATTING |
|||
/* if locale is 0, use the default */ |
|||
if(u_locbund_init(&result->str.fBundle, locale) == 0) { |
|||
/* DO NOT FCLOSE HERE! */ |
|||
uprv_free(result); |
|||
return 0; |
|||
} |
|||
#endif |
|||
|
|||
/* If the codepage is not "" use the ucnv_open default behavior */ |
|||
if(codepage == NULL || *codepage != '\0') { |
|||
result->fConverter = ucnv_open(codepage, &status); |
|||
} |
|||
/* else result->fConverter is already memset'd to NULL. */ |
|||
|
|||
if(U_SUCCESS(status)) { |
|||
result->fOwnFile = takeOwnership; |
|||
} |
|||
else { |
|||
#if !UCONFIG_NO_FORMATTING |
|||
u_locbund_close(&result->str.fBundle); |
|||
#endif |
|||
/* DO NOT fclose here!!!!!! */ |
|||
uprv_free(result); |
|||
result = NULL; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
U_CAPI UFILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_finit(FILE *f, |
|||
const char *locale, |
|||
const char *codepage) |
|||
{ |
|||
return finit_owner(f, locale, codepage, FALSE); |
|||
} |
|||
|
|||
U_CAPI UFILE* U_EXPORT2 |
|||
u_fadopt(FILE *f, |
|||
const char *locale, |
|||
const char *codepage) |
|||
{ |
|||
return finit_owner(f, locale, codepage, TRUE); |
|||
} |
|||
|
|||
U_CAPI UFILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_fopen(const char *filename, |
|||
const char *perm, |
|||
const char *locale, |
|||
const char *codepage) |
|||
{ |
|||
UFILE *result; |
|||
FILE *systemFile = fopen(filename, perm); |
|||
if(systemFile == 0) { |
|||
return 0; |
|||
} |
|||
|
|||
result = finit_owner(systemFile, locale, codepage, TRUE); |
|||
|
|||
if (!result) { |
|||
/* Something bad happened.
|
|||
Maybe the converter couldn't be opened. */ |
|||
fclose(systemFile); |
|||
} |
|||
|
|||
return result; /* not a file leak */ |
|||
} |
|||
|
|||
U_CAPI UFILE* U_EXPORT2 |
|||
u_fopen_u(const UChar *filename, |
|||
const char *perm, |
|||
const char *locale, |
|||
const char *codepage) |
|||
{ |
|||
UFILE *result; |
|||
char buffer[256]; |
|||
|
|||
u_austrcpy(buffer, filename); |
|||
|
|||
result = u_fopen(buffer, perm, locale, codepage); |
|||
#if U_PLATFORM_USES_ONLY_WIN32_API |
|||
/* Try Windows API _wfopen if the above fails. */ |
|||
if (!result) { |
|||
// TODO: test this code path, including wperm.
|
|||
wchar_t wperm[40] = {}; |
|||
size_t retVal; |
|||
mbstowcs_s(&retVal, wperm, perm, _TRUNCATE); |
|||
FILE *systemFile = _wfopen((const wchar_t *)filename, wperm); |
|||
if (systemFile) { |
|||
result = finit_owner(systemFile, locale, codepage, TRUE); |
|||
} |
|||
if (!result) { |
|||
/* Something bad happened.
|
|||
Maybe the converter couldn't be opened. */ |
|||
fclose(systemFile); |
|||
} |
|||
} |
|||
#endif |
|||
return result; /* not a file leak */ |
|||
} |
|||
|
|||
U_CAPI UFILE* U_EXPORT2 |
|||
u_fstropen(UChar *stringBuf, |
|||
int32_t capacity, |
|||
const char *locale) |
|||
{ |
|||
UFILE *result; |
|||
|
|||
if (capacity < 0) { |
|||
return NULL; |
|||
} |
|||
|
|||
result = (UFILE*) uprv_malloc(sizeof(UFILE)); |
|||
/* Null pointer test */ |
|||
if (result == NULL) { |
|||
return NULL; /* Just get out. */ |
|||
} |
|||
uprv_memset(result, 0, sizeof(UFILE)); |
|||
result->str.fBuffer = stringBuf; |
|||
result->str.fPos = stringBuf; |
|||
result->str.fLimit = stringBuf+capacity; |
|||
|
|||
#if !UCONFIG_NO_FORMATTING |
|||
/* if locale is 0, use the default */ |
|||
if(u_locbund_init(&result->str.fBundle, locale) == 0) { |
|||
/* DO NOT FCLOSE HERE! */ |
|||
uprv_free(result); |
|||
return 0; |
|||
} |
|||
#endif |
|||
|
|||
return result; |
|||
} |
|||
|
|||
U_CAPI UBool U_EXPORT2 |
|||
u_feof(UFILE *f) |
|||
{ |
|||
UBool endOfBuffer; |
|||
if (f == NULL) { |
|||
return TRUE; |
|||
} |
|||
endOfBuffer = (UBool)(f->str.fPos >= f->str.fLimit); |
|||
if (f->fFile != NULL) { |
|||
return endOfBuffer && feof(f->fFile); |
|||
} |
|||
return endOfBuffer; |
|||
} |
|||
|
|||
U_CAPI void U_EXPORT2 |
|||
u_fflush(UFILE *file) |
|||
{ |
|||
ufile_flush_translit(file); |
|||
ufile_flush_io(file); |
|||
if (file->fFile) { |
|||
fflush(file->fFile); |
|||
} |
|||
else if (file->str.fPos < file->str.fLimit) { |
|||
*(file->str.fPos++) = 0; |
|||
} |
|||
/* TODO: flush input */ |
|||
} |
|||
|
|||
U_CAPI void |
|||
u_frewind(UFILE *file) |
|||
{ |
|||
u_fflush(file); |
|||
ucnv_reset(file->fConverter); |
|||
if (file->fFile) { |
|||
rewind(file->fFile); |
|||
file->str.fLimit = file->fUCBuffer; |
|||
file->str.fPos = file->fUCBuffer; |
|||
} |
|||
else { |
|||
file->str.fPos = file->str.fBuffer; |
|||
} |
|||
} |
|||
|
|||
U_CAPI void U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_fclose(UFILE *file) |
|||
{ |
|||
if (file) { |
|||
u_fflush(file); |
|||
ufile_close_translit(file); |
|||
|
|||
if(file->fOwnFile) |
|||
fclose(file->fFile); |
|||
|
|||
#if !UCONFIG_NO_FORMATTING |
|||
u_locbund_close(&file->str.fBundle); |
|||
#endif |
|||
|
|||
ucnv_close(file->fConverter); |
|||
uprv_free(file); |
|||
} |
|||
} |
|||
|
|||
U_CAPI FILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_fgetfile( UFILE *f) |
|||
{ |
|||
return f->fFile; |
|||
} |
|||
|
|||
#if !UCONFIG_NO_FORMATTING |
|||
|
|||
U_CAPI const char* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_fgetlocale( UFILE *file) |
|||
{ |
|||
return file->str.fBundle.fLocale; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_fsetlocale(UFILE *file, |
|||
const char *locale) |
|||
{ |
|||
u_locbund_close(&file->str.fBundle); |
|||
|
|||
return u_locbund_init(&file->str.fBundle, locale) == 0 ? -1 : 0; |
|||
} |
|||
|
|||
#endif |
|||
|
|||
U_CAPI const char* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_fgetcodepage(UFILE *file) |
|||
{ |
|||
UErrorCode status = U_ZERO_ERROR; |
|||
const char *codepage = NULL; |
|||
|
|||
if (file->fConverter) { |
|||
codepage = ucnv_getName(file->fConverter, &status); |
|||
if(U_FAILURE(status)) |
|||
return 0; |
|||
} |
|||
return codepage; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_fsetcodepage( const char *codepage, |
|||
UFILE *file) |
|||
{ |
|||
UErrorCode status = U_ZERO_ERROR; |
|||
int32_t retVal = -1; |
|||
|
|||
/* We use the normal default codepage for this system, and not the one for the locale. */ |
|||
if ((file->str.fPos == file->str.fBuffer) && (file->str.fLimit == file->str.fBuffer)) { |
|||
ucnv_close(file->fConverter); |
|||
file->fConverter = ucnv_open(codepage, &status); |
|||
if(U_SUCCESS(status)) { |
|||
retVal = 0; |
|||
} |
|||
} |
|||
return retVal; |
|||
} |
|||
|
|||
|
|||
U_CAPI UConverter * U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_fgetConverter(UFILE *file) |
|||
{ |
|||
return file->fConverter; |
|||
} |
|||
#if !UCONFIG_NO_FORMATTING |
|||
U_CAPI const UNumberFormat* U_EXPORT2 u_fgetNumberFormat(UFILE *file) |
|||
{ |
|||
return u_locbund_getNumberFormat(&file->str.fBundle, UNUM_DECIMAL); |
|||
} |
|||
#endif |
|||
|
|||
#endif |
@ -1,140 +0,0 @@ |
|||
// © 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 ufile.h |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 12/01/98 stephen Creation. |
|||
* 03/12/99 stephen Modified for new C API. |
|||
******************************************************************************* |
|||
*/ |
|||
|
|||
#ifndef UFILE_H |
|||
#define UFILE_H |
|||
|
|||
#include "unicode/utypes.h" |
|||
|
|||
#if !UCONFIG_NO_CONVERSION |
|||
|
|||
#include <stdio.h> |
|||
|
|||
#include "unicode/ucnv.h" |
|||
#include "unicode/utrans.h" |
|||
#include "locbund.h" |
|||
|
|||
/* The buffer size for fromUnicode calls */ |
|||
#define UFILE_CHARBUFFER_SIZE 1024 |
|||
|
|||
/* The buffer size for toUnicode calls */ |
|||
#define UFILE_UCHARBUFFER_SIZE 1024 |
|||
|
|||
/* A UFILE */ |
|||
|
|||
#if !UCONFIG_NO_TRANSLITERATION |
|||
|
|||
typedef struct { |
|||
UChar *buffer; /* Beginning of buffer */ |
|||
int32_t capacity; /* Capacity of buffer */ |
|||
int32_t pos; /* Beginning of untranslitted data */ |
|||
int32_t length; /* Length *from beginning of buffer* of untranslitted data */ |
|||
UTransliterator *translit; |
|||
} UFILETranslitBuffer; |
|||
|
|||
#endif |
|||
|
|||
typedef struct u_localized_string { |
|||
UChar *fPos; /* current pos in fUCBuffer */ |
|||
const UChar *fLimit; /* data limit in fUCBuffer */ |
|||
UChar *fBuffer; /* Place to write the string */ |
|||
|
|||
#if !UCONFIG_NO_FORMATTING |
|||
ULocaleBundle fBundle; /* formatters */ |
|||
#endif |
|||
} u_localized_string; |
|||
|
|||
struct UFILE { |
|||
#if !UCONFIG_NO_TRANSLITERATION |
|||
UFILETranslitBuffer *fTranslit; |
|||
#endif |
|||
|
|||
FILE *fFile; /* the actual filesystem interface */ |
|||
|
|||
UConverter *fConverter; /* for codeset conversion */ |
|||
|
|||
u_localized_string str; /* struct to handle strings for number formatting */ |
|||
|
|||
UChar fUCBuffer[UFILE_UCHARBUFFER_SIZE];/* buffer used for toUnicode */ |
|||
|
|||
UBool fOwnFile; /* TRUE if fFile should be closed */ |
|||
|
|||
int32_t fFileno; /* File number. Useful to determine if it's stdin. */ |
|||
}; |
|||
|
|||
/**
|
|||
* Like u_file_write but takes a flush parameter |
|||
*/ |
|||
U_CFUNC int32_t U_EXPORT2 |
|||
u_file_write_flush( const UChar *chars, |
|||
int32_t count, |
|||
UFILE *f, |
|||
UBool flushIO, |
|||
UBool flushTranslit); |
|||
|
|||
/**
|
|||
* Fill a UFILE's buffer with converted codepage data. |
|||
* @param f The UFILE containing the buffer to fill. |
|||
*/ |
|||
void |
|||
ufile_fill_uchar_buffer(UFILE *f); |
|||
|
|||
/**
|
|||
* Get one code unit and detect whether the end of file has been reached. |
|||
* @param f The UFILE containing the characters. |
|||
* @param ch The read in character |
|||
* @return TRUE if the character is valid, or FALSE when EOF has been detected |
|||
*/ |
|||
U_CFUNC UBool U_EXPORT2 |
|||
ufile_getch(UFILE *f, UChar *ch); |
|||
|
|||
/**
|
|||
* Get one character and detect whether the end of file has been reached. |
|||
* @param f The UFILE containing the characters. |
|||
* @param ch The read in character |
|||
* @return TRUE if the character is valid, or FALSE when EOF has been detected |
|||
*/ |
|||
U_CFUNC UBool U_EXPORT2 |
|||
ufile_getch32(UFILE *f, UChar32 *ch); |
|||
|
|||
/**
|
|||
* Close out the transliterator and flush any data therein. |
|||
* @param f flu |
|||
*/ |
|||
void |
|||
ufile_close_translit(UFILE *f); |
|||
|
|||
/**
|
|||
* Flush the buffer in the transliterator |
|||
* @param f UFile to flush |
|||
*/ |
|||
void |
|||
ufile_flush_translit(UFILE *f); |
|||
|
|||
/**
|
|||
* Flush the IO buffer |
|||
* @param f UFile to flush |
|||
*/ |
|||
void |
|||
ufile_flush_io(UFILE *f); |
|||
|
|||
|
|||
#endif |
|||
#endif |
@ -1,259 +0,0 @@ |
|||
// © 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 ufmt_cmn.c |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 12/02/98 stephen Creation. |
|||
* 03/12/99 stephen Modified for new C API. |
|||
* 03/15/99 stephen Added defaultCPToUnicode, unicodeToDefaultCP |
|||
* 07/19/99 stephen Fixed bug in defaultCPToUnicode |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
#include "cstring.h" |
|||
#include "cmemory.h" |
|||
#include "ufmt_cmn.h" |
|||
#include "unicode/uchar.h" |
|||
#include "unicode/ucnv.h" |
|||
#include "ustr_cnv.h" |
|||
|
|||
#if !UCONFIG_NO_CONVERSION |
|||
|
|||
|
|||
#define DIGIT_0 0x0030 |
|||
#define DIGIT_9 0x0039 |
|||
#define LOWERCASE_A 0x0061 |
|||
#define UPPERCASE_A 0x0041 |
|||
#define LOWERCASE_Z 0x007A |
|||
#define UPPERCASE_Z 0x005A |
|||
|
|||
int |
|||
ufmt_digitvalue(UChar c) |
|||
{ |
|||
if( ((c>=DIGIT_0)&&(c<=DIGIT_9)) || |
|||
((c>=LOWERCASE_A)&&(c<=LOWERCASE_Z)) || |
|||
((c>=UPPERCASE_A)&&(c<=UPPERCASE_Z)) ) |
|||
{ |
|||
return c - DIGIT_0 - (c >= 0x0041 ? (c >= 0x0061 ? 39 : 7) : 0); |
|||
} |
|||
else |
|||
{ |
|||
return -1; |
|||
} |
|||
} |
|||
|
|||
UBool |
|||
ufmt_isdigit(UChar c, |
|||
int32_t radix) |
|||
{ |
|||
int digitVal = ufmt_digitvalue(c); |
|||
|
|||
return (UBool)(digitVal < radix && digitVal >= 0); |
|||
} |
|||
|
|||
#define TO_UC_DIGIT(a) a <= 9 ? (DIGIT_0 + a) : (0x0037 + a) |
|||
#define TO_LC_DIGIT(a) a <= 9 ? (DIGIT_0 + a) : (0x0057 + a) |
|||
|
|||
void |
|||
ufmt_64tou(UChar *buffer, |
|||
int32_t *len, |
|||
uint64_t value, |
|||
uint8_t radix, |
|||
UBool uselower, |
|||
int32_t minDigits) |
|||
{ |
|||
int32_t length = 0; |
|||
uint32_t digit; |
|||
UChar *left, *right, temp; |
|||
|
|||
do { |
|||
digit = (uint32_t)(value % radix); |
|||
value = value / radix; |
|||
buffer[length++] = (UChar)(uselower ? TO_LC_DIGIT(digit) |
|||
: TO_UC_DIGIT(digit)); |
|||
} while(value); |
|||
|
|||
/* pad with zeroes to make it minDigits long */ |
|||
if(minDigits != -1 && length < minDigits) { |
|||
while(length < minDigits && length < *len) |
|||
buffer[length++] = DIGIT_0; /*zero padding */ |
|||
} |
|||
|
|||
/* reverse the buffer */ |
|||
left = buffer; |
|||
right = buffer + length; |
|||
while(left < --right) { |
|||
temp = *left; |
|||
*left++ = *right; |
|||
*right = temp; |
|||
} |
|||
|
|||
*len = length; |
|||
} |
|||
|
|||
void |
|||
ufmt_ptou(UChar *buffer, |
|||
int32_t *len, |
|||
void *value, |
|||
UBool uselower) |
|||
{ |
|||
int32_t i; |
|||
int32_t length = 0; |
|||
uint8_t *ptrIdx = (uint8_t *)&value; |
|||
|
|||
#if U_IS_BIG_ENDIAN |
|||
for (i = 0; i < (int32_t)sizeof(void *); i++) |
|||
#else |
|||
for (i = (int32_t)sizeof(void *)-1; i >= 0 ; i--) |
|||
#endif |
|||
{ |
|||
uint8_t byteVal = ptrIdx[i]; |
|||
uint16_t firstNibble = (uint16_t)(byteVal>>4); |
|||
uint16_t secondNibble = (uint16_t)(byteVal&0xF); |
|||
if (uselower) { |
|||
buffer[length++]=TO_LC_DIGIT(firstNibble); |
|||
buffer[length++]=TO_LC_DIGIT(secondNibble); |
|||
} |
|||
else { |
|||
buffer[length++]=TO_UC_DIGIT(firstNibble); |
|||
buffer[length++]=TO_UC_DIGIT(secondNibble); |
|||
} |
|||
} |
|||
|
|||
*len = length; |
|||
} |
|||
|
|||
int64_t |
|||
ufmt_uto64(const UChar *buffer, |
|||
int32_t *len, |
|||
int8_t radix) |
|||
{ |
|||
const UChar *limit; |
|||
int32_t count; |
|||
int64_t result; |
|||
|
|||
|
|||
/* intialize parameters */ |
|||
limit = buffer + *len; |
|||
count = 0; |
|||
result = 0; |
|||
|
|||
/* iterate through buffer */ |
|||
while(ufmt_isdigit(*buffer, radix) && buffer < limit) { |
|||
|
|||
/* read the next digit */ |
|||
result *= radix; |
|||
result += ufmt_digitvalue(*buffer++); |
|||
|
|||
/* increment our count */ |
|||
++count; |
|||
} |
|||
|
|||
*len = count; |
|||
return result; |
|||
} |
|||
|
|||
#define NIBBLE_PER_BYTE 2 |
|||
void * |
|||
ufmt_utop(const UChar *buffer, |
|||
int32_t *len) |
|||
{ |
|||
int32_t count, resultIdx, incVal, offset; |
|||
/* This union allows the pointer to be written as an array. */ |
|||
union { |
|||
void *ptr; |
|||
uint8_t bytes[sizeof(void*)]; |
|||
} result; |
|||
|
|||
/* intialize variables */ |
|||
count = 0; |
|||
offset = 0; |
|||
result.ptr = NULL; |
|||
|
|||
/* Skip the leading zeros */ |
|||
while(buffer[count] == DIGIT_0 || u_isspace(buffer[count])) { |
|||
count++; |
|||
offset++; |
|||
} |
|||
|
|||
/* iterate through buffer, stop when you hit the end */ |
|||
while(ufmt_isdigit(buffer[count], 16) && count < *len) { |
|||
/* increment the count consumed */ |
|||
++count; |
|||
} |
|||
|
|||
/* detect overflow */ |
|||
if (count - offset > (int32_t)(sizeof(void*)*NIBBLE_PER_BYTE)) { |
|||
offset = count - (int32_t)(sizeof(void*)*NIBBLE_PER_BYTE); |
|||
} |
|||
|
|||
/* Initialize the direction of the input */ |
|||
#if U_IS_BIG_ENDIAN |
|||
incVal = -1; |
|||
resultIdx = (int32_t)(sizeof(void*) - 1); |
|||
#else |
|||
incVal = 1; |
|||
resultIdx = 0; |
|||
#endif |
|||
/* Write how much was consumed. */ |
|||
*len = count; |
|||
while(--count >= offset) { |
|||
/* Get the first nibble of the byte */ |
|||
uint8_t byte = (uint8_t)ufmt_digitvalue(buffer[count]); |
|||
|
|||
if (count > offset) { |
|||
/* Get the second nibble of the byte when available */ |
|||
byte = (uint8_t)(byte + (ufmt_digitvalue(buffer[--count]) << 4)); |
|||
} |
|||
/* Write the byte into the array */ |
|||
result.bytes[resultIdx] = byte; |
|||
resultIdx += incVal; |
|||
} |
|||
|
|||
return result.ptr; |
|||
} |
|||
|
|||
UChar* |
|||
ufmt_defaultCPToUnicode(const char *s, int32_t sSize, |
|||
UChar *target, int32_t tSize) |
|||
{ |
|||
UChar *alias; |
|||
UErrorCode status = U_ZERO_ERROR; |
|||
UConverter *defConverter = u_getDefaultConverter(&status); |
|||
|
|||
if(U_FAILURE(status) || defConverter == 0) |
|||
return 0; |
|||
|
|||
if(sSize <= 0) { |
|||
sSize = uprv_strlen(s) + 1; |
|||
} |
|||
|
|||
/* perform the conversion in one swoop */ |
|||
if(target != 0) { |
|||
|
|||
alias = target; |
|||
ucnv_toUnicode(defConverter, &alias, alias + tSize, &s, s + sSize - 1, |
|||
NULL, TRUE, &status); |
|||
|
|||
|
|||
/* add the null terminator */ |
|||
*alias = 0x0000; |
|||
} |
|||
|
|||
u_releaseDefaultConverter(defConverter); |
|||
|
|||
return target; |
|||
} |
|||
|
|||
|
|||
#endif |
@ -1,161 +0,0 @@ |
|||
// © 2016 and later: Unicode, Inc. and others.
|
|||
// License & terms of use: http://www.unicode.org/copyright.html
|
|||
/*
|
|||
****************************************************************************** |
|||
* |
|||
* Copyright (C) 1998-2011, International Business Machines |
|||
* Corporation and others. All Rights Reserved. |
|||
* |
|||
****************************************************************************** |
|||
* |
|||
* File ufmt_cmn.h |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 12/02/98 stephen Creation. |
|||
* 03/12/99 stephen Modified for new C API. |
|||
* 03/15/99 stephen Added defaultCPToUnicode, unicodeToDefaultCP |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
#ifndef UFMT_CMN_H |
|||
#define UFMT_CMN_H |
|||
|
|||
#include "unicode/utypes.h" |
|||
#include "unicode/utf16.h" |
|||
|
|||
#define UFMT_DEFAULT_BUFFER_SIZE 128 |
|||
#define MAX_UCHAR_BUFFER_SIZE(buffer) ((int32_t)(sizeof(buffer)/(U16_MAX_LENGTH*sizeof(UChar)))) |
|||
#define MAX_UCHAR_BUFFER_NEEDED(strLen) ((strLen+1)*U16_MAX_LENGTH*sizeof(UChar)) |
|||
|
|||
/**
|
|||
* Enum representing the possible argument types for uprintf/uscanf |
|||
*/ |
|||
typedef enum ufmt_type_info { |
|||
ufmt_empty = 0, |
|||
ufmt_simple_percent, /* %% do nothing */ |
|||
ufmt_count, /* special flag for count */ |
|||
ufmt_int, /* int */ |
|||
ufmt_char, /* int, cast to char */ |
|||
ufmt_string, /* char* */ |
|||
ufmt_pointer, /* void* */ |
|||
ufmt_float, /* float */ |
|||
ufmt_double, /* double */ |
|||
ufmt_uchar, /* int, cast to UChar */ |
|||
ufmt_ustring /* UChar* */ |
|||
/*ufmt_wchar,*/ /* wchar_t */ |
|||
/*ufmt_wstring,*/ /* wchar_t* */ |
|||
/*ufmt_date,*/ /* Date */ |
|||
/*ufmt_last*/ |
|||
} ufmt_type_info; |
|||
|
|||
/**
|
|||
* Union representing a uprintf/uscanf argument |
|||
*/ |
|||
typedef union ufmt_args { |
|||
int64_t int64Value; /* int, UChar */ |
|||
float floatValue; /* float */ |
|||
double doubleValue; /* double */ |
|||
void *ptrValue; /* any pointer - void*, char*, wchar_t*, UChar* */ |
|||
/*wchar_t wcharValue;*/ /* wchar_t */ /* TODO: Should wchar_t be used? */ |
|||
/*UDate dateValue;*/ /* Date */ |
|||
} ufmt_args; |
|||
|
|||
/**
|
|||
* Macro for determining the minimum of two numbers. |
|||
* @param a An integer |
|||
* @param b An integer |
|||
* @return <TT>a</TT> if </TT>a < b</TT>, <TT>b</TT> otherwise |
|||
*/ |
|||
#define ufmt_min(a,b) ((a) < (b) ? (a) : (b)) |
|||
|
|||
/**
|
|||
* Convert a UChar in hex radix to an integer value. |
|||
* @param c The UChar to convert. |
|||
* @return The integer value of <TT>c</TT>. |
|||
*/ |
|||
int |
|||
ufmt_digitvalue(UChar c); |
|||
|
|||
/**
|
|||
* Determine if a UChar is a digit for a specified radix. |
|||
* @param c The UChar to check. |
|||
* @param radix The desired radix. |
|||
* @return TRUE if <TT>c</TT> is a digit in <TT>radix</TT>, FALSE otherwise. |
|||
*/ |
|||
UBool |
|||
ufmt_isdigit(UChar c, |
|||
int32_t radix); |
|||
|
|||
/**
|
|||
* Convert an int64_t to a UChar* in a specified radix |
|||
* @param buffer The target buffer |
|||
* @param len On input, the size of <TT>buffer</TT>. On output, |
|||
* the number of UChars written to <TT>buffer</TT>. |
|||
* @param value The value to be converted |
|||
* @param radix The desired radix |
|||
* @param uselower TRUE means lower case will be used, FALSE means upper case |
|||
* @param minDigits The minimum number of digits for for the formatted number, |
|||
* which will be padded with zeroes. -1 means do not pad. |
|||
*/ |
|||
void |
|||
ufmt_64tou(UChar *buffer, |
|||
int32_t *len, |
|||
uint64_t value, |
|||
uint8_t radix, |
|||
UBool uselower, |
|||
int32_t minDigits); |
|||
|
|||
/**
|
|||
* It's like ufmt_64tou, but with a pointer. |
|||
* This functions avoids size constraints of 64-bit types. |
|||
* Pointers can be at 32-128 bits in size. |
|||
*/ |
|||
void |
|||
ufmt_ptou(UChar *buffer, |
|||
int32_t *len, |
|||
void *value, |
|||
UBool uselower); |
|||
|
|||
/**
|
|||
* Convert a UChar* in a specified radix to an int64_t. |
|||
* @param buffer The target buffer |
|||
* @param len On input, the size of <TT>buffer</TT>. On output, |
|||
* the number of UChars read from <TT>buffer</TT>. |
|||
* @param radix The desired radix |
|||
* @return The numeric value. |
|||
*/ |
|||
int64_t |
|||
ufmt_uto64(const UChar *buffer, |
|||
int32_t *len, |
|||
int8_t radix); |
|||
|
|||
/**
|
|||
* Convert a UChar* in a specified radix to a pointer, |
|||
* @param buffer The target buffer |
|||
* @param len On input, the size of <TT>buffer</TT>. On output, |
|||
* the number of UChars read from <TT>buffer</TT>. |
|||
* @param radix The desired radix |
|||
* @return The pointer value. |
|||
*/ |
|||
void * |
|||
ufmt_utop(const UChar *buffer, |
|||
int32_t *len); |
|||
|
|||
/**
|
|||
* Convert a string from the default codepage to Unicode. |
|||
* @param s The string to convert, in the default codepage. |
|||
* @param sSize The size of s to convert. |
|||
* @param target The buffer to convert to. |
|||
* @param tSize The size of target |
|||
* @return A pointer to a newly allocated converted version of s, or 0 |
|||
* on error. |
|||
*/ |
|||
UChar* |
|||
ufmt_defaultCPToUnicode(const char *s, int32_t sSize, |
|||
UChar *target, int32_t tSize); |
|||
|
|||
|
|||
|
|||
#endif |
File diff suppressed because it is too large
@ -1,70 +0,0 @@ |
|||
// © 2016 and later: Unicode, Inc. and others.
|
|||
// License & terms of use: http://www.unicode.org/copyright.html
|
|||
/*
|
|||
********************************************************************** |
|||
* Copyright (C) 2001-2014 International Business Machines |
|||
* Corporation and others. All Rights Reserved. |
|||
********************************************************************** |
|||
* FILE NAME : ustream.h |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 06/25/2001 grhoten Move iostream from unistr.h |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
#ifndef USTREAM_H |
|||
#define USTREAM_H |
|||
|
|||
#include "unicode/unistr.h" |
|||
|
|||
#if !UCONFIG_NO_CONVERSION // not available without conversion
|
|||
|
|||
/**
|
|||
* \file |
|||
* \brief C++ API: Unicode iostream like API |
|||
* |
|||
* At this time, this API is very limited. It contains |
|||
* operator<< and operator>> for UnicodeString manipulation with the |
|||
* C++ I/O stream API. |
|||
*/ |
|||
|
|||
#if defined(__GLIBCXX__) |
|||
namespace std { class type_info; } // WORKAROUND: http://llvm.org/bugs/show_bug.cgi?id=13364
|
|||
#endif |
|||
|
|||
#if U_IOSTREAM_SOURCE >= 199711 |
|||
#if (__GNUC__ == 2) |
|||
#include <iostream> |
|||
#else |
|||
#include <istream> |
|||
#include <ostream> |
|||
#endif |
|||
|
|||
U_NAMESPACE_BEGIN |
|||
|
|||
/**
|
|||
* Write the contents of a UnicodeString to a C++ ostream. This functions writes |
|||
* the characters in a UnicodeString to an ostream. The UChars in the |
|||
* UnicodeString are converted to the char based ostream with the default |
|||
* converter. |
|||
* @stable 3.0 |
|||
*/ |
|||
U_IO_API std::ostream & U_EXPORT2 operator<<(std::ostream& stream, const UnicodeString& s); |
|||
|
|||
/**
|
|||
* Write the contents from a C++ istream to a UnicodeString. The UChars in the |
|||
* UnicodeString are converted from the char based istream with the default |
|||
* converter. |
|||
* @stable 3.0 |
|||
*/ |
|||
U_IO_API std::istream & U_EXPORT2 operator>>(std::istream& stream, UnicodeString& s); |
|||
U_NAMESPACE_END |
|||
|
|||
#endif |
|||
|
|||
/* No operator for UChar because it can conflict with wchar_t */ |
|||
|
|||
#endif |
|||
#endif |
@ -1,218 +0,0 @@ |
|||
// © 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 uprintf.cpp |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 11/19/98 stephen Creation. |
|||
* 03/12/99 stephen Modified for new C API. |
|||
* Added conversion from default codepage. |
|||
* 08/07/2003 george Reunify printf implementations |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
#include "unicode/utypes.h" |
|||
|
|||
#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_CONVERSION |
|||
|
|||
#include "unicode/ustdio.h" |
|||
#include "unicode/ustring.h" |
|||
#include "unicode/unum.h" |
|||
#include "unicode/udat.h" |
|||
#include "unicode/putil.h" |
|||
|
|||
#include "cmemory.h" |
|||
#include "locbund.h" |
|||
#include "mutex.h" |
|||
#include "uassert.h" |
|||
#include "uprintf.h" |
|||
#include "ufile.h" |
|||
#include "ucln_io.h" |
|||
|
|||
U_NAMESPACE_USE |
|||
|
|||
static UFILE *gStdOut = NULL; |
|||
static UInitOnce gStdOutInitOnce = U_INITONCE_INITIALIZER; |
|||
|
|||
static UBool U_CALLCONV uprintf_cleanup(void) |
|||
{ |
|||
if (gStdOut != NULL) { |
|||
u_fclose(gStdOut); |
|||
gStdOut = NULL; |
|||
} |
|||
gStdOutInitOnce.reset(); |
|||
return TRUE; |
|||
} |
|||
|
|||
static void U_CALLCONV u_stdout_init() { |
|||
U_ASSERT(gStdOut == NULL); |
|||
gStdOut = u_finit(stdout, NULL, NULL); |
|||
ucln_io_registerCleanup(UCLN_IO_PRINTF, &uprintf_cleanup); |
|||
} |
|||
|
|||
U_CAPI UFILE * U_EXPORT2 |
|||
u_get_stdout() |
|||
{ |
|||
umtx_initOnce(gStdOutInitOnce, &u_stdout_init); |
|||
return gStdOut; |
|||
} |
|||
|
|||
static int32_t U_EXPORT2 |
|||
u_printf_write(void *context, |
|||
const UChar *str, |
|||
int32_t count) |
|||
{ |
|||
return u_file_write(str, count, (UFILE *)context); |
|||
} |
|||
|
|||
static int32_t |
|||
u_printf_pad_and_justify(void *context, |
|||
const u_printf_spec_info *info, |
|||
const UChar *result, |
|||
int32_t resultLen) |
|||
{ |
|||
UFILE *output = (UFILE *)context; |
|||
int32_t written, i; |
|||
|
|||
/* pad and justify, if needed */ |
|||
if(info->fWidth != -1 && resultLen < info->fWidth) { |
|||
/* left justify */ |
|||
if(info->fLeft) { |
|||
written = u_file_write(result, resultLen, output); |
|||
for(i = 0; i < info->fWidth - resultLen; ++i) { |
|||
written += u_file_write(&info->fPadChar, 1, output); |
|||
} |
|||
} |
|||
/* right justify */ |
|||
else { |
|||
written = 0; |
|||
for(i = 0; i < info->fWidth - resultLen; ++i) { |
|||
written += u_file_write(&info->fPadChar, 1, output); |
|||
} |
|||
written += u_file_write(result, resultLen, output); |
|||
} |
|||
} |
|||
/* just write the formatted output */ |
|||
else { |
|||
written = u_file_write(result, resultLen, output); |
|||
} |
|||
|
|||
return written; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 |
|||
u_fprintf( UFILE *f, |
|||
const char *patternSpecification, |
|||
... ) |
|||
{ |
|||
va_list ap; |
|||
int32_t count; |
|||
|
|||
va_start(ap, patternSpecification); |
|||
count = u_vfprintf(f, patternSpecification, ap); |
|||
va_end(ap); |
|||
|
|||
return count; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 |
|||
u_printf(const char *patternSpecification, |
|||
...) |
|||
{ |
|||
va_list ap; |
|||
int32_t count; |
|||
va_start(ap, patternSpecification); |
|||
count = u_vfprintf(u_get_stdout(), patternSpecification, ap); |
|||
va_end(ap); |
|||
return count; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 |
|||
u_fprintf_u( UFILE *f, |
|||
const UChar *patternSpecification, |
|||
... ) |
|||
{ |
|||
va_list ap; |
|||
int32_t count; |
|||
|
|||
va_start(ap, patternSpecification); |
|||
count = u_vfprintf_u(f, patternSpecification, ap); |
|||
va_end(ap); |
|||
|
|||
return count; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 |
|||
u_printf_u(const UChar *patternSpecification, |
|||
...) |
|||
{ |
|||
va_list ap; |
|||
int32_t count; |
|||
va_start(ap, patternSpecification); |
|||
count = u_vfprintf_u(u_get_stdout(), patternSpecification, ap); |
|||
va_end(ap); |
|||
return count; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_vfprintf( UFILE *f, |
|||
const char *patternSpecification, |
|||
va_list ap) |
|||
{ |
|||
int32_t count; |
|||
UChar *pattern; |
|||
UChar buffer[UFMT_DEFAULT_BUFFER_SIZE]; |
|||
size_t size = strlen(patternSpecification) + 1; |
|||
|
|||
/* convert from the default codepage to Unicode */ |
|||
if (size >= MAX_UCHAR_BUFFER_SIZE(buffer)) { |
|||
pattern = (UChar *)uprv_malloc(size * sizeof(UChar)); |
|||
if(pattern == 0) { |
|||
return 0; |
|||
} |
|||
} |
|||
else { |
|||
pattern = buffer; |
|||
} |
|||
u_charsToUChars(patternSpecification, pattern, size); |
|||
|
|||
/* do the work */ |
|||
count = u_vfprintf_u(f, pattern, ap); |
|||
|
|||
/* clean up */ |
|||
if (pattern != buffer) { |
|||
uprv_free(pattern); |
|||
} |
|||
|
|||
return count; |
|||
} |
|||
|
|||
static const u_printf_stream_handler g_stream_handler = { |
|||
u_printf_write, |
|||
u_printf_pad_and_justify |
|||
}; |
|||
|
|||
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_vfprintf_u( UFILE *f, |
|||
const UChar *patternSpecification, |
|||
va_list ap) |
|||
{ |
|||
int32_t written = 0; /* haven't written anything yet */ |
|||
|
|||
/* parse and print the whole format string */ |
|||
u_printf_parse(&g_stream_handler, patternSpecification, f, NULL, &f->str.fBundle, &written, ap); |
|||
|
|||
/* return # of UChars written */ |
|||
return written; |
|||
} |
|||
|
|||
#endif /* #if !UCONFIG_NO_FORMATTING */ |
@ -1,103 +0,0 @@ |
|||
// © 2016 and later: Unicode, Inc. and others.
|
|||
// License & terms of use: http://www.unicode.org/copyright.html
|
|||
/*
|
|||
****************************************************************************** |
|||
* |
|||
* Copyright (C) 1998-2006, International Business Machines |
|||
* Corporation and others. All Rights Reserved. |
|||
* |
|||
****************************************************************************** |
|||
* |
|||
* File uprintf.h |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 11/19/98 stephen Creation. |
|||
* 03/12/99 stephen Modified for new C API. |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
#ifndef UPRINTF_H |
|||
#define UPRINTF_H |
|||
|
|||
#include "unicode/utypes.h" |
|||
|
|||
#if !UCONFIG_NO_FORMATTING |
|||
|
|||
#include "unicode/ustdio.h" |
|||
#include "ufmt_cmn.h" |
|||
#include "locbund.h" |
|||
|
|||
/**
|
|||
* Struct encapsulating a single uprintf format specification. |
|||
*/ |
|||
typedef struct u_printf_spec_info { |
|||
int32_t fPrecision; /* Precision */ |
|||
int32_t fWidth; /* Width */ |
|||
|
|||
UChar fOrigSpec; /* Conversion specification */ |
|||
UChar fSpec; /* Conversion specification */ |
|||
UChar fPadChar; /* Padding character */ |
|||
|
|||
UBool fAlt; /* # flag */ |
|||
UBool fSpace; /* Space flag */ |
|||
UBool fLeft; /* - flag */ |
|||
UBool fShowSign; /* + flag */ |
|||
UBool fZero; /* 0 flag */ |
|||
|
|||
UBool fIsLongDouble; /* L flag */ |
|||
UBool fIsShort; /* h flag */ |
|||
UBool fIsLong; /* l flag */ |
|||
UBool fIsLongLong; /* ll flag */ |
|||
} u_printf_spec_info; |
|||
|
|||
typedef int32_t U_EXPORT2 |
|||
u_printf_write_stream(void *context, |
|||
const UChar *str, |
|||
int32_t count); |
|||
|
|||
typedef int32_t U_EXPORT2 |
|||
u_printf_pad_and_justify_stream(void *context, |
|||
const u_printf_spec_info *info, |
|||
const UChar *result, |
|||
int32_t resultLen); |
|||
|
|||
typedef struct u_printf_stream_handler { |
|||
u_printf_write_stream *write; |
|||
u_printf_pad_and_justify_stream *pad_and_justify; |
|||
} u_printf_stream_handler; |
|||
|
|||
/* Used by sprintf */ |
|||
typedef struct u_localized_print_string { |
|||
UChar *str; /* Place to write the string */ |
|||
int32_t available;/* Number of codeunits available to write to */ |
|||
int32_t len; /* Maximum number of code units that can be written to output */ |
|||
|
|||
ULocaleBundle fBundle; /* formatters */ |
|||
} u_localized_print_string; |
|||
|
|||
#define UP_PERCENT 0x0025 |
|||
|
|||
/**
|
|||
* Parse a single u_printf format string. |
|||
* @param fmt A pointer to a '%' character in a u_printf format specification. |
|||
* @param spec A pointer to a <TT>u_printf_spec</TT> to receive the parsed |
|||
* format specifier. |
|||
* @param locStringContext If present, will make sure that it will only write |
|||
* to the buffer when space is available. It's done this way because |
|||
* va_list sometimes can't be passed by pointer. |
|||
* @return The number of characters contained in this specifier. |
|||
*/ |
|||
U_CFUNC int32_t |
|||
u_printf_parse(const u_printf_stream_handler *streamHandler, |
|||
const UChar *fmt, |
|||
void *context, |
|||
u_localized_print_string *locStringContext, |
|||
ULocaleBundle *formatBundle, |
|||
int32_t *written, |
|||
va_list ap); |
|||
|
|||
#endif /* #if !UCONFIG_NO_FORMATTING */ |
|||
|
|||
#endif |
File diff suppressed because it is too large
@ -1,107 +0,0 @@ |
|||
// © 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 uscanf.c |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 12/02/98 stephen Creation. |
|||
* 03/13/99 stephen Modified for new C API. |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
#include "unicode/utypes.h" |
|||
|
|||
#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_CONVERSION |
|||
|
|||
#include "unicode/putil.h" |
|||
#include "unicode/ustdio.h" |
|||
#include "unicode/ustring.h" |
|||
#include "uscanf.h" |
|||
#include "ufile.h" |
|||
#include "ufmt_cmn.h" |
|||
|
|||
#include "cmemory.h" |
|||
#include "cstring.h" |
|||
|
|||
|
|||
U_CAPI int32_t U_EXPORT2 |
|||
u_fscanf(UFILE *f, |
|||
const char *patternSpecification, |
|||
... ) |
|||
{ |
|||
va_list ap; |
|||
int32_t converted; |
|||
|
|||
va_start(ap, patternSpecification); |
|||
converted = u_vfscanf(f, patternSpecification, ap); |
|||
va_end(ap); |
|||
|
|||
return converted; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 |
|||
u_fscanf_u(UFILE *f, |
|||
const UChar *patternSpecification, |
|||
... ) |
|||
{ |
|||
va_list ap; |
|||
int32_t converted; |
|||
|
|||
va_start(ap, patternSpecification); |
|||
converted = u_vfscanf_u(f, patternSpecification, ap); |
|||
va_end(ap); |
|||
|
|||
return converted; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_vfscanf(UFILE *f, |
|||
const char *patternSpecification, |
|||
va_list ap) |
|||
{ |
|||
int32_t converted; |
|||
UChar *pattern; |
|||
UChar patBuffer[UFMT_DEFAULT_BUFFER_SIZE]; |
|||
int32_t size = (int32_t)uprv_strlen(patternSpecification) + 1; |
|||
|
|||
/* convert from the default codepage to Unicode */ |
|||
if (size >= MAX_UCHAR_BUFFER_SIZE(patBuffer)) { |
|||
pattern = (UChar *)uprv_malloc(size * sizeof(UChar)); |
|||
if(pattern == 0) { |
|||
return 0; |
|||
} |
|||
} |
|||
else { |
|||
pattern = patBuffer; |
|||
} |
|||
u_charsToUChars(patternSpecification, pattern, size); |
|||
|
|||
/* do the work */ |
|||
converted = u_vfscanf_u(f, pattern, ap); |
|||
|
|||
/* clean up */ |
|||
if (pattern != patBuffer) { |
|||
uprv_free(pattern); |
|||
} |
|||
|
|||
return converted; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_vfscanf_u(UFILE *f, |
|||
const UChar *patternSpecification, |
|||
va_list ap) |
|||
{ |
|||
return u_scanf_parse(f, patternSpecification, ap); |
|||
} |
|||
|
|||
#endif /* #if !UCONFIG_NO_FORMATTING */ |
@ -1,37 +0,0 @@ |
|||
// © 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 uscanf.h |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 12/02/98 stephen Creation. |
|||
* 03/13/99 stephen Modified for new C API. |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
#ifndef USCANF_H |
|||
#define USCANF_H |
|||
|
|||
#include "unicode/utypes.h" |
|||
|
|||
#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_CONVERSION |
|||
|
|||
#include "unicode/ustdio.h" |
|||
|
|||
U_CFUNC int32_t |
|||
u_scanf_parse(UFILE *f, |
|||
const UChar *patternSpecification, |
|||
va_list ap); |
|||
|
|||
#endif /* #if !UCONFIG_NO_FORMATTING */ |
|||
|
|||
#endif |
File diff suppressed because it is too large
@ -1,732 +0,0 @@ |
|||
// © 2016 and later: Unicode, Inc. and others.
|
|||
// License & terms of use: http://www.unicode.org/copyright.html
|
|||
/*
|
|||
****************************************************************************** |
|||
* |
|||
* Copyright (C) 1998-2016, International Business Machines |
|||
* Corporation and others. All Rights Reserved. |
|||
* |
|||
****************************************************************************** |
|||
* |
|||
* File ustdio.c |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 11/18/98 stephen Creation. |
|||
* 03/12/99 stephen Modified for new C API. |
|||
* 07/19/99 stephen Fixed read() and gets() |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
#include "unicode/ustdio.h" |
|||
|
|||
#if !UCONFIG_NO_CONVERSION |
|||
|
|||
#include "unicode/putil.h" |
|||
#include "cmemory.h" |
|||
#include "cstring.h" |
|||
#include "ufile.h" |
|||
#include "ufmt_cmn.h" |
|||
#include "unicode/ucnv.h" |
|||
#include "unicode/ustring.h" |
|||
|
|||
#include <string.h> |
|||
|
|||
#define DELIM_LF 0x000A |
|||
#define DELIM_VT 0x000B |
|||
#define DELIM_FF 0x000C |
|||
#define DELIM_CR 0x000D |
|||
#define DELIM_NEL 0x0085 |
|||
#define DELIM_LS 0x2028 |
|||
#define DELIM_PS 0x2029 |
|||
|
|||
/* TODO: is this correct for all codepages? Should we just use \n and let the converter handle it? */ |
|||
#if U_PLATFORM_USES_ONLY_WIN32_API |
|||
static const UChar DELIMITERS [] = { DELIM_CR, DELIM_LF, 0x0000 }; |
|||
static const uint32_t DELIMITERS_LEN = 2; |
|||
/* TODO: Default newline writing should be detected based upon the converter being used. */ |
|||
#else |
|||
static const UChar DELIMITERS [] = { DELIM_LF, 0x0000 }; |
|||
static const uint32_t DELIMITERS_LEN = 1; |
|||
#endif |
|||
|
|||
#define IS_FIRST_STRING_DELIMITER(c1) \ |
|||
(UBool)((DELIM_LF <= (c1) && (c1) <= DELIM_CR) \ |
|||
|| (c1) == DELIM_NEL \ |
|||
|| (c1) == DELIM_LS \ |
|||
|| (c1) == DELIM_PS) |
|||
#define CAN_HAVE_COMBINED_STRING_DELIMITER(c1) (UBool)((c1) == DELIM_CR) |
|||
#define IS_COMBINED_STRING_DELIMITER(c1, c2) \ |
|||
(UBool)((c1) == DELIM_CR && (c2) == DELIM_LF) |
|||
|
|||
|
|||
#if !UCONFIG_NO_TRANSLITERATION |
|||
|
|||
U_CAPI UTransliterator* U_EXPORT2 |
|||
u_fsettransliterator(UFILE *file, UFileDirection direction, |
|||
UTransliterator *adopt, UErrorCode *status) |
|||
{ |
|||
UTransliterator *old = NULL; |
|||
|
|||
if(U_FAILURE(*status)) |
|||
{ |
|||
return adopt; |
|||
} |
|||
|
|||
if(!file) |
|||
{ |
|||
*status = U_ILLEGAL_ARGUMENT_ERROR; |
|||
return adopt; |
|||
} |
|||
|
|||
if(direction & U_READ) |
|||
{ |
|||
/** TODO: implement */ |
|||
*status = U_UNSUPPORTED_ERROR; |
|||
return adopt; |
|||
} |
|||
|
|||
if(adopt == NULL) /* they are clearing it */ |
|||
{ |
|||
if(file->fTranslit != NULL) |
|||
{ |
|||
/* TODO: Check side */ |
|||
old = file->fTranslit->translit; |
|||
uprv_free(file->fTranslit->buffer); |
|||
file->fTranslit->buffer=NULL; |
|||
uprv_free(file->fTranslit); |
|||
file->fTranslit=NULL; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
if(file->fTranslit == NULL) |
|||
{ |
|||
file->fTranslit = (UFILETranslitBuffer*) uprv_malloc(sizeof(UFILETranslitBuffer)); |
|||
if(!file->fTranslit) |
|||
{ |
|||
*status = U_MEMORY_ALLOCATION_ERROR; |
|||
return adopt; |
|||
} |
|||
file->fTranslit->capacity = 0; |
|||
file->fTranslit->length = 0; |
|||
file->fTranslit->pos = 0; |
|||
file->fTranslit->buffer = NULL; |
|||
} |
|||
else |
|||
{ |
|||
old = file->fTranslit->translit; |
|||
ufile_flush_translit(file); |
|||
} |
|||
|
|||
file->fTranslit->translit = adopt; |
|||
} |
|||
|
|||
return old; |
|||
} |
|||
|
|||
static const UChar * u_file_translit(UFILE *f, const UChar *src, int32_t *count, UBool flush) |
|||
{ |
|||
int32_t newlen; |
|||
int32_t junkCount = 0; |
|||
int32_t textLength; |
|||
int32_t textLimit; |
|||
UTransPosition pos; |
|||
UErrorCode status = U_ZERO_ERROR; |
|||
|
|||
if(count == NULL) |
|||
{ |
|||
count = &junkCount; |
|||
} |
|||
|
|||
if ((!f)||(!f->fTranslit)||(!f->fTranslit->translit)) |
|||
{ |
|||
/* fast path */ |
|||
return src; |
|||
} |
|||
|
|||
/* First: slide over everything */ |
|||
if(f->fTranslit->length > f->fTranslit->pos) |
|||
{ |
|||
memmove(f->fTranslit->buffer, f->fTranslit->buffer + f->fTranslit->pos, |
|||
(f->fTranslit->length - f->fTranslit->pos)*sizeof(UChar)); |
|||
} |
|||
f->fTranslit->length -= f->fTranslit->pos; /* always */ |
|||
f->fTranslit->pos = 0; |
|||
|
|||
/* Calculate new buffer size needed */ |
|||
newlen = (*count + f->fTranslit->length) * 4; |
|||
|
|||
if(newlen > f->fTranslit->capacity) |
|||
{ |
|||
if(f->fTranslit->buffer == NULL) |
|||
{ |
|||
f->fTranslit->buffer = (UChar*)uprv_malloc(newlen * sizeof(UChar)); |
|||
} |
|||
else |
|||
{ |
|||
f->fTranslit->buffer = (UChar*)uprv_realloc(f->fTranslit->buffer, newlen * sizeof(UChar)); |
|||
} |
|||
/* Check for malloc/realloc failure. */ |
|||
if (f->fTranslit->buffer == NULL) { |
|||
return NULL; |
|||
} |
|||
f->fTranslit->capacity = newlen; |
|||
} |
|||
|
|||
/* Now, copy any data over */ |
|||
u_strncpy(f->fTranslit->buffer + f->fTranslit->length, |
|||
src, |
|||
*count); |
|||
f->fTranslit->length += *count; |
|||
|
|||
/* Now, translit in place as much as we can */ |
|||
if(flush == FALSE) |
|||
{ |
|||
textLength = f->fTranslit->length; |
|||
pos.contextStart = 0; |
|||
pos.contextLimit = textLength; |
|||
pos.start = 0; |
|||
pos.limit = textLength; |
|||
|
|||
utrans_transIncrementalUChars(f->fTranslit->translit, |
|||
f->fTranslit->buffer, /* because we shifted */ |
|||
&textLength, |
|||
f->fTranslit->capacity, |
|||
&pos, |
|||
&status); |
|||
|
|||
/* now: start/limit point to the transliterated text */ |
|||
/* Transliterated is [buffer..pos.start) */ |
|||
*count = pos.start; |
|||
f->fTranslit->pos = pos.start; |
|||
f->fTranslit->length = pos.limit; |
|||
|
|||
return f->fTranslit->buffer; |
|||
} |
|||
else |
|||
{ |
|||
textLength = f->fTranslit->length; |
|||
textLimit = f->fTranslit->length; |
|||
|
|||
utrans_transUChars(f->fTranslit->translit, |
|||
f->fTranslit->buffer, |
|||
&textLength, |
|||
f->fTranslit->capacity, |
|||
0, |
|||
&textLimit, |
|||
&status); |
|||
|
|||
/* out: converted len */ |
|||
*count = textLimit; |
|||
|
|||
/* Set pointers to 0 */ |
|||
f->fTranslit->pos = 0; |
|||
f->fTranslit->length = 0; |
|||
|
|||
return f->fTranslit->buffer; |
|||
} |
|||
} |
|||
|
|||
#endif |
|||
|
|||
void |
|||
ufile_flush_translit(UFILE *f) |
|||
{ |
|||
#if !UCONFIG_NO_TRANSLITERATION |
|||
if((!f)||(!f->fTranslit)) |
|||
return; |
|||
#endif |
|||
|
|||
u_file_write_flush(NULL, 0, f, FALSE, TRUE); |
|||
} |
|||
|
|||
|
|||
void |
|||
ufile_flush_io(UFILE *f) |
|||
{ |
|||
if((!f) || (!f->fFile)) { |
|||
return; /* skip if no file */ |
|||
} |
|||
|
|||
u_file_write_flush(NULL, 0, f, TRUE, FALSE); |
|||
} |
|||
|
|||
|
|||
void |
|||
ufile_close_translit(UFILE *f) |
|||
{ |
|||
#if !UCONFIG_NO_TRANSLITERATION |
|||
if((!f)||(!f->fTranslit)) |
|||
return; |
|||
#endif |
|||
|
|||
ufile_flush_translit(f); |
|||
|
|||
#if !UCONFIG_NO_TRANSLITERATION |
|||
if(f->fTranslit->translit) |
|||
utrans_close(f->fTranslit->translit); |
|||
|
|||
if(f->fTranslit->buffer) |
|||
{ |
|||
uprv_free(f->fTranslit->buffer); |
|||
} |
|||
|
|||
uprv_free(f->fTranslit); |
|||
f->fTranslit = NULL; |
|||
#endif |
|||
} |
|||
|
|||
|
|||
/* Input/output */ |
|||
|
|||
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_fputs(const UChar *s, |
|||
UFILE *f) |
|||
{ |
|||
int32_t count = u_file_write(s, u_strlen(s), f); |
|||
count += u_file_write(DELIMITERS, DELIMITERS_LEN, f); |
|||
return count; |
|||
} |
|||
|
|||
U_CAPI UChar32 U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_fputc(UChar32 uc, |
|||
UFILE *f) |
|||
{ |
|||
UChar buf[2]; |
|||
int32_t idx = 0; |
|||
UBool isError = FALSE; |
|||
|
|||
U16_APPEND(buf, idx, UPRV_LENGTHOF(buf), uc, isError); |
|||
if (isError) { |
|||
return U_EOF; |
|||
} |
|||
return u_file_write(buf, idx, f) == idx ? uc : U_EOF; |
|||
} |
|||
|
|||
|
|||
U_CFUNC int32_t U_EXPORT2 |
|||
u_file_write_flush(const UChar *chars, |
|||
int32_t count, |
|||
UFILE *f, |
|||
UBool flushIO, |
|||
UBool flushTranslit) |
|||
{ |
|||
/* Set up conversion parameters */ |
|||
UErrorCode status = U_ZERO_ERROR; |
|||
const UChar *mySource = chars; |
|||
const UChar *mySourceBegin; |
|||
const UChar *mySourceEnd; |
|||
char charBuffer[UFILE_CHARBUFFER_SIZE]; |
|||
char *myTarget = charBuffer; |
|||
int32_t written = 0; |
|||
int32_t numConverted = 0; |
|||
|
|||
if (count < 0) { |
|||
count = u_strlen(chars); |
|||
} |
|||
|
|||
#if !UCONFIG_NO_TRANSLITERATION |
|||
if((f->fTranslit) && (f->fTranslit->translit)) |
|||
{ |
|||
/* Do the transliteration */ |
|||
mySource = u_file_translit(f, chars, &count, flushTranslit); |
|||
} |
|||
#endif |
|||
|
|||
/* Write to a string. */ |
|||
if (!f->fFile) { |
|||
int32_t charsLeft = (int32_t)(f->str.fLimit - f->str.fPos); |
|||
if (flushIO && charsLeft > count) { |
|||
count++; |
|||
} |
|||
written = ufmt_min(count, charsLeft); |
|||
u_strncpy(f->str.fPos, mySource, written); |
|||
f->str.fPos += written; |
|||
return written; |
|||
} |
|||
|
|||
mySourceEnd = mySource + count; |
|||
|
|||
/* Perform the conversion in a loop */ |
|||
do { |
|||
mySourceBegin = mySource; /* beginning location for this loop */ |
|||
status = U_ZERO_ERROR; |
|||
if(f->fConverter != NULL) { /* We have a valid converter */ |
|||
ucnv_fromUnicode(f->fConverter, |
|||
&myTarget, |
|||
charBuffer + UFILE_CHARBUFFER_SIZE, |
|||
&mySource, |
|||
mySourceEnd, |
|||
NULL, |
|||
flushIO, |
|||
&status); |
|||
} else { /*weiv: do the invariant conversion */ |
|||
int32_t convertChars = (int32_t) (mySourceEnd - mySource); |
|||
if (convertChars > UFILE_CHARBUFFER_SIZE) { |
|||
convertChars = UFILE_CHARBUFFER_SIZE; |
|||
status = U_BUFFER_OVERFLOW_ERROR; |
|||
} |
|||
u_UCharsToChars(mySource, myTarget, convertChars); |
|||
mySource += convertChars; |
|||
myTarget += convertChars; |
|||
} |
|||
numConverted = (int32_t)(myTarget - charBuffer); |
|||
|
|||
if (numConverted > 0) { |
|||
/* write the converted bytes */ |
|||
fwrite(charBuffer, |
|||
sizeof(char), |
|||
numConverted, |
|||
f->fFile); |
|||
|
|||
written += (int32_t) (mySource - mySourceBegin); |
|||
} |
|||
myTarget = charBuffer; |
|||
} |
|||
while(status == U_BUFFER_OVERFLOW_ERROR); |
|||
|
|||
/* return # of chars written */ |
|||
return written; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_file_write( const UChar *chars, |
|||
int32_t count, |
|||
UFILE *f) |
|||
{ |
|||
return u_file_write_flush(chars,count,f,FALSE,FALSE); |
|||
} |
|||
|
|||
|
|||
/* private function used for buffering input */ |
|||
void |
|||
ufile_fill_uchar_buffer(UFILE *f) |
|||
{ |
|||
UErrorCode status; |
|||
const char *mySource; |
|||
const char *mySourceEnd; |
|||
UChar *myTarget; |
|||
int32_t bufferSize; |
|||
int32_t maxCPBytes; |
|||
int32_t bytesRead; |
|||
int32_t availLength; |
|||
int32_t dataSize; |
|||
char charBuffer[UFILE_CHARBUFFER_SIZE]; |
|||
u_localized_string *str; |
|||
|
|||
if (f->fFile == NULL) { |
|||
/* There is nothing to do. It's a string. */ |
|||
return; |
|||
} |
|||
|
|||
str = &f->str; |
|||
dataSize = (int32_t)(str->fLimit - str->fPos); |
|||
if (f->fFileno == 0 && dataSize > 0) { |
|||
/* Don't read from stdin too many times. There is still some data. */ |
|||
return; |
|||
} |
|||
|
|||
/* shift the buffer if it isn't empty */ |
|||
if(dataSize != 0) { |
|||
u_memmove(f->fUCBuffer, str->fPos, dataSize); /* not accessing beyond memory */ |
|||
} |
|||
|
|||
|
|||
/* record how much buffer space is available */ |
|||
availLength = UFILE_UCHARBUFFER_SIZE - dataSize; |
|||
|
|||
/* Determine the # of codepage bytes needed to fill our UChar buffer */ |
|||
/* weiv: if converter is NULL, we use invariant converter with charwidth = 1)*/ |
|||
maxCPBytes = availLength / (f->fConverter!=NULL?(2*ucnv_getMinCharSize(f->fConverter)):1); |
|||
|
|||
/* Read in the data to convert */ |
|||
if (f->fFileno == 0) { |
|||
/* Special case. Read from stdin one line at a time. */ |
|||
char *retStr = fgets(charBuffer, ufmt_min(maxCPBytes, UFILE_CHARBUFFER_SIZE), f->fFile); |
|||
bytesRead = (int32_t)(retStr ? uprv_strlen(charBuffer) : 0); |
|||
} |
|||
else { |
|||
/* A normal file */ |
|||
bytesRead = (int32_t)fread(charBuffer, |
|||
sizeof(char), |
|||
ufmt_min(maxCPBytes, UFILE_CHARBUFFER_SIZE), |
|||
f->fFile); |
|||
} |
|||
|
|||
/* Set up conversion parameters */ |
|||
status = U_ZERO_ERROR; |
|||
mySource = charBuffer; |
|||
mySourceEnd = charBuffer + bytesRead; |
|||
myTarget = f->fUCBuffer + dataSize; |
|||
bufferSize = UFILE_UCHARBUFFER_SIZE; |
|||
|
|||
if(f->fConverter != NULL) { /* We have a valid converter */ |
|||
/* Perform the conversion */ |
|||
ucnv_toUnicode(f->fConverter, |
|||
&myTarget, |
|||
f->fUCBuffer + bufferSize, |
|||
&mySource, |
|||
mySourceEnd, |
|||
NULL, |
|||
(UBool)(feof(f->fFile) != 0), |
|||
&status); |
|||
|
|||
} else { /*weiv: do the invariant conversion */ |
|||
u_charsToUChars(mySource, myTarget, bytesRead); |
|||
myTarget += bytesRead; |
|||
} |
|||
|
|||
/* update the pointers into our array */ |
|||
str->fPos = str->fBuffer; |
|||
str->fLimit = myTarget; |
|||
} |
|||
|
|||
U_CAPI UChar* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_fgets(UChar *s, |
|||
int32_t n, |
|||
UFILE *f) |
|||
{ |
|||
int32_t dataSize; |
|||
int32_t count; |
|||
UChar *alias; |
|||
const UChar *limit; |
|||
UChar *sItr; |
|||
UChar currDelim = 0; |
|||
u_localized_string *str; |
|||
|
|||
if (n <= 0) { |
|||
/* Caller screwed up. We need to write the null terminatior. */ |
|||
return NULL; |
|||
} |
|||
|
|||
/* fill the buffer if needed */ |
|||
str = &f->str; |
|||
if (str->fPos >= str->fLimit) { |
|||
ufile_fill_uchar_buffer(f); |
|||
} |
|||
|
|||
/* subtract 1 from n to compensate for the terminator */ |
|||
--n; |
|||
|
|||
/* determine the amount of data in the buffer */ |
|||
dataSize = (int32_t)(str->fLimit - str->fPos); |
|||
|
|||
/* if 0 characters were left, return 0 */ |
|||
if (dataSize == 0) |
|||
return NULL; |
|||
|
|||
/* otherwise, iteratively fill the buffer and copy */ |
|||
count = 0; |
|||
sItr = s; |
|||
currDelim = 0; |
|||
while (dataSize > 0 && count < n) { |
|||
alias = str->fPos; |
|||
|
|||
/* Find how much to copy */ |
|||
if (dataSize < (n - count)) { |
|||
limit = str->fLimit; |
|||
} |
|||
else { |
|||
limit = alias + (n - count); |
|||
} |
|||
|
|||
if (!currDelim) { |
|||
/* Copy UChars until we find the first occurrence of a delimiter character */ |
|||
while (alias < limit && !IS_FIRST_STRING_DELIMITER(*alias)) { |
|||
count++; |
|||
*(sItr++) = *(alias++); |
|||
} |
|||
/* Preserve the newline */ |
|||
if (alias < limit && IS_FIRST_STRING_DELIMITER(*alias)) { |
|||
if (CAN_HAVE_COMBINED_STRING_DELIMITER(*alias)) { |
|||
currDelim = *alias; |
|||
} |
|||
else { |
|||
currDelim = 1; /* This isn't a newline, but it's used to say
|
|||
that we should break later. We've checked all |
|||
possible newline combinations even across buffer |
|||
boundaries. */ |
|||
} |
|||
count++; |
|||
*(sItr++) = *(alias++); |
|||
} |
|||
} |
|||
/* If we have a CRLF combination, preserve that too. */ |
|||
if (alias < limit) { |
|||
if (currDelim && IS_COMBINED_STRING_DELIMITER(currDelim, *alias)) { |
|||
count++; |
|||
*(sItr++) = *(alias++); |
|||
} |
|||
currDelim = 1; /* This isn't a newline, but it's used to say
|
|||
that we should break later. We've checked all |
|||
possible newline combinations even across buffer |
|||
boundaries. */ |
|||
} |
|||
|
|||
/* update the current buffer position */ |
|||
str->fPos = alias; |
|||
|
|||
/* if we found a delimiter */ |
|||
if (currDelim == 1) { |
|||
/* break out */ |
|||
break; |
|||
} |
|||
|
|||
/* refill the buffer */ |
|||
ufile_fill_uchar_buffer(f); |
|||
|
|||
/* determine the amount of data in the buffer */ |
|||
dataSize = (int32_t)(str->fLimit - str->fPos); |
|||
} |
|||
|
|||
/* add the terminator and return s */ |
|||
*sItr = 0x0000; |
|||
return s; |
|||
} |
|||
|
|||
U_CFUNC UBool U_EXPORT2 |
|||
ufile_getch(UFILE *f, UChar *ch) |
|||
{ |
|||
UBool isValidChar = FALSE; |
|||
|
|||
*ch = U_EOF; |
|||
/* if we have an available character in the buffer, return it */ |
|||
if(f->str.fPos < f->str.fLimit){ |
|||
*ch = *(f->str.fPos)++; |
|||
isValidChar = TRUE; |
|||
} |
|||
else { |
|||
/* otherwise, fill the buffer and return the next character */ |
|||
if(f->str.fPos >= f->str.fLimit) { |
|||
ufile_fill_uchar_buffer(f); |
|||
} |
|||
if(f->str.fPos < f->str.fLimit) { |
|||
*ch = *(f->str.fPos)++; |
|||
isValidChar = TRUE; |
|||
} |
|||
} |
|||
return isValidChar; |
|||
} |
|||
|
|||
U_CAPI UChar U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_fgetc(UFILE *f) |
|||
{ |
|||
UChar ch; |
|||
ufile_getch(f, &ch); |
|||
return ch; |
|||
} |
|||
|
|||
U_CFUNC UBool U_EXPORT2 |
|||
ufile_getch32(UFILE *f, UChar32 *c32) |
|||
{ |
|||
UBool isValidChar = FALSE; |
|||
u_localized_string *str; |
|||
|
|||
*c32 = U_EOF; |
|||
|
|||
/* Fill the buffer if it is empty */ |
|||
str = &f->str; |
|||
if (f && str->fPos + 1 >= str->fLimit) { |
|||
ufile_fill_uchar_buffer(f); |
|||
} |
|||
|
|||
/* Get the next character in the buffer */ |
|||
if (str->fPos < str->fLimit) { |
|||
*c32 = *(str->fPos)++; |
|||
if (U_IS_LEAD(*c32)) { |
|||
if (str->fPos < str->fLimit) { |
|||
UChar c16 = *(str->fPos)++; |
|||
*c32 = U16_GET_SUPPLEMENTARY(*c32, c16); |
|||
isValidChar = TRUE; |
|||
} |
|||
else { |
|||
*c32 = U_EOF; |
|||
} |
|||
} |
|||
else { |
|||
isValidChar = TRUE; |
|||
} |
|||
} |
|||
|
|||
return isValidChar; |
|||
} |
|||
|
|||
U_CAPI UChar32 U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_fgetcx(UFILE *f) |
|||
{ |
|||
UChar32 ch; |
|||
ufile_getch32(f, &ch); |
|||
return ch; |
|||
} |
|||
|
|||
U_CAPI UChar32 U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_fungetc(UChar32 ch, |
|||
UFILE *f) |
|||
{ |
|||
u_localized_string *str; |
|||
|
|||
str = &f->str; |
|||
|
|||
/* if we're at the beginning of the buffer, sorry! */ |
|||
if (str->fPos == str->fBuffer |
|||
|| (U_IS_LEAD(ch) && (str->fPos - 1) == str->fBuffer)) |
|||
{ |
|||
ch = U_EOF; |
|||
} |
|||
else { |
|||
/* otherwise, put the character back */ |
|||
/* Remember, read them back on in the reverse order. */ |
|||
if (U_IS_LEAD(ch)) { |
|||
if (*--(str->fPos) != U16_TRAIL(ch) |
|||
|| *--(str->fPos) != U16_LEAD(ch)) |
|||
{ |
|||
ch = U_EOF; |
|||
} |
|||
} |
|||
else if (*--(str->fPos) != ch) { |
|||
ch = U_EOF; |
|||
} |
|||
} |
|||
return ch; |
|||
} |
|||
|
|||
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ |
|||
u_file_read( UChar *chars, |
|||
int32_t count, |
|||
UFILE *f) |
|||
{ |
|||
int32_t dataSize; |
|||
int32_t read = 0; |
|||
u_localized_string *str = &f->str; |
|||
|
|||
do { |
|||
|
|||
/* determine the amount of data in the buffer */ |
|||
dataSize = (int32_t)(str->fLimit - str->fPos); |
|||
if (dataSize <= 0) { |
|||
/* fill the buffer */ |
|||
ufile_fill_uchar_buffer(f); |
|||
dataSize = (int32_t)(str->fLimit - str->fPos); |
|||
} |
|||
|
|||
/* Make sure that we don't read too much */ |
|||
if (dataSize > (count - read)) { |
|||
dataSize = count - read; |
|||
} |
|||
|
|||
/* copy the current data in the buffer */ |
|||
memcpy(chars + read, str->fPos, dataSize * sizeof(UChar)); |
|||
|
|||
/* update number of items read */ |
|||
read += dataSize; |
|||
|
|||
/* update the current buffer position */ |
|||
str->fPos += dataSize; |
|||
} |
|||
while (dataSize != 0 && read < count); |
|||
|
|||
return read; |
|||
} |
|||
#endif |
@ -1,173 +0,0 @@ |
|||
// © 2016 and later: Unicode, Inc. and others.
|
|||
// License & terms of use: http://www.unicode.org/copyright.html
|
|||
/*
|
|||
********************************************************************** |
|||
* Copyright (C) 2001-2016, International Business Machines |
|||
* Corporation and others. All Rights Reserved. |
|||
********************************************************************** |
|||
* FILE NAME : ustream.cpp |
|||
* |
|||
* Modification History: |
|||
* |
|||
* Date Name Description |
|||
* 06/25/2001 grhoten Move iostream from unistr.h to here |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
#include "unicode/utypes.h" |
|||
|
|||
#if !UCONFIG_NO_CONVERSION |
|||
|
|||
#include "unicode/uobject.h" |
|||
#include "unicode/ustream.h" |
|||
#include "unicode/ucnv.h" |
|||
#include "unicode/uchar.h" |
|||
#include "unicode/utf16.h" |
|||
#include "ustr_cnv.h" |
|||
#include "cmemory.h" |
|||
#include <string.h> |
|||
|
|||
// console IO
|
|||
|
|||
#if U_IOSTREAM_SOURCE >= 199711 |
|||
|
|||
#define STD_NAMESPACE std:: |
|||
|
|||
#define STD_OSTREAM STD_NAMESPACE ostream |
|||
#define STD_ISTREAM STD_NAMESPACE istream |
|||
|
|||
U_NAMESPACE_BEGIN |
|||
|
|||
U_IO_API STD_OSTREAM & U_EXPORT2 |
|||
operator<<(STD_OSTREAM& stream, const UnicodeString& str) |
|||
{ |
|||
if(str.length() > 0) { |
|||
char buffer[200]; |
|||
UConverter *converter; |
|||
UErrorCode errorCode = U_ZERO_ERROR; |
|||
|
|||
// use the default converter to convert chunks of text
|
|||
converter = u_getDefaultConverter(&errorCode); |
|||
if(U_SUCCESS(errorCode)) { |
|||
const UChar *us = str.getBuffer(); |
|||
const UChar *uLimit = us + str.length(); |
|||
char *s, *sLimit = buffer + (sizeof(buffer) - 1); |
|||
do { |
|||
errorCode = U_ZERO_ERROR; |
|||
s = buffer; |
|||
ucnv_fromUnicode(converter, &s, sLimit, &us, uLimit, 0, FALSE, &errorCode); |
|||
*s = 0; |
|||
|
|||
// write this chunk
|
|||
if(s > buffer) { |
|||
stream << buffer; |
|||
} |
|||
} while(errorCode == U_BUFFER_OVERFLOW_ERROR); |
|||
u_releaseDefaultConverter(converter); |
|||
} |
|||
} |
|||
|
|||
/* stream.flush();*/ |
|||
return stream; |
|||
} |
|||
|
|||
U_IO_API STD_ISTREAM & U_EXPORT2 |
|||
operator>>(STD_ISTREAM& stream, UnicodeString& str) |
|||
{ |
|||
// This is like ICU status checking.
|
|||
if (stream.fail()) { |
|||
return stream; |
|||
} |
|||
|
|||
/* ipfx should eat whitespace when ios::skipws is set */ |
|||
UChar uBuffer[16]; |
|||
char buffer[16]; |
|||
int32_t idx = 0; |
|||
UConverter *converter; |
|||
UErrorCode errorCode = U_ZERO_ERROR; |
|||
|
|||
// use the default converter to convert chunks of text
|
|||
converter = u_getDefaultConverter(&errorCode); |
|||
if(U_SUCCESS(errorCode)) { |
|||
UChar *us = uBuffer; |
|||
const UChar *uLimit = uBuffer + UPRV_LENGTHOF(uBuffer); |
|||
const char *s, *sLimit; |
|||
char ch; |
|||
UChar ch32; |
|||
UBool initialWhitespace = TRUE; |
|||
UBool continueReading = TRUE; |
|||
|
|||
/* We need to consume one byte at a time to see what is considered whitespace. */ |
|||
while (continueReading) { |
|||
ch = stream.get(); |
|||
if (stream.eof()) { |
|||
// The EOF is only set after the get() of an unavailable byte.
|
|||
if (!initialWhitespace) { |
|||
stream.clear(stream.eofbit); |
|||
} |
|||
continueReading = FALSE; |
|||
} |
|||
sLimit = &ch + (int)continueReading; |
|||
us = uBuffer; |
|||
s = &ch; |
|||
errorCode = U_ZERO_ERROR; |
|||
/*
|
|||
Since we aren't guaranteed to see the state before this call, |
|||
this code won't work on stateful encodings like ISO-2022 or an EBCDIC stateful encoding. |
|||
We flush on the last byte to ensure that we output truncated multibyte characters. |
|||
*/ |
|||
ucnv_toUnicode(converter, &us, uLimit, &s, sLimit, 0, !continueReading, &errorCode); |
|||
if(U_FAILURE(errorCode)) { |
|||
/* Something really bad happened. setstate() isn't always an available API */ |
|||
stream.clear(stream.failbit); |
|||
goto STOP_READING; |
|||
} |
|||
/* Was the character consumed? */ |
|||
if (us != uBuffer) { |
|||
/* Reminder: ibm-1390 & JISX0213 can output 2 Unicode code points */ |
|||
int32_t uBuffSize = us-uBuffer; |
|||
int32_t uBuffIdx = 0; |
|||
while (uBuffIdx < uBuffSize) { |
|||
U16_NEXT(uBuffer, uBuffIdx, uBuffSize, ch32); |
|||
if (u_isWhitespace(ch32)) { |
|||
if (!initialWhitespace) { |
|||
buffer[idx++] = ch; |
|||
while (idx > 0) { |
|||
stream.putback(buffer[--idx]); |
|||
} |
|||
goto STOP_READING; |
|||
} |
|||
/* else skip intialWhitespace */ |
|||
} |
|||
else { |
|||
if (initialWhitespace) { |
|||
/*
|
|||
When initialWhitespace is TRUE, we haven't appended any |
|||
character yet. This is where we truncate the string, |
|||
to avoid modifying the string before we know if we can |
|||
actually read from the stream. |
|||
*/ |
|||
str.truncate(0); |
|||
initialWhitespace = FALSE; |
|||
} |
|||
str.append(ch32); |
|||
} |
|||
} |
|||
idx = 0; |
|||
} |
|||
else { |
|||
buffer[idx++] = ch; |
|||
} |
|||
} |
|||
STOP_READING: |
|||
u_releaseDefaultConverter(converter); |
|||
} |
|||
|
|||
/* stream.flush();*/ |
|||
return stream; |
|||
} |
|||
|
|||
U_NAMESPACE_END |
|||
|
|||
#endif |
|||
#endif |
Loading…
Reference in new issue