os/textandloc/fontservices/textshaperplugin/IcuSource/common/propname.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200 (2014-06-10)
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
**********************************************************************
sl@0
     3
* Copyright (c) 2002-2004, International Business Machines
sl@0
     4
* Corporation and others.  All Rights Reserved.
sl@0
     5
**********************************************************************
sl@0
     6
* Author: Alan Liu
sl@0
     7
* Created: October 30 2002
sl@0
     8
* Since: ICU 2.4
sl@0
     9
**********************************************************************
sl@0
    10
*/
sl@0
    11
#ifndef PROPNAME_H
sl@0
    12
#define PROPNAME_H
sl@0
    13
sl@0
    14
#include "unicode/utypes.h"
sl@0
    15
#include "unicode/uchar.h"
sl@0
    16
#include "udataswp.h"
sl@0
    17
#include "uprops.h"
sl@0
    18
sl@0
    19
/*
sl@0
    20
 * This header defines the in-memory layout of the property names data
sl@0
    21
 * structure representing the UCD data files PropertyAliases.txt and
sl@0
    22
 * PropertyValueAliases.txt.  It is used by:
sl@0
    23
 *   propname.cpp - reads data
sl@0
    24
 *   genpname     - creates data
sl@0
    25
 */
sl@0
    26
sl@0
    27
/* low-level char * property name comparison -------------------------------- */
sl@0
    28
sl@0
    29
U_CDECL_BEGIN
sl@0
    30
sl@0
    31
/**
sl@0
    32
 * \var uprv_comparePropertyNames
sl@0
    33
 * Unicode property names and property value names are compared "loosely".
sl@0
    34
 *
sl@0
    35
 * UCD.html 4.0.1 says:
sl@0
    36
 *   For all property names, property value names, and for property values for
sl@0
    37
 *   Enumerated, Binary, or Catalog properties, use the following
sl@0
    38
 *   loose matching rule:
sl@0
    39
 *
sl@0
    40
 *   LM3. Ignore case, whitespace, underscore ('_'), and hyphens.
sl@0
    41
 *
sl@0
    42
 * This function does just that, for (char *) name strings.
sl@0
    43
 * It is almost identical to ucnv_compareNames() but also ignores
sl@0
    44
 * C0 White_Space characters (U+0009..U+000d, and U+0085 on EBCDIC).
sl@0
    45
 *
sl@0
    46
 * @internal
sl@0
    47
 */
sl@0
    48
sl@0
    49
U_CAPI int32_t U_EXPORT2
sl@0
    50
uprv_compareASCIIPropertyNames(const char *name1, const char *name2);
sl@0
    51
sl@0
    52
U_CAPI int32_t U_EXPORT2
sl@0
    53
uprv_compareEBCDICPropertyNames(const char *name1, const char *name2);
sl@0
    54
sl@0
    55
#if U_CHARSET_FAMILY==U_ASCII_FAMILY
sl@0
    56
#   define uprv_comparePropertyNames uprv_compareASCIIPropertyNames
sl@0
    57
#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
sl@0
    58
#   define uprv_comparePropertyNames uprv_compareEBCDICPropertyNames
sl@0
    59
#else
sl@0
    60
#   error U_CHARSET_FAMILY is not valid
sl@0
    61
#endif
sl@0
    62
sl@0
    63
U_CDECL_END
sl@0
    64
sl@0
    65
/* UDataMemory structure and signatures ------------------------------------- */
sl@0
    66
sl@0
    67
#define PNAME_DATA_NAME "pnames"
sl@0
    68
#define PNAME_DATA_TYPE "icu"
sl@0
    69
sl@0
    70
/* Fields in UDataInfo: */
sl@0
    71
sl@0
    72
/* PNAME_SIG[] is encoded as numeric literals for compatibility with the HP compiler */
sl@0
    73
#define PNAME_SIG_0 ((uint8_t)0x70) /* p */
sl@0
    74
#define PNAME_SIG_1 ((uint8_t)0x6E) /* n */
sl@0
    75
#define PNAME_SIG_2 ((uint8_t)0x61) /* a */
sl@0
    76
#define PNAME_SIG_3 ((uint8_t)0x6D) /* m */
sl@0
    77
sl@0
    78
#define PNAME_FORMAT_VERSION ((int8_t)1) /* formatVersion[0] */
sl@0
    79
sl@0
    80
/**
sl@0
    81
 * Swap pnames.icu. See udataswp.h.
sl@0
    82
 * @internal
sl@0
    83
 */
