1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef THIRD_PARTY_HUNSPELL_GOOGLE_BDICT_H_
6 #define THIRD_PARTY_HUNSPELL_GOOGLE_BDICT_H_
8 #include "base/basictypes.h"
11 // BDict (binary dictionary) format. All offsets are little endian.
14 // "BDic" Signature (4 bytes)
15 // Version (little endian 4 bytes)
16 // Absolute offset in file of the aff info. (4 bytes)
17 // Absolute offset in file of the dic table. (4 bytes)
18 // (Added by v2.0) MD5 checksum of the aff info and the dic table. (16 bytes)
21 // Absolute offset in file of the affix group table (4 bytes)
22 // Absolute offset in file of the affix rules table (4 bytes)
23 // Absolute offset in file of the replacements table (4 bytes)
24 // Absolute offset in file of the "other rules" table (4 bytes)
26 // The data between the aff header and the affix rules table is the comment
27 // from the beginning of the .aff file which often contains copyrights, etc.
30 // Array of NULL terminated strings. It will end in a double-NULL.
33 // List of LF termianted lines. NULL terminated.
35 // Replacements table:
36 // List of pairs of NULL teminated words. The end is indicated by a
37 // double-NULL. The first word in the pair is the replacement source, the
38 // second is what to replace it with. Example:
40 // for replacing ("foo" with "bar") and ("a" with "b").
43 // List of LF termianted lines. NULL terminated.
46 // Dic table. This stores the .dic file which contains the words in the
47 // dictionary, and indices for each one that indicate a set of suffixes or
48 // prefixes that can be applied. We store it in a trie to save space. It
49 // replaces Hunspell's hash manager.
51 // 0abxxxxx xxxxxxxx (in binary) Leaf node:
52 // The number stored in the bits represented by x is the affix index.
54 // If bit <a> is set, the leaf node has an additional string. Following the
55 // 2 byte header is a NULL-terminated (possibly 0-length) string that should
56 // be appended to the node. This allows long unique endings to be handled
59 // If bit <b> is set, the leaf node has a supplimental list of affix IDs
60 // following the ordinary data for the leaf node. These affix group IDs are
61 // additional rules for the same word. For example, two prefixes may go
62 // with distinct sets of suffixes.
64 // If the affix index is all 1's, then that means that there is only the
65 // supplimental list, and the 13-bit of affix built-in to the node don't
66 // count. This is used to represent numbers greater than 13 bits, since
67 // the supplimentary list has 16 bits per entry. The node must have a
68 // supplimenal list if this is set.
70 // This additional array is an array of 16-bit little-endian values,
71 // terminated by 0xFFFF (since 0 is an affix ID meaning "no affix ID".
73 // 0x110000ab: Lookup node.
74 // When <a> is set, addresses are 32-bits relative to the beginning of the
75 // dictionary data. When unset, addresses are 16-bits relative to the
76 // beginning of this node. All values are little endian.
78 // When <b> is set, there is one additional entry before the table begins.
79 // This is the 0th character. 0 is a common addition (meaning no more data)
80 // and this prevents us from having to store entries for all the control
81 // characters. This magic element is not counted in the table size.
83 // The ID byte is followeed by two bytes:
84 // XX: First character value in the lookup table.
85 // XX: Number of characters in the lookup table.
87 // This is followed optionally by the entry for 0, and then by a table of
88 // size indicated by the second charatcer after the ID.
90 // 1110xxxx: List node with 8-bit addresses.
91 // The number of items (max 16) in the list is stored in the bits xxxx.
92 // Followed by N (character byte, 8-bit offset) pairs. These offsets are
93 // relative to the end of the list of pairs.
94 // 1111xxxx: List node with 16-bit addresses. Same as above but offsets are
95 // 2-bytes each. LITTLE ENDIAN!
104 enum { SIGNATURE
= 0x63694442 };
112 // Major versions are incompatible with other major versions. Minor versions
113 // should be readable by older programs expecting the same major version.
114 uint16 major_version
;
115 uint16 minor_version
;
117 uint32 aff_offset
; // Offset of the aff data.
118 uint32 dic_offset
; // Offset of the dic data.
120 // Added by version 2.0.
121 base::MD5Digest digest
; // MD5 digest of the aff data and the dic data.
124 // AFF section ===============================================================
127 uint32 affix_group_offset
;
128 uint32 affix_rule_offset
;
129 uint32 rep_offset
; // Replacements table.
133 // DIC section ===============================================================
135 // Leaf ----------------------------------------------------------------------
137 // Leaf nodes have the high bit set to 0.
138 enum { LEAF_NODE_TYPE_MASK
= 0x80 }; // 10000000
139 enum { LEAF_NODE_TYPE_VALUE
= 0 }; // 00000000
141 // Leaf nodes with additional strings have the next-to-high bit set to 1.
142 // This mask/value pair also includes the high bit set to 0 which is the leaf
144 enum { LEAF_NODE_ADDITIONAL_MASK
= 0xC0 }; // 11000000
145 enum { LEAF_NODE_ADDITIONAL_VALUE
= 0x40 }; // 01000000
147 // Leaf nodes with an additional array of affix rules following it.
148 enum { LEAF_NODE_FOLLOWING_MASK
= 0xA0 }; // 10100000
149 enum { LEAF_NODE_FOLLOWING_VALUE
= 0x20 }; // 00100000
151 // The low 5 bits of the leaf node ID byte are the first 5 bits of the affix
152 // ID. The following byte is used for the low bits of the affix ID (we don't
153 // specify as mask for that).
154 enum { LEAF_NODE_FIRST_BYTE_AFFIX_MASK
= 0x1F }; // 00011111
156 // The maximum affix value that can be stored in the first entry (not in the
157 // following list). We reserve all 1's to be a magic value (see next entry)
158 // so we can store large numbers somewhere else.
159 enum { LEAF_NODE_MAX_FIRST_AFFIX_ID
= 0x1FFE }; // 00011111 11111110
161 // When the affix built-in to the leaf node (the first one) has too many bits
162 // for the space reserved for it (13 bits), then we fill it with this value.
163 // This means that the affix doesn't count. The affix will instead be stored
164 // in the "following list" which allows up to 16 bits per entry.
165 enum { FIRST_AFFIX_IS_UNUSED
= 0x1FFF }; // 00011111 11111111
167 // The maximum number of leaf nodes we'll read that have the same word and
168 // follow each other (the FOLLOWING bit is set).
169 enum { MAX_AFFIXES_PER_WORD
= 32 };
171 // The terminator for the list of following affix group IDs.
172 enum { LEAF_NODE_FOLLOWING_LIST_TERMINATOR
= 0xFFFF };
174 // Lookup --------------------------------------------------------------------
176 // Lookup nodes have the first 6 bits set to 110000.
177 enum { LOOKUP_NODE_TYPE_MASK
= 0xFC }; // 11111100
178 enum { LOOKUP_NODE_TYPE_VALUE
= 0xC0 }; // 11000000
180 // Lookup nodes have the low bit meaning it has a 0th entry, and the
181 // next-to-lowest bit indicating whether the offsets are 32-bits. Included
182 // in these masks are the lookup ID above.
183 enum { LOOKUP_NODE_0TH_MASK
= 0xFD }; // 11111110
184 enum { LOOKUP_NODE_0TH_VALUE
= 0xC1 }; // 11000010
185 enum { LOOKUP_NODE_32BIT_MASK
= 0xFE}; // 11111110
186 enum { LOOKUP_NODE_32BIT_VALUE
= 0xC2}; // 11000001
188 // List ----------------------------------------------------------------------
190 // List nodes have the first 3 bits set to 1.
191 enum { LIST_NODE_TYPE_MASK
= 0xE0 }; // 11100000
192 enum { LIST_NODE_TYPE_VALUE
= 0xE0 }; // 11100000
194 // The 4th from highest bit indicates a 16 bit (as opposed to 8 bit) list.
195 // This mask/value also includes the list ID in the high 3 bits.
196 enum { LIST_NODE_16BIT_MASK
= 0xF0 }; // 11110000
197 enum { LIST_NODE_16BIT_VALUE
= 0xF0 }; // 11110000
199 // The low 4 bits of the list ID byte are the count.
200 enum { LIST_NODE_COUNT_MASK
= 0xF }; // 00001111
202 // Verifies the specified BDICT is sane. This function checks the BDICT header
203 // and compares the MD5 digest of the data with the one in the header.
204 static bool Verify(const char* bdict_data
, size_t bdict_length
);
209 } // namespace hunspell
211 #endif // THIRD_PARTY_HUNSPELL_GOOGLE_BDICT_H_