Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/i18n/icu_encoding_detection.h" | 5 #include "base/i18n/icu_encoding_detection.h" |
| 6 | 6 |
| 7 #include "base/string_util.h" | 7 #include "base/string_util.h" |
| 8 #include "unicode/ucsdet.h" | 8 #include "unicode/ucsdet.h" |
| 9 | 9 |
| 10 namespace base { | 10 namespace base { |
| 11 | 11 |
| 12 // TODO(jungshik): We can apply more heuristics here (e.g. using various hints | |
| 13 // like TLD, the UI language/default encoding of a client, etc). | |
| 14 bool DetectEncoding(const std::string& text, std::string* encoding) { | 12 bool DetectEncoding(const std::string& text, std::string* encoding) { |
| 15 if (IsStringASCII(text)) { | 13 if (IsStringASCII(text)) { |
| 16 *encoding = std::string(); | 14 *encoding = std::string(); |
| 17 return true; | 15 return true; |
| 18 } | 16 } |
| 19 | 17 |
| 20 UErrorCode status = U_ZERO_ERROR; | 18 UErrorCode status = U_ZERO_ERROR; |
| 21 UCharsetDetector* detector = ucsdet_open(&status); | 19 UCharsetDetector* detector = ucsdet_open(&status); |
| 22 ucsdet_setText(detector, text.data(), static_cast<int32_t>(text.length()), | 20 ucsdet_setText(detector, text.data(), static_cast<int32_t>(text.length()), |
| 23 &status); | 21 &status); |
| 24 // TODO(jungshik): Should we check the quality of the match? A rather | |
| 25 // arbitrary number is assigned by ICU and it's hard to come up with | |
| 26 // a lower limit. | |
| 27 const UCharsetMatch* match = ucsdet_detect(detector, &status); | 22 const UCharsetMatch* match = ucsdet_detect(detector, &status); |
| 28 const char* detected_encoding = ucsdet_getName(match, &status); | 23 const char* detected_encoding = ucsdet_getName(match, &status); |
| 29 ucsdet_close(detector); | 24 ucsdet_close(detector); |
| 30 | 25 |
| 31 if (U_FAILURE(status)) | 26 if (U_FAILURE(status)) |
| 32 return false; | 27 return false; |
| 33 | 28 |
| 34 *encoding = detected_encoding; | 29 *encoding = detected_encoding; |
| 35 return true; | 30 return true; |
| 36 } | 31 } |
| 37 | 32 |
| 33 bool DetectAllEncodings(const std::string& text, | |
|
cbentzel
2010/11/18 16:39:43
Is a bool needed here? Could empty encodings be su
| |
| 34 std::vector<std::string>* encodings) { | |
| 35 UErrorCode status = U_ZERO_ERROR; | |
| 36 UCharsetDetector* detector = ucsdet_open(&status); | |
|
cbentzel
2010/11/18 16:39:43
Should you check for failure after this call?
ht
| |
| 37 ucsdet_setText(detector, text.data(), static_cast<int32_t>(text.length()), | |
|
cbentzel
2010/11/18 16:39:43
Should you check for failure after this call as we
| |
| 38 &status); | |
| 39 int matches_count = 0; | |
| 40 const UCharsetMatch** matches = ucsdet_detectAll(detector, | |
| 41 &matches_count, | |
| 42 &status); | |
| 43 if (U_FAILURE(status)) { | |
| 44 ucsdet_close(detector); | |
| 45 return false; | |
| 46 } | |
| 47 | |
| 48 encodings->clear(); | |
| 49 for (int i = 0; i < matches_count; i++) { | |
| 50 UErrorCode get_name_status = U_ZERO_ERROR; | |
| 51 const char* encoding_name = ucsdet_getName(matches[i], &get_name_status); | |
| 52 | |
| 53 // If we failed to get the encoding's name, ignore the error. | |
| 54 if (U_FAILURE(get_name_status)) | |
| 55 continue; | |
| 56 | |
| 57 encodings->push_back(encoding_name); | |
| 58 } | |
| 59 | |
| 60 ucsdet_close(detector); | |
| 61 return !encodings->empty(); | |
| 62 } | |
| 63 | |
| 38 } // namespace base | 64 } // namespace base |
| OLD | NEW |