sl@0
    84
U_CAPI int32_t U_EXPORT2
sl@0
    85
upname_swap(const UDataSwapper *ds,
sl@0
    86
            const void *inData, int32_t length, void *outData,
sl@0
    87
            UErrorCode *pErrorCode);
sl@0
    88
sl@0
    89
sl@0
    90
#ifdef XP_CPLUSPLUS
sl@0
    91
sl@0
    92
class Builder;
sl@0
    93
sl@0
    94
U_NAMESPACE_BEGIN
sl@0
    95
sl@0
    96
/**
sl@0
    97
 * An offset from the start of the pnames data to a contained entity.
sl@0
    98
 * This must be a signed value, since negative offsets are used as an
sl@0
    99
 * end-of-list marker.  Offsets to actual objects are non-zero.  A
sl@0
   100
 * zero offset indicates an absent entry; this corresponds to aliases
sl@0
   101
 * marked "n/a" in the original Unicode data files.
sl@0
   102
 */
sl@0
   103
typedef int16_t Offset; /*  must be signed */
sl@0
   104
sl@0
   105
#define MAX_OFFSET 0x7FFF
sl@0
   106
sl@0
   107
/**
sl@0
   108
 * A generic value for a property or property value.  Typically an
sl@0
   109
 * enum from uchar.h, but sometimes a non-enum value.  It must be
sl@0
   110
 * large enough to accomodate the largest enum value, which as of this
sl@0
   111
 * writing is the largest general category mask.  Need not be signed
sl@0
   112
 * but may be.  Typically it doesn't matter, since the caller will
sl@0
   113
 * cast it to the proper type before use.  Takes the special value
sl@0
   114
 * UCHAR_INVALID_CODE for invalid input.
sl@0
   115
 */
sl@0
   116
typedef int32_t EnumValue;
sl@0
   117
sl@0
   118
/* ---------------------------------------------------------------------- */
sl@0
   119
/*  ValueMap */
sl@0
   120
sl@0
   121
/**
sl@0
   122
 * For any top-level property that has named values (binary and
sl@0
   123
 * enumerated properties), there is a ValueMap object.  This object
sl@0
   124
 * maps from enum values to two other maps.  One goes from value enums
sl@0
   125
 * to value names.  The other goes from value names to value enums.
sl@0
   126
 * 
sl@0
   127
 * The value enum values may be contiguous or disjoint.  If they are
sl@0
   128
 * contiguous then the enumToName_offset is nonzero, and the
sl@0
   129
 * ncEnumToName_offset is zero.  Vice versa if the value enums are
sl@0
   130
 * disjoint.
sl@0
   131
 *
sl@0
   132
 * There are n of these objects, where n is the number of binary
sl@0
   133
 * properties + the number of enumerated properties.
sl@0
   134
 */
sl@0
   135
struct ValueMap {
sl@0
   136
sl@0
   137
    /*  -- begin pnames data -- */
sl@0
   138
    /*  Enum=>name EnumToOffset / NonContiguousEnumToOffset objects. */
sl@0
   139
    /*  Exactly one of these will be nonzero. */
sl@0
   140
    Offset enumToName_offset;
sl@0
   141
    Offset ncEnumToName_offset;
sl@0
   142
sl@0
   143
    Offset nameToEnum_offset; /*  Name=>enum data */
sl@0
   144
    /*  -- end pnames data -- */
sl@0
   145
};
sl@0
   146
sl@0
   147
/* ---------------------------------------------------------------------- */
sl@0
   148
/*  PropertyAliases class */
sl@0
   149
sl@0
   150
/**
sl@0
   151
 * A class encapsulating access to the memory-mapped data representing
sl@0
   152
 * property aliases and property value aliases (pnames).  The class
sl@0
   153
 * MUST have no v-table and declares certain methods inline -- small
sl@0
   154
 * methods and methods that are called from only one point.
sl@0
   155
 *
sl@0
   156
 * The data members in this class correspond to the in-memory layout
sl@0
   157
 * of the header of the pnames data.
sl@0
   158
 */
sl@0
   159
