Re-merge NVGRenderStage component, fixes for Bug 1410 and Bug 26, and "theme generation" changes into latest drop from Nokia.
/*
* Copyright (c) 1999 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
/*
Reads and parses the Unicode collation value table and writes out a C++ source file
containing the data in a form that can be used by the EPOC collation system.
The program reads three files:
1. Base keys (maps single Unicode values to single collation key values): must be in the same format as
basekeys.txt, supplied with the Standard Unicode Collation system
2. Composite keys (maps single Unicode values to strings of collation keys): must be in the same format as
compkeys.txt, supplied with the Standard Unicode Collation system
3. Strings (maps strings of Unicode values to single collation keys OR strings of collation keys): must be in the
same format as compkeys.txt, except that there can be any number of Unicode characters at the start of the line,
space-separated and each exactly 4 hex digits.
*/
#include <assert.h>
#include <ctype.h>
#include <fstream.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/*
Constants constraining the range of level-1 and level-2 keys so that they can be packed.
Non-zero values are reduced by one less than the minimum value.
*/
const unsigned int KLevel1Bits = 8;
const unsigned int KLevel1Min = 0x20;
const unsigned int KLevel1Max = KLevel1Min + (1 << KLevel1Bits) - 2;
const unsigned int KLevel2Bits = 6;
const unsigned int KLevel2Min = 1;
const unsigned int KLevel2Max = KLevel2Min + (1 << KLevel2Bits) - 2;
/*
Table of characters in the WGL4 set, plus characters in canonical decompositions of
those characters, plus commonly used control characters and space characters,
given as ranges of Unicode characters. In each pair, the first code is the first in the range,
and the second is the first code NOT in the range.
The extra characters are added mainly to ensure that control characters and spaces are
normally ignored. The extra characters are:
0x0000-0x001F: ASCII control characters
0x2000-0x2012: spaces, hyphen variants, figure dash
0x2028-0x202E: line and paragraph separator, bidirectional control characters
0xFEFF : byte-order mark
0xFFFC-0xFFFD: object replacement character, replacement character
*/
const unsigned short Wgl4Range[] =
{
0x00, 0x7f, // All ASCII
0xa0, 0x180, // Non-breaking space, Latin-1, Latin Extended-A
0x192,0x193, // Latin f with hook
0x1fa,0x200, // A-ring, a-ring, AE, ae, O slash, o slash all with acute accent
0x2c6,0x2c8, // non-combining circumflex and caron
0x2c9,0x2ca, // non-combining macron
0x2d8,0x2dc, // non-combining breve, dot above, ring above, ogonek
0x2dd,0x2de, // non-combining double acute
0x300,0x305, // combining grave, acute, circumflex, tilde, macron
0x306,0x309, // combining breve, dot above, double dot above
0x30a,0x30e, // combining ring above, double acute, caron, vertical line above
0x327,0x329, // combining cedilla, ogonek
0x384,0x38b, // Greek
0x38c,0x38d, // Greek
0x38e,0x3a2, // Greek
0x3a3,0x3cf, // Greek
0x401,0x40d, // Cyrillic
0x40e,0x450, // Cyrillic
0x451,0x45d, // Cyrillic
0x45e,0x460, // Cyrillic
0x490,0x492, // Cyrillic
0x1e80,0x1e86, // Both W and w with each of grave, acute and diaeresis
0x1ef2,0x1ef4, // Y with grave, y with grave
0x2000,0x2016, // various space and horizontal lines
0x2017,0x201f, //double vertical line, double low line, various quotation marks
0x2020,0x2023, // dagger, double dagger, bullet
0x2026,0x2027, //ellipsis
0x2028,0x202F, // line & paragraph separators and directional formatting
0x2030,0x2031, // per mille
0x2032,0x2034, // prime
0x2039,0x203b, // single angle quotation marks
0x203c,0x203d, // double exclamation mark
0x203e,0x203f, // non-combining overscore
0x2044,0x2045, // fraction slash
0x207f,0x2080, // superscript n
0x20a3,0x20a5, // French Franc, Italian/Turkish Lira
0x20a7,0x20a8, // Spanish Peseta
0x20ac,0x20ad, // Euro symbol
0x2105,0x2106, // care of
0x2113,0x2114, // script l
0x2116,0x2117, // numero
0x2122,0x2123, // trade mark
0x2126,0x2127, // ohm
0x212e,0x212f, // estimated (net weight)
0x215b,0x215f, // 1/8, 3/8, 5/8, 7/8
0x2190,0x2196, // horizontal and vertical arrows
0x21a8,0x21a9, // up down arrow with base
0x2202,0x2203, // partial differential
0x2206,0x2207, // increment (delta)
0x220f,0x2210, // n-ary product (pi)
0x2211,0x2213, // n-ary sum (sigma), minus
0x2215,0x2216, // division (slash)
0x2219,0x221b, // bullet operator, square root
0x221e,0x2220, // infinity, right angle
0x2229,0x222a, // intersection
0x222b,0x222c, // union
0x2248,0x2249, // almost equal to
0x2260,0x2262, // not equal to, identical to
0x2264,0x2266, // less-than-or-equal-to, greater-than-or-equal-to
0x2302,0x2303, // house
0x2310,0x2311, // rversed not sign
0x2320,0x2322, // top and bottom of integral
0x2500,0x2501, // box drawing
0x2502,0x2503, // box drawing
0x250c,0x250d, // box drawing
0x2510,0x2511, // box drawing
0x2514,0x2515, // box drawing
0x2518,0x2519, // box drawing
0x251c,0x251d, // box drawing
0x2524,0x2525, // box drawing
0x252c,0x252d, // box drawing
0x2534,0x2535, // box drawing
0x253c,0x253d, // box drawing
0x2550,0x256d, // box drawing
0x2580,0x2581, // block element
0x2584,0x2585, // block element
0x2588,0x2589, // block element
0x258c,0x258d, // block element
0x2590,0x2594, // block element
0x25a0,0x25a2, // geometric shapes
0x25aa,0x25ad, // geometric shapes
0x25b2,0x25b3, // geometric shapes
0x25ba,0x25bb, // geometric shapes
0x25bc,0x25bd, // geometric shapes
0x25c4,0x25c5, // geometric shapes
0x25ca,0x25cc, // geometric shapes
0x25cf,0x25d0, // geometric shapes
0x25d8,0x25da, // geometric shapes
0x25e6,0x25e7, // geometric shapes
0x263a,0x263d, // smilies, sun
0x2640,0x2641, // female
0x2642,0x2643, // male
0x2660,0x2661, // spade
0x2663,0x2664, // club
0x2665,0x2667, // heart
0x266a,0x266c, // quaver, beamed quavers
0xfb01,0xfb03, // fi, fl ligatures
0xfeff,0xff00, // zero-width non-breaking space
0xfffc, 0xfffe // object replacement character and replacement character
};
const int Wgl4Ranges = sizeof(Wgl4Range) / sizeof(Wgl4Range[0]) / 2;
int CompareWgl4Ranges(const void* aRange1,const void* aRange2)
{
unsigned short* p = (unsigned short*)aRange1;
unsigned short* q = (unsigned short*)aRange2;
if (q[0] == q[1])
{
unsigned short* temp = p;
p = q;
q = temp;
}
if (*p < *q)
return -1;
else if (*p >= q[1])
return 1;
else
return 0;
}
// Determine if a character is in the WGL4 character repertoire.
static bool InWgl4(unsigned short aChar)
{
unsigned short key[2];
key[0] = key[1] = aChar;
return bsearch(key,Wgl4Range,Wgl4Ranges,sizeof(Wgl4Range[0]) * 2,CompareWgl4Ranges) != NULL;
}
// A collation key.
class CollationKey
{
public:
bool operator==(const CollationKey& k) const
{ return iLevel[0] == k.iLevel[0] && iLevel[1] == k.iLevel[1] && iLevel[2] == k.iLevel[2] &&
iIgnorable == k.iIgnorable && iStop == k.iStop; }
enum
{
ELevels = 3
};
int iLevel[ELevels];// the keys at the various levels
bool iIgnorable; // TRUE if this key can normally be ignored
bool iStop; // TRUE if this is the last key in a string of keys
};
// The collation index for a single Unicode value.
class CollationIndex
{
public:
static int Compare(const void* aIndex1,const void* aIndex2);
int iCode; // Unicode value
int iIndex; // index into the key table
};
class Reader
{
public:
Reader(bool aWgl4,bool aStandard,const char* aLocaleName);
~Reader();
void ReadBaseKeys(const char* aFileName);
void ReadCompKeys(const char* aFileName);
void ReadStrings(const char* aFileName);
void WriteOutput(const char* aFileName);
int CompareStringIndices(int aIndex1,int aIndex2) const;
private:
int Hex(const char *aString,bool aTolerate = false);
void GetCollationKey(const char* aString,CollationKey* aKey = NULL);
void GetMultipleCollationKeys(const char* aString);
unsigned int PackKey(const CollationKey& aValue);
unsigned int PackIndex(const CollationIndex& aValue);
bool ParseLine(const char* aLine,int& aCode,int& aKeyStart);
enum
{
EMaxCollationKeys = 65536,
EMaxCollationIndices = 65536,
EMaxStringElements = 65536,
EMaxStringIndices = 65536
};
CollationKey iCollationKey[EMaxCollationKeys];
int iKeys;
CollationIndex iCollationIndex[EMaxCollationIndices];
int iIndices;
unsigned short iStringElement[EMaxStringElements];
int iStringElements;
unsigned int iStringIndex[EMaxStringIndices];
int iStringIndices;
const char* iInputFileName;
int iLineNumber;
bool iWgl4; // true if writing keys for wgl4 characters only
bool iStandard; // true if reading standard files, not tailoring files
const char* iLocaleName;
};
void UsageError()
{
cout << "Usage: coltab <locale>\n";
cout << "For the locales 'standard' and 'wgl4' coltab reads basekeys.txt & compkeys.txt\n";
cout << "For any other locale name <name> coltab reads <name>_basekeys.txt,\n";
cout << "<name>_compkeys.txt and <name>_strings.txt.\n";
cout << "The output file is always ls_<name>.cpp.";
exit(1);
}
int main(int argc,char** argv)
{
if (argc != 2)
UsageError();
bool wgl4 = false;
const char* prefix = "";
const char* infix = "";
const char* locale = "";
bool standard = false;
if (!_stricmp(argv[1],"standard"))
{
locale = "Standard";
standard = true;
}
else if (!_stricmp(argv[1],"wgl4"))
{
locale = "Wgl4";
wgl4 = true;
standard = true;
}
else
{
locale = prefix = argv[1];
infix = "_";
}
Reader* reader = new Reader(wgl4,standard,locale);
if (!reader)
{
cout << "out of memory\n";
exit(1);
}
char* filename = new char[strlen(prefix) + 64];
sprintf(filename,"%s%scompkeys.txt",prefix,infix);
reader->ReadCompKeys(filename);
if (!standard)
{
sprintf(filename,"%s%sstrings.txt",prefix,infix);
reader->ReadStrings(filename);
}
sprintf(filename,"%s%sbasekeys.txt",prefix,infix);
reader->ReadBaseKeys(filename);
sprintf(filename,"ls_%s.cpp",argv[1]);
reader->WriteOutput(filename);
delete reader;
delete [] filename;
return 0;
}
Reader::Reader(bool aWgl4,bool aStandard,const char* aLocaleName):
iKeys(0),
iIndices(0),
iStringElements(0),
iStringIndices(0),
iInputFileName(NULL),
iLineNumber(0),
iWgl4(aWgl4),
iStandard(aStandard),
iLocaleName(aLocaleName)
{
}
Reader::~Reader()
{
}
// Get a hex number of exactly four digits from aString. Return -1 if none is found and aTolerate is true.
int Reader::Hex(const char *aString,bool aTolerate)
{
char *end;
unsigned long x = strtoul(aString,&end,16);
if (end != aString + 4)
{
if (!aTolerate)
{
cout << "bad hex number on line " << iLineNumber << " of file " << iInputFileName << '\n';
exit(1);
}
return -1;
}
return x;
}
// Get a collation value from a string of the form [.xxxx.xxxx.xxxx.xxxx]
void Reader::GetCollationKey(const char* aString,CollationKey* aKey)
{
if (aString[0] != '[' || aString[21] != ']')
{
cout << "syntax error on line " << iLineNumber << " of file " << iInputFileName << '\n';
exit(1);
}
if (aKey == NULL)
{
if (iKeys >= EMaxCollationKeys)
{
cout << "too many keys";
exit(1);
}
aKey = &iCollationKey[iKeys++];
}
aKey->iIgnorable = aString[1] == '*'; // asterisk means that this character is normally ignored
for (int i = 0; i < CollationKey::ELevels; i++)
aKey->iLevel[i] = Hex(aString + 2 + i * 5);
if (aKey->iLevel[1] > 0 && (aKey->iLevel[1] < KLevel1Min || aKey->iLevel[1] > KLevel1Max))
{
cout << "illegal level-1 key value on line " << iLineNumber << "; outside the range " << KLevel1Min << ".." << KLevel1Max;
exit(1);
}
if (aKey->iLevel[2] > 0 && (aKey->iLevel[2] < KLevel2Min || aKey->iLevel[2] > KLevel2Max))
{
cout << "illegal level-2 key value on line " << iLineNumber << "; outside the range " << KLevel2Min << ".." << KLevel2Max;
exit(1);
}
aKey->iStop = true;
}
void Reader::GetMultipleCollationKeys(const char* aString)
{
while (aString[0] == '[')
{
GetCollationKey(aString);
iCollationKey[iKeys - 1].iStop = false;
if (strlen(aString) <= 23)
break;
aString += 23;
}
iCollationKey[iKeys - 1].iStop = true;
}
/*
Partially parse a line, returning its key code and the start of its first block of key data.
Return false if it is not a data line, or not relevant.
*/
bool Reader::ParseLine(const char* aLine,int& aCode,int& aKeyStart)
{
int line_length = strlen(aLine);
aCode = Hex(aLine,true);
/*
A data line must start with a hex number and be at least 27 characters long.
Canonically decomposable Unicode characters are skipped.
Skip non-WGL4 characters if doing WGL4 only.
*/
if (aCode != -1)
{
if (line_length < 27 ||
!strcmp(aLine + line_length - 8,"CANONSEQ") ||
(iWgl4 && !InWgl4((unsigned short)aCode)))
aCode = -1;
}
if (aCode != -1)
{
aKeyStart = 4;
while (aKeyStart < line_length && aLine[aKeyStart] != '[')
aKeyStart++;
}
return aCode != -1;
}
void Reader::ReadBaseKeys(const char* aFileName)
{
iLineNumber = 0;
iInputFileName = aFileName;
ifstream input_file;
input_file.open(iInputFileName,ios::in | ios::nocreate);
if (input_file.fail())
{
cout << "cannot open input file '" << iInputFileName << "'\n";
exit(1);
}
cout << "reading base keys from '" << iInputFileName << "'\n";
char line[1024];
for (;;)
{
input_file.getline(line,sizeof(line));
if (input_file.eof())
break;
iLineNumber++;
if (iLineNumber % 100 == 0)
{
cout << "line " << iLineNumber << '\n';
cout.flush();
}
int code = 0;
int key_start = 0;
if (ParseLine(line,code,key_start))
{
if (iIndices >= EMaxCollationIndices)
{
cout << "too many Unicode values";
exit(1);
}
CollationIndex& index = iCollationIndex[iIndices++];
index.iCode = code;
index.iIndex = -1;
/*
First try to find the key in the array of keys found so far.
Search backwards to use the fact that runs of the same key occur together.
*/
CollationKey key;
GetCollationKey(line + key_start,&key);
for (int i = iKeys - 1; i >= 0 && index.iIndex == -1; i--)
if (iCollationKey[i] == key)
index.iIndex = i;
// If that fails, add a new key.
if (index.iIndex == -1)
{
index.iIndex = iKeys++;
if (iKeys > EMaxCollationKeys)
{
cout << "too many keys";
exit(1);
}
iCollationKey[index.iIndex] = key;
}
}
}
input_file.close();
}
void Reader::ReadCompKeys(const char* aFileName)
{
iLineNumber = 0;
iInputFileName = aFileName;
ifstream input_file;
input_file.open(iInputFileName,ios::in | ios::nocreate);
if (input_file.fail())
{
cout << "there are no composite keys; '" << iInputFileName << "' not found\n";
return;
}
cout << "reading composite keys from '" << iInputFileName << "'\n";
char line[1024];
for (;;)
{
input_file.getline(line,sizeof(line));
if (input_file.eof())
break;
iLineNumber++;
if (iLineNumber % 100 == 0)
{
cout << "line " << iLineNumber << '\n';
cout.flush();
}
int code = 0;
int key_start = 0;
if (ParseLine(line,code,key_start))
{
if (iIndices >= EMaxCollationIndices)
{
cout << "too many Unicode values";
exit(1);
}
CollationIndex& index = iCollationIndex[iIndices++];
index.iCode = code;
index.iIndex = iKeys;
GetMultipleCollationKeys(line + key_start);
}
}
input_file.close();
}
void Reader::ReadStrings(const char* aFileName)
{
iLineNumber = 0;
iInputFileName = aFileName;
ifstream input_file;
input_file.open(iInputFileName,ios::in | ios::nocreate);
if (input_file.fail())
{
cout << "there are no strings; '" << iInputFileName << "' not found\n";
return;
}
cout << "reading strings from '" << iInputFileName << "'\n";
char line[1024];
for (;;)
{
input_file.getline(line,sizeof(line));
if (input_file.eof())
break;
iLineNumber++;
if (iLineNumber % 100 == 0)
{
cout << "line " << iLineNumber << '\n';
cout.flush();
}
int code = 0;
int key_start = 0;
if (ParseLine(line,code,key_start))
{
// Store the index to the Unicode string and the key sequence.
if (iStringIndices > EMaxStringIndices)
{
cout << "too many string indices";
exit(1);
}
iStringIndex[iStringIndices++] = (iStringElements << 16) | iKeys;
// Reserve space for the length.
if (iStringElements >= EMaxStringElements)
{
cout << "too many string elements";
exit(1);
}
iStringElements++;
// Read the Unicode string.
int index = 0;
int length = 0;
while (index < key_start)
{
if (iStringElements >= EMaxStringElements)
{
cout << "too many string elements";
exit(1);
}
iStringElement[iStringElements++] = (unsigned short)Hex(line + index);
index += 5;
length++;
}
iStringElement[iStringElements - length - 1] = (unsigned short)length;
// Read the key sequence.
GetMultipleCollationKeys(line + key_start);
}
}
input_file.close();
}
// Pack the 3 collation key levels into a single 32-bit integer.
unsigned int Reader::PackKey(const CollationKey& aValue)
{
unsigned int level0 = aValue.iLevel[0];
unsigned int level1 = aValue.iLevel[1];
if (level1 > 0)
level1 -= (KLevel1Min - 1);
unsigned int level2 = aValue.iLevel[2];
if (level2 > 0)
level2 -= (KLevel2Min - 1);
unsigned int key = level0 << 16 | level1 << 8 | level2 << 2;
if (aValue.iIgnorable)
key |= 2;
if (aValue.iStop)
key |= 1;
return key;
}
// Pack a collation index value into a single 32-bit integer.
unsigned int Reader::PackIndex(const CollationIndex& aValue)
{
unsigned int code = aValue.iCode;
unsigned int index = aValue.iIndex;
return code << 16 | index;
}
const Reader* TheReader;
static int CompareStringIndices(const void* aIndex1,const void* aIndex2)
{
return TheReader->CompareStringIndices(*(unsigned int*)aIndex1 >> 16,*(unsigned int*)aIndex2 >> 16);
}
int CompareUnicodeStrings(const unsigned short *aString1,int aLength1,const unsigned short *aString2,int aLength2)
{
for (int i = 0; i < aLength1 || i < aLength2; i++, aString1++, aString2++)
{
int x = i < aLength1 ? *aString1 : -1;
int y = i < aLength2 ? *aString2 : -1;
if (x != y)
return x - y;
}
return 0;
}
int Reader::CompareStringIndices(int aIndex1,int aIndex2) const
{
return CompareUnicodeStrings(iStringElement + aIndex1 + 1,iStringElement[aIndex1],
iStringElement + aIndex2 + 1,iStringElement[aIndex2]);
}
void Reader::WriteOutput(const char* aFileName)
{
ofstream output_file;
output_file.open(aFileName);
if (output_file.fail())
{
cout << "cannot open output file '" << aFileName << "'\n";
exit(1);
}
cout << "writing output to '" << aFileName << "'\n";
char *locale = NULL;
if (iStandard)
locale = _strdup("Standard");
else
locale = _strdup(iLocaleName);
if (!iStandard)
{
_strupr(locale);
output_file << "/*\nLS_" << locale << ".CPP\n\nCopyright (C) 2000 Symbian Ltd. All rights reserved.\n*/\n";
_strlwr(locale);
locale[0] = (char)toupper(locale[0]);
output_file << "\n/*\nThe LCharSet object used by the " << locale << " locale.\n";
output_file << "Generated by COLTAB.\n*/\n";
output_file << "\n#include \"ls_std.h\"\n#include <collate.h>\n";
output_file << "\nconst TUint KUid" << locale << "CollationMethod = /* FILL THIS IN */;\n";
}
/*
Write the unique collation keys.
Each one has the format, going from highest to lowest bit:
16 bits: level-0 key
8 bits: level-1 key
6 bits: level-2 key
1 bit: set if this key is optionally ignorable
1 bit: set if this is the last key in the string of keys for a single Unicode value
*/
if (iKeys != 0)
{
output_file << "\nstatic const TUint32 The" << locale << "Key[] = \n\t{";
CollationKey* ck = iCollationKey;
output_file << hex;
for (int i = 0; i < iKeys; i++, ck++)
{
unsigned int key = PackKey(*ck);
if (i % 8 == 0)
output_file << "\n\t";
output_file << "0x" << key << ",";
}
output_file << dec;
output_file << "\n\t};\n\n";
}
if (iIndices != 0)
{
// Sort then write the collation index values - these relate Unicode values to collation keys.
qsort(iCollationIndex,iIndices,sizeof(CollationIndex),CollationIndex::Compare);
output_file << "static const TUint32 The" << locale << "Index[] = \n\t{";
CollationIndex* ci = iCollationIndex;
output_file << hex;
for (int i = 0; i < iIndices; i++, ci++)
{
unsigned int key = PackIndex(*ci);
if (i % 8 == 0)
output_file << "\n\t";
output_file << "0x" << key << ",";
}
output_file << dec;
output_file << "\n\t};\n\n";
}
if (iStringElements)
{
// Write the Unicode strings; these are preceded by their lengths.
output_file << "static const TUint16 The" << locale << "StringElement[] = \n\t{";
output_file << hex;
for (int i = 0; i < iStringElements; i++)
{
if (i % 8 == 0)
output_file << "\n\t";
output_file << "0x" << iStringElement[i] << ",";
}
output_file << dec;
if (iStringElements==0)
output_file << "0";
output_file << "\n\t};\n\n";
/*
Sort then write the string index values - these relate Unicode strings to collation keys.
Each one has the string index in the upper word and the key index in the lower word.
*/
TheReader = this;
qsort(iStringIndex,iStringIndices,sizeof(iStringIndex[0]),::CompareStringIndices);
output_file << "static const TUint32 The" << locale << "StringIndex[] = \n\t{";
output_file << hex;
for (i = 0; i < iStringIndices; i++)
{
if (i % 8 == 0)
output_file << "\n\t";
output_file << "0x" << iStringIndex[i] << ",";
}
output_file << dec;
if (iStringIndices ==0)
output_file << "0";
output_file << "\n\t};\n\n";
}
// Write the collation table structure.
output_file << "static const TCollationKeyTable The" << locale << "Table = \n\t{ ";
if (iKeys)
output_file << "The" << locale << "Key";
else
output_file << "0";
if (iIndices)
output_file << ", The" << locale << "Index, " << iIndices;
else
output_file << ", 0, 0";
if (iStringElements)
output_file << ", The" << locale << "StringElement, The" << locale << "StringIndex, " << iStringIndices << " };\n";
else
output_file << ", 0, 0, 0 };\n";
if (!iStandard)
output_file << "\nstatic const TCollationMethod TheCollationMethod[] = \n"\
" {\n"\
" {\n"\
" KUid" << locale << "CollationMethod, // the method for the locale\n"\
" NULL, // use the standard table as the main table\n"\
" &The" << locale << "Table, // the locale values override the standard values\n"\
" 0 // the flags are standard\n"\
" },\n"\
" {\n"\
" KUidBasicCollationMethod, // the standard unlocalised method\n"\
" NULL, // null means use the standard table\n"\
" NULL, // there's no override table\n"\
" 0 // the flags are standard\n"\
" }\n"\
" };\n"\
"\n"\
"static const TCollationDataSet TheCollationDataSet =\n"\
" {\n"\
" TheCollationMethod,\n"\
" 2\n"\
" };"\
"\n\n"\
"// The one and only locale character set object.\n"\
"const LCharSet TheCharSet =\n"\
" {\n"\
" NULL,\n"\
" &TheCollationDataSet\n"\
" };\n";
output_file.close();
delete [] locale;
}
int CollationIndex::Compare(const void* aIndex1,const void* aIndex2)
{
return ((CollationIndex*)aIndex1)->iCode - ((CollationIndex*)aIndex2)->iCode;
}