12e5b6d6dSopenharmony_ci// © 2018 and later: Unicode, Inc. and others. 22e5b6d6dSopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html 32e5b6d6dSopenharmony_ci 42e5b6d6dSopenharmony_ci// layoutpropsbuilder.cpp 52e5b6d6dSopenharmony_ci// created: 2018aug30 Markus W. Scherer 62e5b6d6dSopenharmony_ci 72e5b6d6dSopenharmony_ci#include <stdio.h> 82e5b6d6dSopenharmony_ci#include <string.h> 92e5b6d6dSopenharmony_ci#include "unicode/utypes.h" 102e5b6d6dSopenharmony_ci#include "unicode/uchar.h" 112e5b6d6dSopenharmony_ci#include "unicode/ucptrie.h" 122e5b6d6dSopenharmony_ci#include "unicode/udata.h" 132e5b6d6dSopenharmony_ci#include "unicode/umutablecptrie.h" 142e5b6d6dSopenharmony_ci#include "unicode/uniset.h" 152e5b6d6dSopenharmony_ci#include "cmemory.h" 162e5b6d6dSopenharmony_ci#include "genprops.h" 172e5b6d6dSopenharmony_ci#include "ppucd.h" 182e5b6d6dSopenharmony_ci#include "uassert.h" 192e5b6d6dSopenharmony_ci#include "ulayout_props.h" 202e5b6d6dSopenharmony_ci#include "unewdata.h" 212e5b6d6dSopenharmony_ci 222e5b6d6dSopenharmony_ci/* Unicode layout properties file format --------------------------------------- 232e5b6d6dSopenharmony_ci 242e5b6d6dSopenharmony_ciThe file format prepared and written here contains several data 252e5b6d6dSopenharmony_cistructures that store indexes or data. 262e5b6d6dSopenharmony_ci 272e5b6d6dSopenharmony_ciBefore the data contents described below, there are the headers required by 282e5b6d6dSopenharmony_cithe udata API for loading ICU data. Especially, a UDataInfo structure 292e5b6d6dSopenharmony_ciprecedes the actual data. It contains platform properties values and the 302e5b6d6dSopenharmony_cifile format version. 312e5b6d6dSopenharmony_ci 322e5b6d6dSopenharmony_ciThe following is a description of format version 1.0 . 332e5b6d6dSopenharmony_ci 342e5b6d6dSopenharmony_ciThe file contains the following structures: 352e5b6d6dSopenharmony_ci 362e5b6d6dSopenharmony_ci const int32_t indexes[i0] with values i0, i1, ...: 372e5b6d6dSopenharmony_ci (see ULAYOUT_IX_... constants for names of indexes) 382e5b6d6dSopenharmony_ci 392e5b6d6dSopenharmony_ci i0 indexesLength; -- length of indexes[] (ULAYOUT_IX_COUNT) 402e5b6d6dSopenharmony_ci i1 inpcTop; -- limit byte offset of the InPC trie 412e5b6d6dSopenharmony_ci i2 inscTop; -- limit byte offset of the InSC trie 422e5b6d6dSopenharmony_ci i3 voTop; -- limit byte offset of the vo trie 432e5b6d6dSopenharmony_ci i4..i7 -- reserved, same as the last limit byte offset 442e5b6d6dSopenharmony_ci i8 -- reserved, 0 452e5b6d6dSopenharmony_ci 462e5b6d6dSopenharmony_ci i9 maxValues; -- max values of the InPC, InSC, vo properties 472e5b6d6dSopenharmony_ci (8 bits each; lowest 8 bits reserved, 0) 482e5b6d6dSopenharmony_ci i10..i11 -- reserved, 0 492e5b6d6dSopenharmony_ci 502e5b6d6dSopenharmony_ci After the indexes array follow consecutive, serialized, 512e5b6d6dSopenharmony_ci single-property code point tries for the following properties, 522e5b6d6dSopenharmony_ci each built "small" or "fast", 532e5b6d6dSopenharmony_ci each padded to a multiple of 16 bytes: 542e5b6d6dSopenharmony_ci - InPC 552e5b6d6dSopenharmony_ci - InSC 562e5b6d6dSopenharmony_ci - vo 572e5b6d6dSopenharmony_ci 582e5b6d6dSopenharmony_ci----------------------------------------------------------------------------- */ 592e5b6d6dSopenharmony_ci 602e5b6d6dSopenharmony_ciU_NAMESPACE_USE 612e5b6d6dSopenharmony_ci 622e5b6d6dSopenharmony_ci// UDataInfo cf. udata.h 632e5b6d6dSopenharmony_cistatic UDataInfo dataInfo = { 642e5b6d6dSopenharmony_ci sizeof(UDataInfo), 652e5b6d6dSopenharmony_ci 0, 662e5b6d6dSopenharmony_ci 672e5b6d6dSopenharmony_ci U_IS_BIG_ENDIAN, 682e5b6d6dSopenharmony_ci U_CHARSET_FAMILY, 692e5b6d6dSopenharmony_ci U_SIZEOF_UCHAR, 702e5b6d6dSopenharmony_ci 0, 712e5b6d6dSopenharmony_ci 722e5b6d6dSopenharmony_ci // dataFormat="Layo" 732e5b6d6dSopenharmony_ci { ULAYOUT_FMT_0, ULAYOUT_FMT_1, ULAYOUT_FMT_2, ULAYOUT_FMT_3 }, 742e5b6d6dSopenharmony_ci { 1, 0, 0, 0 }, // formatVersion 752e5b6d6dSopenharmony_ci { 12, 0, 0, 0 } // dataVersion 762e5b6d6dSopenharmony_ci}; 772e5b6d6dSopenharmony_ci 782e5b6d6dSopenharmony_ciclass LayoutPropsBuilder : public PropsBuilder { 792e5b6d6dSopenharmony_cipublic: 802e5b6d6dSopenharmony_ci LayoutPropsBuilder(UErrorCode &errorCode); 812e5b6d6dSopenharmony_ci virtual ~LayoutPropsBuilder() U_OVERRIDE; 822e5b6d6dSopenharmony_ci 832e5b6d6dSopenharmony_ci virtual void setUnicodeVersion(const UVersionInfo version) U_OVERRIDE; 842e5b6d6dSopenharmony_ci virtual void setProps(const UniProps &props, const UnicodeSet &newValues, UErrorCode &errorCode) U_OVERRIDE; 852e5b6d6dSopenharmony_ci virtual void build(UErrorCode &errorCode) U_OVERRIDE; 862e5b6d6dSopenharmony_ci virtual void writeBinaryData(const char *path, UBool withCopyright, UErrorCode &errorCode) U_OVERRIDE; 872e5b6d6dSopenharmony_ci 882e5b6d6dSopenharmony_ciprivate: 892e5b6d6dSopenharmony_ci void setIntProp(const UniProps &, const UnicodeSet &newValues, 902e5b6d6dSopenharmony_ci UProperty prop, UMutableCPTrie *trie, 912e5b6d6dSopenharmony_ci UErrorCode &errorCode); 922e5b6d6dSopenharmony_ci int32_t getMaxIntValue(UProperty prop) const { 932e5b6d6dSopenharmony_ci return maxIntValues[prop - UCHAR_INT_START]; 942e5b6d6dSopenharmony_ci } 952e5b6d6dSopenharmony_ci void checkMaxIntValue(UProperty prop, int32_t maxMax, UErrorCode &errorCode) const; 962e5b6d6dSopenharmony_ci 972e5b6d6dSopenharmony_ci int32_t maxIntValues[UCHAR_INT_LIMIT - UCHAR_INT_START]; 982e5b6d6dSopenharmony_ci UMutableCPTrie *inpcMutableTrie; 992e5b6d6dSopenharmony_ci UMutableCPTrie *inscMutableTrie; 1002e5b6d6dSopenharmony_ci UMutableCPTrie *voMutableTrie; 1012e5b6d6dSopenharmony_ci 1022e5b6d6dSopenharmony_ci UCPTrie *inpcTrie; 1032e5b6d6dSopenharmony_ci UCPTrie *inscTrie; 1042e5b6d6dSopenharmony_ci UCPTrie *voTrie; 1052e5b6d6dSopenharmony_ci}; 1062e5b6d6dSopenharmony_ci 1072e5b6d6dSopenharmony_ciLayoutPropsBuilder::LayoutPropsBuilder(UErrorCode &errorCode) : 1082e5b6d6dSopenharmony_ci inpcTrie(nullptr), inscTrie(nullptr), voTrie(nullptr) { 1092e5b6d6dSopenharmony_ci memset(maxIntValues, 0, sizeof(maxIntValues)); 1102e5b6d6dSopenharmony_ci inpcMutableTrie = umutablecptrie_open(0, 0, &errorCode); 1112e5b6d6dSopenharmony_ci inscMutableTrie = umutablecptrie_open(0, 0, &errorCode); 1122e5b6d6dSopenharmony_ci voMutableTrie = umutablecptrie_open(0, 0, &errorCode); 1132e5b6d6dSopenharmony_ci if (U_FAILURE(errorCode)) { 1142e5b6d6dSopenharmony_ci fprintf(stderr, "genprops error: layoutpropsbuilder umutablecptrie_open() failed - %s\n", 1152e5b6d6dSopenharmony_ci u_errorName(errorCode)); 1162e5b6d6dSopenharmony_ci } 1172e5b6d6dSopenharmony_ci} 1182e5b6d6dSopenharmony_ci 1192e5b6d6dSopenharmony_ciLayoutPropsBuilder::~LayoutPropsBuilder() { 1202e5b6d6dSopenharmony_ci umutablecptrie_close(inpcMutableTrie); 1212e5b6d6dSopenharmony_ci umutablecptrie_close(inscMutableTrie); 1222e5b6d6dSopenharmony_ci umutablecptrie_close(voMutableTrie); 1232e5b6d6dSopenharmony_ci ucptrie_close(inpcTrie); 1242e5b6d6dSopenharmony_ci ucptrie_close(inscTrie); 1252e5b6d6dSopenharmony_ci ucptrie_close(voTrie); 1262e5b6d6dSopenharmony_ci} 1272e5b6d6dSopenharmony_ci 1282e5b6d6dSopenharmony_civoid 1292e5b6d6dSopenharmony_ciLayoutPropsBuilder::setUnicodeVersion(const UVersionInfo version) { 1302e5b6d6dSopenharmony_ci uprv_memcpy(dataInfo.dataVersion, version, 4); 1312e5b6d6dSopenharmony_ci} 1322e5b6d6dSopenharmony_ci 1332e5b6d6dSopenharmony_civoid 1342e5b6d6dSopenharmony_ciLayoutPropsBuilder::setProps(const UniProps &props, const UnicodeSet &newValues, 1352e5b6d6dSopenharmony_ci UErrorCode &errorCode) { 1362e5b6d6dSopenharmony_ci setIntProp(props, newValues, UCHAR_INDIC_POSITIONAL_CATEGORY, inpcMutableTrie, errorCode); 1372e5b6d6dSopenharmony_ci setIntProp(props, newValues, UCHAR_INDIC_SYLLABIC_CATEGORY, inscMutableTrie, errorCode); 1382e5b6d6dSopenharmony_ci setIntProp(props, newValues, UCHAR_VERTICAL_ORIENTATION, voMutableTrie, errorCode); 1392e5b6d6dSopenharmony_ci} 1402e5b6d6dSopenharmony_ci 1412e5b6d6dSopenharmony_civoid LayoutPropsBuilder::setIntProp(const UniProps &props, const UnicodeSet &newValues, 1422e5b6d6dSopenharmony_ci UProperty prop, UMutableCPTrie *trie, 1432e5b6d6dSopenharmony_ci UErrorCode &errorCode) { 1442e5b6d6dSopenharmony_ci if (U_SUCCESS(errorCode) && newValues.contains(prop)) { 1452e5b6d6dSopenharmony_ci UChar32 start=props.start; 1462e5b6d6dSopenharmony_ci UChar32 end=props.end; 1472e5b6d6dSopenharmony_ci int32_t value = props.getIntProp(prop); 1482e5b6d6dSopenharmony_ci if (value < 0) { 1492e5b6d6dSopenharmony_ci fprintf(stderr, "error: unencodable negative value for property 0x%x %04lX..%04lX=%ld\n", 1502e5b6d6dSopenharmony_ci (int)prop, (long)start, (long)end, (long)value); 1512e5b6d6dSopenharmony_ci errorCode = U_ILLEGAL_ARGUMENT_ERROR; 1522e5b6d6dSopenharmony_ci return; 1532e5b6d6dSopenharmony_ci } 1542e5b6d6dSopenharmony_ci if (value > maxIntValues[prop - UCHAR_INT_START]) { 1552e5b6d6dSopenharmony_ci maxIntValues[prop - UCHAR_INT_START] = value; 1562e5b6d6dSopenharmony_ci } 1572e5b6d6dSopenharmony_ci if (start == end) { 1582e5b6d6dSopenharmony_ci umutablecptrie_set(trie, start, value, &errorCode); 1592e5b6d6dSopenharmony_ci } else { 1602e5b6d6dSopenharmony_ci umutablecptrie_setRange(trie, start, end, value, &errorCode); 1612e5b6d6dSopenharmony_ci } 1622e5b6d6dSopenharmony_ci if (U_FAILURE(errorCode)) { 1632e5b6d6dSopenharmony_ci fprintf(stderr, "error: umutablecptrie_set(prop 0x%x trie %04lX..%04lX) failed - %s\n", 1642e5b6d6dSopenharmony_ci (int)prop, (long)start, (long)end, u_errorName(errorCode)); 1652e5b6d6dSopenharmony_ci } 1662e5b6d6dSopenharmony_ci } 1672e5b6d6dSopenharmony_ci} 1682e5b6d6dSopenharmony_ci 1692e5b6d6dSopenharmony_cinamespace { 1702e5b6d6dSopenharmony_ci 1712e5b6d6dSopenharmony_ciUCPTrie *buildUCPTrie(const char *name, UMutableCPTrie *mutableTrie, 1722e5b6d6dSopenharmony_ci UCPTrieType type, UCPTrieValueWidth valueWidth, UErrorCode &errorCode) { 1732e5b6d6dSopenharmony_ci UCPTrie *trie = umutablecptrie_buildImmutable(mutableTrie, type, valueWidth, &errorCode); 1742e5b6d6dSopenharmony_ci if(U_FAILURE(errorCode)) { 1752e5b6d6dSopenharmony_ci fprintf(stderr, "genprops error: %s trie buildImmutable() failed: %s\n", 1762e5b6d6dSopenharmony_ci name, u_errorName(errorCode)); 1772e5b6d6dSopenharmony_ci return trie; 1782e5b6d6dSopenharmony_ci } 1792e5b6d6dSopenharmony_ci if (!beQuiet) { 1802e5b6d6dSopenharmony_ci UErrorCode overflow = U_ZERO_ERROR; 1812e5b6d6dSopenharmony_ci int32_t length = ucptrie_toBinary(trie, nullptr, 0, &overflow); 1822e5b6d6dSopenharmony_ci printf("%11s trie size in bytes: %5u\n", name, (int)length); 1832e5b6d6dSopenharmony_ci } 1842e5b6d6dSopenharmony_ci return trie; 1852e5b6d6dSopenharmony_ci} 1862e5b6d6dSopenharmony_ci 1872e5b6d6dSopenharmony_ciconstexpr int32_t TRIE_BLOCK_CAPACITY = 100000; 1882e5b6d6dSopenharmony_ci 1892e5b6d6dSopenharmony_ciuint8_t inpcBytes[TRIE_BLOCK_CAPACITY]; 1902e5b6d6dSopenharmony_ciuint8_t inscBytes[TRIE_BLOCK_CAPACITY]; 1912e5b6d6dSopenharmony_ciuint8_t voBytes[TRIE_BLOCK_CAPACITY]; 1922e5b6d6dSopenharmony_ci 1932e5b6d6dSopenharmony_ciint32_t inpcLength = 0; 1942e5b6d6dSopenharmony_ciint32_t inscLength = 0; 1952e5b6d6dSopenharmony_ciint32_t voLength = 0; 1962e5b6d6dSopenharmony_ci 1972e5b6d6dSopenharmony_ciint32_t writeTrieBytes(const UCPTrie *trie, uint8_t block[], UErrorCode &errorCode) { 1982e5b6d6dSopenharmony_ci int32_t length = ucptrie_toBinary(trie, block, TRIE_BLOCK_CAPACITY, &errorCode); 1992e5b6d6dSopenharmony_ci while ((length & 0xf) != 0) { 2002e5b6d6dSopenharmony_ci block[length++] = 0xaa; 2012e5b6d6dSopenharmony_ci } 2022e5b6d6dSopenharmony_ci return length; 2032e5b6d6dSopenharmony_ci} 2042e5b6d6dSopenharmony_ci 2052e5b6d6dSopenharmony_ci} // namespace 2062e5b6d6dSopenharmony_ci 2072e5b6d6dSopenharmony_civoid 2082e5b6d6dSopenharmony_ciLayoutPropsBuilder::build(UErrorCode &errorCode) { 2092e5b6d6dSopenharmony_ci if (U_FAILURE(errorCode)) { return; } 2102e5b6d6dSopenharmony_ci if (!beQuiet) { 2112e5b6d6dSopenharmony_ci puts("* text layout properties stats *"); 2122e5b6d6dSopenharmony_ci } 2132e5b6d6dSopenharmony_ci 2142e5b6d6dSopenharmony_ci checkMaxIntValue(UCHAR_INDIC_POSITIONAL_CATEGORY, 0xff, errorCode); 2152e5b6d6dSopenharmony_ci checkMaxIntValue(UCHAR_INDIC_SYLLABIC_CATEGORY, 0xff, errorCode); 2162e5b6d6dSopenharmony_ci checkMaxIntValue(UCHAR_VERTICAL_ORIENTATION, 0xff, errorCode); 2172e5b6d6dSopenharmony_ci inpcTrie = buildUCPTrie("inpc", inpcMutableTrie, 2182e5b6d6dSopenharmony_ci UCPTRIE_TYPE_SMALL, UCPTRIE_VALUE_BITS_8, errorCode); 2192e5b6d6dSopenharmony_ci inscTrie = buildUCPTrie("insc", inscMutableTrie, 2202e5b6d6dSopenharmony_ci UCPTRIE_TYPE_SMALL, UCPTRIE_VALUE_BITS_8, errorCode); 2212e5b6d6dSopenharmony_ci voTrie = buildUCPTrie("vo", voMutableTrie, 2222e5b6d6dSopenharmony_ci UCPTRIE_TYPE_SMALL, UCPTRIE_VALUE_BITS_8, errorCode); 2232e5b6d6dSopenharmony_ci 2242e5b6d6dSopenharmony_ci inpcLength = writeTrieBytes(inpcTrie, inpcBytes, errorCode); 2252e5b6d6dSopenharmony_ci inscLength = writeTrieBytes(inscTrie, inscBytes, errorCode); 2262e5b6d6dSopenharmony_ci voLength = writeTrieBytes(voTrie, voBytes, errorCode); 2272e5b6d6dSopenharmony_ci 2282e5b6d6dSopenharmony_ci if (!beQuiet) { 2292e5b6d6dSopenharmony_ci int32_t size = ULAYOUT_IX_COUNT * 4 + inpcLength + inscLength + voLength; 2302e5b6d6dSopenharmony_ci printf("data size: %5d\n", (int)size); 2312e5b6d6dSopenharmony_ci } 2322e5b6d6dSopenharmony_ci} 2332e5b6d6dSopenharmony_ci 2342e5b6d6dSopenharmony_civoid LayoutPropsBuilder::checkMaxIntValue(UProperty prop, int32_t maxMax, 2352e5b6d6dSopenharmony_ci UErrorCode &errorCode) const { 2362e5b6d6dSopenharmony_ci int32_t max = getMaxIntValue(prop); 2372e5b6d6dSopenharmony_ci if (max > maxMax) { 2382e5b6d6dSopenharmony_ci fprintf(stderr, "genprops error: 0x%x max value = %d overflow\n", (int)prop, (int)max); 2392e5b6d6dSopenharmony_ci errorCode = U_ILLEGAL_ARGUMENT_ERROR; 2402e5b6d6dSopenharmony_ci } 2412e5b6d6dSopenharmony_ci} 2422e5b6d6dSopenharmony_ci 2432e5b6d6dSopenharmony_ci// In ICU 63, we had functions writeCSourceFile() and writeJavaSourceFile(). 2442e5b6d6dSopenharmony_ci// For Java, each serialized trie was written as a String constant with 2452e5b6d6dSopenharmony_ci// one byte per char and an optimization for byte 0, 2462e5b6d6dSopenharmony_ci// to optimize for Java .class file size. 2472e5b6d6dSopenharmony_ci// (See ICU 63 if we need to resurrect some of that code.) 2482e5b6d6dSopenharmony_ci// Since ICU 64, we write a binary ulayout.icu file for use in both C++ & Java. 2492e5b6d6dSopenharmony_ci 2502e5b6d6dSopenharmony_civoid 2512e5b6d6dSopenharmony_ciLayoutPropsBuilder::writeBinaryData(const char *path, UBool withCopyright, UErrorCode &errorCode) { 2522e5b6d6dSopenharmony_ci if (U_FAILURE(errorCode)) { return; } 2532e5b6d6dSopenharmony_ci 2542e5b6d6dSopenharmony_ci UNewDataMemory *pData = udata_create( 2552e5b6d6dSopenharmony_ci path, ULAYOUT_DATA_TYPE, ULAYOUT_DATA_NAME, &dataInfo, 2562e5b6d6dSopenharmony_ci withCopyright ? U_COPYRIGHT_STRING : NULL, &errorCode); 2572e5b6d6dSopenharmony_ci if (U_FAILURE(errorCode)) { 2582e5b6d6dSopenharmony_ci fprintf(stderr, "genprops: udata_create(%s, ulayout.icu) failed - %s\n", 2592e5b6d6dSopenharmony_ci path, u_errorName(errorCode)); 2602e5b6d6dSopenharmony_ci return; 2612e5b6d6dSopenharmony_ci } 2622e5b6d6dSopenharmony_ci 2632e5b6d6dSopenharmony_ci int32_t indexes[ULAYOUT_IX_COUNT] = { ULAYOUT_IX_COUNT }; 2642e5b6d6dSopenharmony_ci int32_t top = ULAYOUT_IX_COUNT * 4; 2652e5b6d6dSopenharmony_ci 2662e5b6d6dSopenharmony_ci indexes[ULAYOUT_IX_INPC_TRIE_TOP] = (top += inpcLength); 2672e5b6d6dSopenharmony_ci indexes[ULAYOUT_IX_INSC_TRIE_TOP] = (top += inscLength); 2682e5b6d6dSopenharmony_ci indexes[ULAYOUT_IX_VO_TRIE_TOP] = (top += voLength); 2692e5b6d6dSopenharmony_ci 2702e5b6d6dSopenharmony_ci // Set reserved trie-top values to the top of the last trie 2712e5b6d6dSopenharmony_ci // so that they look empty until a later file format version 2722e5b6d6dSopenharmony_ci // uses one or more of these slots. 2732e5b6d6dSopenharmony_ci for (int32_t i = ULAYOUT_IX_RESERVED_TOP; i <= ULAYOUT_IX_TRIES_TOP; ++i) { 2742e5b6d6dSopenharmony_ci indexes[i] = top; 2752e5b6d6dSopenharmony_ci } 2762e5b6d6dSopenharmony_ci 2772e5b6d6dSopenharmony_ci indexes[ULAYOUT_IX_MAX_VALUES] = 2782e5b6d6dSopenharmony_ci ((getMaxIntValue(UCHAR_INDIC_POSITIONAL_CATEGORY)) << ULAYOUT_MAX_INPC_SHIFT) | 2792e5b6d6dSopenharmony_ci ((getMaxIntValue(UCHAR_INDIC_SYLLABIC_CATEGORY)) << ULAYOUT_MAX_INSC_SHIFT) | 2802e5b6d6dSopenharmony_ci ((getMaxIntValue(UCHAR_VERTICAL_ORIENTATION)) << ULAYOUT_MAX_VO_SHIFT); 2812e5b6d6dSopenharmony_ci 2822e5b6d6dSopenharmony_ci udata_writeBlock(pData, indexes, sizeof(indexes)); 2832e5b6d6dSopenharmony_ci udata_writeBlock(pData, inpcBytes, inpcLength); 2842e5b6d6dSopenharmony_ci udata_writeBlock(pData, inscBytes, inscLength); 2852e5b6d6dSopenharmony_ci udata_writeBlock(pData, voBytes, voLength); 2862e5b6d6dSopenharmony_ci 2872e5b6d6dSopenharmony_ci long dataLength = udata_finish(pData, &errorCode); 2882e5b6d6dSopenharmony_ci if (U_FAILURE(errorCode)) { 2892e5b6d6dSopenharmony_ci fprintf(stderr, "genprops: error %s writing the output file\n", u_errorName(errorCode)); 2902e5b6d6dSopenharmony_ci return; 2912e5b6d6dSopenharmony_ci } 2922e5b6d6dSopenharmony_ci 2932e5b6d6dSopenharmony_ci if (dataLength != (long)top) { 2942e5b6d6dSopenharmony_ci fprintf(stderr, 2952e5b6d6dSopenharmony_ci "udata_finish(ulayout.icu) reports %ld bytes written but should be %ld\n", 2962e5b6d6dSopenharmony_ci dataLength, (long)top); 2972e5b6d6dSopenharmony_ci errorCode = U_INTERNAL_PROGRAM_ERROR; 2982e5b6d6dSopenharmony_ci } 2992e5b6d6dSopenharmony_ci} 3002e5b6d6dSopenharmony_ci 3012e5b6d6dSopenharmony_ciPropsBuilder * 3022e5b6d6dSopenharmony_cicreateLayoutPropsBuilder(UErrorCode &errorCode) { 3032e5b6d6dSopenharmony_ci if(U_FAILURE(errorCode)) { return nullptr; } 3042e5b6d6dSopenharmony_ci PropsBuilder *pb=new LayoutPropsBuilder(errorCode); 3052e5b6d6dSopenharmony_ci if(pb==nullptr) { 3062e5b6d6dSopenharmony_ci errorCode=U_MEMORY_ALLOCATION_ERROR; 3072e5b6d6dSopenharmony_ci } 3082e5b6d6dSopenharmony_ci return pb; 3092e5b6d6dSopenharmony_ci} 310