class PropertyAliases {
sl@0
   160
sl@0
   161
    /*  -- begin pnames data -- */
sl@0
   162
    /*  Enum=>name EnumToOffset object for binary and enumerated */
sl@0
   163
    /*  properties */
sl@0
   164
    Offset enumToName_offset;
sl@0
   165
sl@0
   166
    /*  Name=>enum data for binary & enumerated properties */
sl@0
   167
    Offset nameToEnum_offset;
sl@0
   168
sl@0
   169
    /*  Enum=>offset EnumToOffset object mapping enumerated properties */
sl@0
   170
    /*  to ValueMap objects */
sl@0
   171
    Offset enumToValue_offset;
sl@0
   172
sl@0
   173
    /*  The following are needed by external readers of this data. */
sl@0
   174
    /*  We don't use them ourselves. */
sl@0
   175
    int16_t total_size; /*  size in bytes excluding the udata header */
sl@0
   176
    Offset valueMap_offset; /*  offset to start of array */
sl@0
   177
    int16_t valueMap_count; /*  number of entries */
sl@0
   178
    Offset nameGroupPool_offset; /*  offset to start of array */
sl@0
   179
    int16_t nameGroupPool_count; /*  number of entries (not groups) */
sl@0
   180
    Offset stringPool_offset; /*  offset to start of pool */
sl@0
   181
    int16_t stringPool_count; /*  number of strings (not size in bytes) */
sl@0
   182
sl@0
   183
    /*  -- end pnames data -- */
sl@0
   184
sl@0
   185
    friend class ::Builder;
sl@0
   186
sl@0
   187
    const ValueMap* getValueMap(EnumValue prop) const;
sl@0
   188
sl@0
   189
    const char* chooseNameInGroup(Offset offset,
sl@0
   190
                                  UPropertyNameChoice choice) const;
sl@0
   191
sl@0
   192
 public:
sl@0
   193
sl@0
   194
    inline const int8_t* getPointer(Offset o) const {
sl@0
   195
        return ((const int8_t*) this) + o;
sl@0
   196
    }
sl@0
   197
sl@0
   198
    inline const int8_t* getPointerNull(Offset o) const {
sl@0
   199
        return o ? getPointer(o) : NULL;
sl@0
   200
    }
sl@0
   201
sl@0
   202
    inline const char* getPropertyName(EnumValue prop,
sl@0
   203
                                       UPropertyNameChoice choice) const;
sl@0
   204
    
sl@0
   205
    inline EnumValue getPropertyEnum(const char* alias) const;
sl@0
   206
sl@0
   207
    inline const char* getPropertyValueName(EnumValue prop, EnumValue value,
sl@0
   208
                                            UPropertyNameChoice choice) const;
sl@0
   209
    
sl@0
   210
    inline EnumValue getPropertyValueEnum(EnumValue prop,
sl@0
   211
                                          const char* alias) const;
sl@0
   212
sl@0
   213
    static int32_t
sl@0
   214
    swap(const UDataSwapper *ds,
sl@0
   215
         const uint8_t *inBytes, int32_t length, uint8_t *outBytes,
sl@0
   216
         UErrorCode *pErrorCode);
sl@0
   217
};
sl@0
   218
sl@0
   219
/* ---------------------------------------------------------------------- */
sl@0
   220
/*  EnumToOffset */
sl@0
   221
sl@0
   222
/**
sl@0
   223
 * A generic map from enum values to Offsets.  The enum values must be
sl@0
   224
 * contiguous, from enumStart to enumLimit.  The Offset values may
sl@0
   225
 * point to anything.
sl@0
   226
 */
sl@0
   227
class EnumToOffset {
sl@0
   228
sl@0
   229
    /*  -- begin pnames data -- */
sl@0
   230
    EnumValue enumStart;
sl@0
   231
    EnumValue enumLimit;
sl@0
   232
    Offset _offsetArray; /*  [array of enumLimit-enumStart] */
sl@0
   233
    /*  -- end pnames data -- */
sl@0
   234
sl@0
   235
    friend class ::Builder;
sl@0
   236
sl@0
   237
    Offset* getOffsetArray() {
sl@0
   238
        return &_offsetArray;
sl@0
   239
    }
sl@0
   240
sl@0
   241
    const Offset* getOffsetArray() const {
sl@0
   242
        return &_offsetArray;
sl@0
   243
    }
sl@0
   244
sl@0
   245
    static int32_t getSize(int32_t n) {
sl@0
   246
        return sizeof(EnumToOffset) + sizeof(Offset) * (n - 1);
sl@0
   247
    }
sl@0
   248
sl@0
   249
    int32_t getSize() {
sl@0
   250
        return getSize(enumLimit - enumStart);
sl@0
   251
    }
sl@0
   252
sl@0
   253
 public:
sl@0
   254
sl@0
   255
    Offset getOffset(EnumValue enumProbe) const {
sl@0
   256
        if (enumProbe < enumStart ||
sl@0
   257
            enumProbe >= enumLimit) {
sl@0
   258
            return 0; /*  not found */
sl@0
   259
        }
sl@0
   260
        const Offset* p = getOffsetArray();
sl@0
   261
        return p[enumProbe - enumStart];
sl@0
   262
    }
sl@0
   263
sl@0
   264
    static int32_t
sl@0
   265
    swap(const UDataSwapper *ds,
sl@0
   266
         const uint8_t *inBytes, int32_t length, uint8_t *outBytes,
sl@0
   267
         uint8_t *temp, int32_t pos,
sl@0
   268
         UErrorCode *pErrorCode);
sl@0
   269
};
sl@0
   270
