Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / third_party / cld_2 / src / internal / cld2_dynamic_data.cc
1 // Copyright 2014 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "cld2_dynamic_data.h"
16 #include "integral_types.h"
17 #include <assert.h>
18 #include <iostream>
19 #include <stdint.h>
20
21 namespace CLD2DynamicData {
22 static int DEBUG=0;
23 void setDebug(int debug) {
24   DEBUG=debug;
25 }
26
27 bool mem_compare(const void* data1, const void* data2, const int length) {
28   const unsigned char* raw1 = static_cast<const unsigned char*>(data1);
29   const unsigned char* raw2 = static_cast<const unsigned char*>(data2);
30   for (int x=0; x<length; x++) {
31     if (raw1[x] != raw2[x]) {
32       std::cerr << "mem difference at data[" << x << "]: decimal " << (unsigned int) raw1[x] << " != decimal " << (unsigned int) raw2[x] << std::endl;
33       for (int y=std::max(0,x-5); y<length && y<=x+5; y++) {
34         std::cerr << "[" << y << "]: " << (unsigned int) raw1[y]
35           << " <-> " << (unsigned int) raw2[y]
36           << ( x == y ? " [FIRST ERROR DETECTED HERE] " : "")
37           << std::endl;
38       }
39       return false;
40     }
41   }
42   return true;
43 }
44
45 CLD2::uint32 calculateHeaderSize(CLD2::uint32 numTables) {
46   return DATA_FILE_MARKER_LENGTH // NB: no null terminator
47     + (20 * sizeof(CLD2::uint32)) // 20 uint32 fields in the struct
48     + (numTables * (10 * sizeof(CLD2::uint32))); // 10 uint32 per table
49 }
50
51 void dumpHeader(FileHeader* header) {
52   char safeString[DATA_FILE_MARKER_LENGTH + 1];
53   memcpy(safeString, header->sanityString, DATA_FILE_MARKER_LENGTH);
54   safeString[DATA_FILE_MARKER_LENGTH] = 0;
55   std::cout << "sanityString: " << safeString << std::endl;
56   std::cout << "totalFileSizeBytes: " << header->totalFileSizeBytes << std::endl;
57   std::cout << "utf8PropObj_state0: " << header->utf8PropObj_state0 << std::endl;
58   std::cout << "utf8PropObj_state0_size: " << header->utf8PropObj_state0_size << std::endl;
59   std::cout << "utf8PropObj_total_size: " << header->utf8PropObj_total_size << std::endl;
60   std::cout << "utf8PropObj_max_expand: " << header->utf8PropObj_max_expand << std::endl;
61   std::cout << "utf8PropObj_entry_shift: " << header->utf8PropObj_entry_shift << std::endl;
62   std::cout << "utf8PropObj_bytes_per_entry: " << header->utf8PropObj_bytes_per_entry << std::endl;
63   std::cout << "utf8PropObj_losub: " << header->utf8PropObj_losub << std::endl;
64   std::cout << "utf8PropObj_hiadd: " << header->utf8PropObj_hiadd << std::endl;
65   std::cout << "startOf_utf8PropObj_state_table: " << header->startOf_utf8PropObj_state_table << std::endl;
66   std::cout << "lengthOf_utf8PropObj_state_table: " << header->lengthOf_utf8PropObj_state_table << std::endl;
67   std::cout << "startOf_utf8PropObj_remap_base: " << header->startOf_utf8PropObj_remap_base << std::endl;
68   std::cout << "lengthOf_utf8PropObj_remap_base: " << header->lengthOf_utf8PropObj_remap_base << std::endl;
69   std::cout << "startOf_utf8PropObj_remap_string: " << header->startOf_utf8PropObj_remap_string << std::endl;
70   std::cout << "lengthOf_utf8PropObj_remap_string: " << header->lengthOf_utf8PropObj_remap_string << std::endl;
71   std::cout << "startOf_utf8PropObj_fast_state: " << header->startOf_utf8PropObj_fast_state << std::endl;
72   std::cout << "lengthOf_utf8PropObj_fast_state: " << header->lengthOf_utf8PropObj_fast_state << std::endl;
73   std::cout << "startOf_kAvgDeltaOctaScore: " << header->startOf_kAvgDeltaOctaScore << std::endl;
74   std::cout << "lengthOf_kAvgDeltaOctaScore: " << header->lengthOf_kAvgDeltaOctaScore << std::endl;
75   std::cout << "numTablesEncoded: " << header->numTablesEncoded << std::endl;
76
77   const char* tableNames[7];
78   tableNames[0]="unigram_compat_obj";
79   tableNames[1]="deltabi_obj";
80   tableNames[2]="distinctbi_obj";
81   tableNames[3]="quadgram_obj";
82   tableNames[4]="quadgram_obj2";
83   tableNames[5]="deltaocta_obj";
84   tableNames[6]="distinctocta_obj";
85
86   for (int x=0; x<header->numTablesEncoded; x++) {
87     TableHeader& tHeader = header->tableHeaders[x];
88       
89     std::cout << "Table " << (x+1) << ": (" << tableNames[x] << ")" << std::endl;
90     std::cout << "  kCLDTableSizeOne: " << tHeader.kCLDTableSizeOne << std::endl;
91     std::cout << "  kCLDTableSize: " << tHeader.kCLDTableSize << std::endl;
92     std::cout << "  kCLDTableKeyMask: " << tHeader.kCLDTableKeyMask << std::endl;
93     std::cout << "  kCLDTableBuildDate: " << tHeader.kCLDTableBuildDate << std::endl;
94     std::cout << "  startOf_kCLDTable: " << tHeader.startOf_kCLDTable << std::endl;
95     std::cout << "  lengthOf_kCLDTable: " << tHeader.lengthOf_kCLDTable << std::endl;
96     std::cout << "  startOf_kCLDTableInd: " << tHeader.startOf_kCLDTableInd << std::endl;
97     std::cout << "  lengthOf_kCLDTableInd: " << tHeader.lengthOf_kCLDTableInd << std::endl;
98     std::cout << "  startOf_kRecognizedLangScripts: " << tHeader.startOf_kRecognizedLangScripts << std::endl;
99     std::cout << "  lengthOf_kRecognizedLangScripts: " << tHeader.lengthOf_kRecognizedLangScripts << std::endl;
100   }
101 }
102
103 #define CHECK_EQUALS(name) if (loadedData->name != realData->name) {\
104   std::cerr << #name << ": " << loadedData->name << " != " << realData->name << std::endl;\
105   return false;\
106 }
107
108 #define CHECK_MEM_EQUALS(name,size) if (!mem_compare(loadedData->name,realData->name,size)) {\
109   std::cerr << #name << ": data mismatch." << std::endl;\
110   return false;\
111 }
112
113 bool verify(const CLD2::ScoringTables* realData,
114             const Supplement* realSupplement,
115             const CLD2::ScoringTables* loadedData) {
116   const int NUM_TABLES = 7;
117   const CLD2::CLD2TableSummary* realTableSummaries[NUM_TABLES];
118   realTableSummaries[0] = realData->unigram_compat_obj;
119   realTableSummaries[1] = realData->deltabi_obj;
120   realTableSummaries[2] = realData->distinctbi_obj;
121   realTableSummaries[3] = realData->quadgram_obj;
122   realTableSummaries[4] = realData->quadgram_obj2;
123   realTableSummaries[5] = realData->deltaocta_obj;
124   realTableSummaries[6] = realData->distinctocta_obj;
125
126   const CLD2::CLD2TableSummary* loadedTableSummaries[NUM_TABLES];
127   loadedTableSummaries[0] = loadedData->unigram_compat_obj;
128   loadedTableSummaries[1] = loadedData->deltabi_obj;
129   loadedTableSummaries[2] = loadedData->distinctbi_obj;
130   loadedTableSummaries[3] = loadedData->quadgram_obj;
131   loadedTableSummaries[4] = loadedData->quadgram_obj2;
132   loadedTableSummaries[5] = loadedData->deltaocta_obj;
133   loadedTableSummaries[6] = loadedData->distinctocta_obj;
134
135   CHECK_EQUALS(unigram_obj->state0);
136   CHECK_EQUALS(unigram_obj->state0_size);
137   CHECK_EQUALS(unigram_obj->total_size);
138   CHECK_EQUALS(unigram_obj->max_expand);
139   CHECK_EQUALS(unigram_obj->entry_shift);
140   CHECK_EQUALS(unigram_obj->bytes_per_entry);
141   CHECK_EQUALS(unigram_obj->losub);
142   CHECK_EQUALS(unigram_obj->hiadd);
143   CHECK_MEM_EQUALS(unigram_obj->state_table, realData->unigram_obj->total_size);
144   CHECK_MEM_EQUALS(unigram_obj->remap_base, sizeof(CLD2::RemapEntry)); // TODO: can this have more than one entry?
145   CHECK_MEM_EQUALS(unigram_obj->remap_string, strlen(
146       reinterpret_cast<const char*>(realData->unigram_obj->remap_string)) + 1); // null terminator included
147
148   if (loadedData->unigram_obj->fast_state == NULL) {
149     if (realData->unigram_obj->fast_state != NULL) {
150       std::cerr << "unigram_obj->fast_state is missing." << std::endl;
151       return false;
152     }
153   } else {
154     if (realData->unigram_obj->fast_state == NULL) {
155       std::cerr << "unigram_obj->fast_state shouldn't be present." << std::endl;
156       return false;
157     }
158     CHECK_MEM_EQUALS(unigram_obj->fast_state, strlen(
159       reinterpret_cast<const char*>(realData->unigram_obj->fast_state)) + 1); // null terminator included
160   }
161   if (DEBUG) std::cout << "verified." << std::endl;
162
163   if (DEBUG) std::cout << "Verifying kExpectedScore... ";
164   CHECK_MEM_EQUALS(kExpectedScore, realSupplement->lengthOf_kAvgDeltaOctaScore);
165   if (DEBUG) std::cout << "verified." << std::endl;
166
167   // 3. Each table
168   for (int x=0; x<NUM_TABLES; x++) {
169     if (DEBUG) std::cout << "Verifying table " << (x+1) << "... ";
170     const CLD2::CLD2TableSummary* realData = realTableSummaries[x];
171     const CLD2::CLD2TableSummary* loadedData = loadedTableSummaries[x];
172     // We need to calculate the table lengths to do the memcmp
173     CLD2::uint32 bytesPerBucket = sizeof(CLD2::IndirectProbBucket4);
174     CLD2::uint32 numBuckets = realData->kCLDTableSize;
175     CLD2::uint32 tableSizeBytes = bytesPerBucket * numBuckets;
176     CLD2::uint32 indirectTableSizeBytes = realSupplement->indirectTableSizes[x];
177     CLD2::uint32 recognizedScriptsSizeBytes =
178       strlen(realData->kRecognizedLangScripts) + 1; // null terminator included
179
180     // Verify the table data
181     CHECK_EQUALS(kCLDTableSizeOne);
182     CHECK_EQUALS(kCLDTableSize);
183     CHECK_EQUALS(kCLDTableKeyMask);
184     CHECK_EQUALS(kCLDTableBuildDate);
185     CHECK_MEM_EQUALS(kCLDTable, tableSizeBytes);
186     CHECK_MEM_EQUALS(kCLDTableInd, indirectTableSizeBytes);
187     CHECK_MEM_EQUALS(kRecognizedLangScripts, recognizedScriptsSizeBytes);
188     if (DEBUG) std::cout << "verified." << std::endl;
189   }
190   if (DEBUG) std::cout << "All data verified successfully." << std::endl;
191   return true;
192 }
193
194 // As noted on http://stackoverflow.com/questions/1001307, gcc is highly likely
195 // to convert this function's return into a constant - meaning that any
196 // if-branches based upon it will be eliminated at compile time, allowing
197 // "free" detection throughout any dependent code.
198 bool isLittleEndian() {
199   union {
200     uint32_t integer;
201     char bytes[4];
202   } test = {0x01020304};
203   return test.bytes[0] == 4;
204 }
205
206 bool coreAssumptionsOk() {
207   if (sizeof(CLD2::uint8) != 1) {
208     std::cerr << "uint8 is " << (sizeof(CLD2::uint8) * 8)
209       << " bits instead of 8!" << std::endl;
210     return false;
211   }
212   if (sizeof(CLD2::uint16) != 2) {
213     std::cerr << "uint16 is " << (sizeof(CLD2::uint16) * 8)
214       << " bits instead of 16!" << std::endl;
215     return false;
216   }
217   if (sizeof(CLD2::uint32) != 4) {
218     std::cerr << "uint32 is " << (sizeof(CLD2::uint32) * 8)
219       << " bits instead of 32!" << std::endl;
220     return false;
221   }
222   return true;
223 }
224
225 } // End namespace CLD2DynamicData