First public contribution.
6 <tr><td>Owner:</td><td>Application Frameworks & Protocols</td></tr>
7 <tr><td>Author:</td><td>Leon Clarke</td></tr>
8 <tr><td>Last Revised:</td><td>20 March 2002.</td></tr>
9 <tr><td>Revision:</td><td>3.0</td></tr>
10 <tr><td>Status:</td><td>Released</td></tr>
11 <tr><td>Reviewers:</td><td></td></tr>
12 <tr><td>Approval:</td><td>(PM) Urmi Shah, (ESM) Akin Oyesola, (Architect) Andrew Baldwin</td></tr>
17 @section Revision History
19 <tr><td>Date</td><td>Version</td><td>Status</td><td>Description</td></tr>
20 <tr><td>21-05-2001</td><td>1.0</td><td>Issued</td><td>Issued</td></tr>
21 <tr><td>05-07-2001</td><td>1.1</td><td>Added more detail, in particular about static tables.</td><td>Issued</td></tr>
22 <tr><td>05-07-2001</td><td>1.2</td><td>Minor editorial changes following T3 review comments.</td><td>Issued</td></tr>
23 <tr><td>23-07-2001</td><td>1.3</td><td>Added reference to example code.</td><td>Issued</td></tr>
24 <tr><td>09-11-2001</td><td>2.0</td><td>Added mutiple table support and case-sensitive strings</td><td>Issued</td></tr>
25 <tr><td>20-03-2002</td><td>3.0</td><td>Incorporated changes following defect fixing</td><td>Released</td></tr>
31 The string pool is a way of storing strings that makes comparison
32 almost instantaneous at the expense of string creation. It is
33 particularly efficient at handling string constants that are known
34 at compile time. It currently only supports 8 bit strings. The
35 basic algorithm is to ensure that the pool only contains one string
36 of any particular value, using reference counts to keep track of
37 it. Subsequent strings with the same value will actualy refer to
40 To use the string pool, you need an RStringPool object. Strings
41 from different string pools can't be compared, so there should only
42 be 1 string pool open per thread (unless one is in a component that
43 doesn't export its use of the string pool). Of course, you can have
44 multiple RStringPool objects, as long as they are all handles to
47 Within this object, there are 2 distinct pools of strings, one
48 comprising strings that are 'case-sensitive' (represented using the
49 RString class) and another representing strings that are 'case-insensitive' (RStringF). Case-sensitive strings behave in a
50 straightforward way. Case-insensitive strings should be used in a
51 situation where case doesn't matter at all; if you create a new
52 RStringF that differs from an existing RStringF only in terms of
53 case, when you read back the value of the 'new' string, it will
54 have the same value as the 'existing' one. This can be very useful
55 in situations where strings are considered case-insensitive, but
56 there is a 'traditional case' that is normaly used. As long as the
57 first value to be added is in the 'traditional case', all
58 subsequent additions will be corrected to match this first entry.
60 Case-insensitivity assumes a character set of us-ascii (i.e.it only
61 considers A-Z to be equivalent to a-z)
63 If a string has a more complex or different case-sensitivity
64 requirement that this model doesn't match, then it may be necessary
65 to compare strings outside the pool, which may make the string pool
68 Corresponding to RString and RStringF are the classes RStringToken
69 and RStringTokenF. These are smaller (4 bytes long rather than 8)
70 but need to be turned into String or StringF classes before you can
71 do anything useful with them. In particular, you can't directly
72 find the contents of a string token. They should be used when space
73 is absoluteley at a premium, for instance storing a lot of strings
74 in an array, or similar applications.
76 @section Static Tables
78 A very important aspect of the string pool is the concept of static string
79 table. This is best thought of as an array of common
80 strings. Integers can be transformed into the strings corresponding
81 to that index position in the array via the String and StringF
82 functions. In addition, a string can be cast back to an integer,
83 allowing a switch statement on strings (it returns -1 if the string
84 isn't one from any static table of the pool). Another advantage to using the
85 static table is that the function to create the string can't leave,
86 and the string doesn't need to be closed (although closing it is
89 Multiple case-insensitive and case-sensitive string tables are supported.
91 A static table is written as a .st file, and is processed by
92 stringtable.pl early in the build process to generate the actual
93 cpp and header files at compile time. The format of the .st file is
94 basicaly as follows. The first noncomment line consists of
95 fstringtable <TableName> for a case-insensitive table and stringtable <TableName>
96 for a case-sensitive table. Each subsequent non-comment line consists
97 of the name of an enum followed by the value of the string. Comment
98 lines start with # and can be added anywhere. You can also have
99 lines starting in !, which will be output into the header file if
100 you want additional comments in the header. e.g.
103 # Example String Table
104 fstringtable ExampleStringTable
105 !// Some types of fruit
106 # This comment won't appear in the .h file, but the one above is.
115 The string table name must be a valid C++ class name, and the
116 generated code includes a class that contains within it an enum
117 corresponding to the elements in the array, so entries in the above
118 example could be referred to as MyStringTable::ECat and so on.
120 The stringpool.pl script takes a .st file and creates .cpp and .h
121 files of the same name in the same directory. The easiest way to
122 use this is to export the .st file to /epoc32/generated/, create an
123 extension makefile that runs the script during the makefile phase
124 and then copies the generated .h file to epoc32, and then compile
125 the .cpp file as normal from an mmp files. Look at the example code
126 in //EPOC/main/generic/bafl/docs/stringtableexample/... for a
127 simple example of how to do this.
129 To be notified when the String Pool is closing you can derive from the mix-in class MStringPoolCloseCallBack and implement the StringPoolClosing() function. The OpenL(const TStringTable& aTable, MStringPoolCloseCallBack& aCallBack) overridden function must be used to register the callback with the String Pool. Where aCallback is the pointer to the callback. The StringPoolClosing() function will then get called when the String Pool is closing.