sl@0
   271
/* ---------------------------------------------------------------------- */
sl@0
   272
/*  NonContiguousEnumToOffset */
sl@0
   273
sl@0
   274
/**
sl@0
   275
 * A generic map from enum values to Offsets.  The enum values may be
sl@0
   276
 * disjoint.  If they are contiguous, an EnumToOffset should be used
sl@0
   277
 * instead.  The Offset values may point to anything.
sl@0
   278
 */
sl@0
   279
class NonContiguousEnumToOffset {
sl@0
   280
sl@0
   281
    /*  -- begin pnames data -- */
sl@0
   282
    int32_t count;
sl@0
   283
    EnumValue _enumArray; /*  [array of count] */
sl@0
   284
    /*  Offset _offsetArray; // [array of count] after enumValue[count-1] */
sl@0
   285
    /*  -- end pnames data -- */
sl@0
   286
sl@0
   287
    friend class ::Builder;
sl@0
   288
sl@0
   289
    EnumValue* getEnumArray() {
sl@0
   290
        return &_enumArray;
sl@0
   291
    }
sl@0
   292
sl@0
   293
    const EnumValue* getEnumArray() const {
sl@0
   294
        return &_enumArray;
sl@0
   295
    }
sl@0
   296
    
sl@0
   297
    Offset* getOffsetArray() {
sl@0
   298
        return (Offset*) (getEnumArray() + count);
sl@0
   299
    }
sl@0
   300
sl@0
   301
    const Offset* getOffsetArray() const {
sl@0
   302
        return (Offset*) (getEnumArray() + count);
sl@0
   303
    }
sl@0
   304
sl@0
   305
    static int32_t getSize(int32_t n) {
sl@0
   306
        return sizeof(int32_t) + (sizeof(EnumValue) + sizeof(Offset)) * n;
sl@0
   307
    }
sl@0
   308
sl@0
   309
    int32_t getSize() {
sl@0
   310
        return getSize(count);
sl@0
   311
    }
sl@0
   312
sl@0
   313
 public:
sl@0
   314
sl@0
   315
    Offset getOffset(EnumValue enumProbe) const {
sl@0
   316
        const EnumValue* e = getEnumArray();
sl@0
   317
        const Offset* p = getOffsetArray();
sl@0
   318
        /*  linear search; binary later if warranted */
sl@0
   319
        /*  (binary is not faster for short lists) */
sl@0
   320
        for (int32_t i=0; i<count; ++i) {
sl@0
   321
            if (e[i] < enumProbe) continue;
sl@0
   322
            if (e[i] > enumProbe) break;
sl@0
   323
            return p[i];
sl@0
   324
        }
sl@0
   325
        return 0; /*  not found */
sl@0
   326
    }
sl@0
   327
sl@0
   328
    static int32_t
sl@0
   329
    swap(const UDataSwapper *ds,
sl@0
   330
         const uint8_t *inBytes, int32_t length, uint8_t *outBytes,
sl@0
   331
         uint8_t *temp, int32_t pos,
sl@0
   332
         UErrorCode *pErrorCode);
sl@0
   333
};
sl@0
   334
sl@0
   335
/* ---------------------------------------------------------------------- */
sl@0
   336
/*  NameToEnum */
sl@0
   337
sl@0
   338
/**
sl@0
   339
 * A map from names to enum values.
sl@0
   340
 */
sl@0
   341
class NameToEnum {
sl@0
   342
sl@0
   343
    /*  -- begin pnames data -- */
sl@0
   344
    int32_t count;       /*  number of entries */
sl@0
   345
    EnumValue _enumArray; /*  [array of count] EnumValues */
sl@0
   346
    /*  Offset _nameArray; // [array of count] offsets to names */
sl@0
   347
    /*  -- end pnames data -- */
sl@0
   348
sl@0
   349
    friend class ::Builder;
sl@0
   350
sl@0
   351
    EnumValue* getEnumArray() {
sl@0
   352
        return &_enumArray;
sl@0
   353
    }
sl@0
   354
sl@0
   355
    const EnumValue* getEnumArray() const {
sl@0
   356
        return &_enumArray;
sl@0
   357
    }
sl@0
   358
sl@0
   359
    Offset* getNameArray() {
sl@0
   360
        return (Offset*) (getEnumArray() + count);
sl@0
   361
    }
sl@0
   362
sl@0
   363
    const Offset* getNameArray() const {
sl@0
   364
        return (Offset*) (getEnumArray() + count);
sl@0
   365
    }
sl@0
   366
sl@0
   367
    static int32_t getSize(int32_t n) {
sl@0
   368
        return sizeof(int32_t) + (sizeof(Offset) + sizeof(EnumValue)) * n;
sl@0
   369
    }
sl@0
   370
sl@0
   371
    int32_t getSize() {
sl@0
   372
        return getSize(count);
sl@0
   373
    }
sl@0
   374
sl@0
   375
 public:
sl@0
   376
  
sl@0
   377
    EnumValue getEnum(const char* alias, const PropertyAliases& data) const {
sl@0
   378
sl@0
   379
        const Offset* n = getNameArray();
sl@0
   380
        const EnumValue* e = getEnumArray();
sl@0
   381
sl@0
   382
        /*  linear search; binary later if warranted */
sl@0
   383
        /*  (binary is not faster for short lists) */
sl@0
   384
        for (int32_t i=0; i<count; ++i) {
sl@0
   385
            const char* name = (const char*) data.getPointer(n[i]);
sl@0
   386
            int32_t c = uprv_comparePropertyNames(alias, name);
sl@0
   387
            if (c > 0) continue;
sl@0
   388
            if (c < 0) break;
sl@0
   389
            return e[i];
sl@0
   390
        }
sl@0
   391
        
sl@0
   392
        return UCHAR_INVALID_CODE;
sl@0
   393
    }
sl@0
   394
sl@0
   395
    static int32_t
sl@0
   396
    swap(const UDataSwapper *ds,
sl@0
   397
         const uint8_t *inBytes, int32_t length, uint8_t *outBytes,
sl@0
   398
         uint8_t *temp, int32_t pos,
sl@0
   399
         UErrorCode *pErrorCode);
sl@0
   400
};
sl@0
   401
sl@0
   402
/*----------------------------------------------------------------------
sl@0
   403
 * 
sl@0
   404
 * In-memory layout.  THIS IS NOT A STANDALONE DOCUMENT.  It goes
sl@0
   405
 * together with above C++ declarations and gives an overview.
sl@0
   406
 *
sl@0
   407
 * See above for definitions of Offset and EnumValue.  Also, refer to
sl@0
   408
 * above class declarations for the "bottom line" on data layout.
sl@0
   409
 *
sl@0
   410
 * Sizes:
sl@0
   411
 * '*_offset' is an Offset (see above)
sl@0
   412
 * 'count' members are typically int32_t (see above declarations)
sl@0
   413
 * 'enumArray' is an array of EnumValue (see above)
sl@0
   414
 * 'offsetArray' is an array of Offset (see above)
sl@0
   415
 * 'nameArray' is an array of Offset (see above)
sl@0
   416
 * 'enum*' is an EnumValue (see above)
sl@0
   417
 * '*Array [x n]' means that *Array has n elements
sl@0
   418
 *
sl@0
   419
 * References:
sl@0
   420
 * Instead of pointers, this flat data structure contains offsets.
sl@0
   421
 * All offsets are relative to the start of 'header'.  A notation
sl@0
   422
 * is used to indicate what structure each offset points to:
sl@0
   423
 * 'foo (>x)' the offset(s) in foo point to structure x
sl@0
   424
 * 
sl@0
   425
 * Structures:
sl@0
   426
 * Each structure is assigned a number, except for the header,
sl@0
   427
 * which is called 'header'.  The numbers are not contiguous
sl@0
   428
 * for historical reasons.  Some structures have sub-parts
sl@0
   429
 * that are denoted with a letter, e.g., "5a".
sl@0
   430
 * 
sl@0
   431
 * BEGIN LAYOUT
sl@0
   432
 * ============
sl@0
   433
 * header:
sl@0
   434
 *  enumToName_offset (>0)
sl@0
   435
 *  nameToEnum_offset (>2)
sl@0
   436
 *  enumToValue_offset (>3)
sl@0
   437
 *  (alignment padding build in to header)
sl@0
   438
 *
sl@0
   439
 * The header also contains the following, used by "external readers"
sl@0
   440
 * like ICU4J and icuswap.
sl@0
   441
 *
sl@0
   442
 *  // The following are needed by external readers of this data.
sl@0
   443
 *  // We don't use them ourselves.
sl@0
   444
 *  int16_t total_size; // size in bytes excluding the udata header
sl@0
   445
 *  Offset valueMap_offset; // offset to start of array
sl@0
   446
 *  int16_t valueMap_count; // number of entries
sl@0
   447
 *  Offset nameGroupPool_offset; // offset to start of array
sl@0
   448
 *  int16_t nameGroupPool_count; // number of entries (not groups)
sl@0
   449
 *  Offset stringPool_offset; // offset to start of pool
sl@0
   450
 *  int16_t stringPool_count; // number of strings (not size in bytes)
sl@0
   451
 *
sl@0
   452
 * 0: # NonContiguousEnumToOffset obj for props => name groups
sl@0
   453
 *  count
sl@0
   454
 *  enumArray [x count]
sl@0
   455
 *  offsetArray [x count] (>98)
sl@0
   456
 * 
sl@0
   457
 * => pad to next 4-byte boundary
sl@0
   458
 * 
sl@0
   459
 * (1: omitted -- no longer used)
sl@0
   460
 * 
sl@0
   461
 * 2: # NameToEnum obj for binary & enumerated props
sl@0
   462
 *  count
sl@0
   463
 *  enumArray [x count]
sl@0
   464
 *  nameArray [x count] (>99)
sl@0
   465
 * 
sl@0
   466
 * => pad to next 4-byte boundary
sl@0
   467
 * 
sl@0
   468
 * 3: # NonContiguousEnumToOffset obj for enumerated props => ValueMaps
sl@0
   469
 *  count
sl@0
   470
 *  enumArray [x count]
sl@0
   471
 *  offsetArray [x count] (>4)
sl@0
   472
 * 
sl@0
   473
 * => pad to next 4-byte boundary
sl@0
   474
 * 
sl@0
   475
 * 4: # ValueMap array [x one for each enumerated prop i]
sl@0
   476
 *  enumToName_offset (>5a +2*i)   one of these two is NULL, one is not
sl@0
   477
 *  ncEnumToName_offset (>5b +2*i)
sl@0
   478
 *  nameToEnums_offset (>6 +2*i)
sl@0
   479
 * 
sl@0
   480
 * => pad to next 4-byte boundary
sl@0
   481
 * 
sl@0
   482
 * for each enumerated prop (either 5a or 5b):
sl@0
   483
 * 
sl@0
   484
 *   5a: # EnumToOffset for enumerated prop's values => name groups
sl@0
   485
 *    enumStart
sl@0
   486
 *    enumLimit
sl@0
   487
 *    offsetArray [x enumLimit - enumStart] (>98) 
sl@0
   488
 * 
sl@0
   489
 *   => pad to next 4-byte boundary
sl@0
   490
 * 
sl@0
   491
 *   5b: # NonContiguousEnumToOffset for enumerated prop's values => name groups
sl@0
   492
 *    count
sl@0
   493
 *    enumArray [x count]
sl@0
   494
 *    offsetArray [x count] (>98)
sl@0
   495
 * 
sl@0
   496
 *   => pad to next 4-byte boundary
sl@0
   497
 * 
sl@0
   498
 *   6: # NameToEnum for enumerated prop's values
sl@0
   499
 *    count
sl@0
   500
 *    enumArray [x count]
sl@0
   501
 *    nameArray [x count] (>99)
sl@0
   502
 * 
sl@0
   503
 *   => pad to next 4-byte boundary
sl@0
   504
 * 
sl@0
   505
 * 98: # name group pool {NGP}
sl@0
   506
 *  [array of Offset values] (>99)
sl@0
   507
 * 
sl@0
   508
 * 99: # string pool {SP}
sl@0
   509
 *  [pool of nul-terminated char* strings]
sl@0
   510
 */
sl@0
   511
U_NAMESPACE_END
sl@0
   512
sl@0
   513
#endif /* C++ */
sl@0
   514
sl@0
   515
#endif