| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2011 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2007-2009 Torch Mobile, Inc. | 3 * Copyright (C) 2007-2009 Torch Mobile, Inc. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 #include "wtf/text/TextCodecUTF8.h" | 43 #include "wtf/text/TextCodecUTF8.h" |
| 44 #include "wtf/text/TextCodecUserDefined.h" | 44 #include "wtf/text/TextCodecUserDefined.h" |
| 45 #include "wtf/text/TextEncoding.h" | 45 #include "wtf/text/TextEncoding.h" |
| 46 | 46 |
| 47 namespace WTF { | 47 namespace WTF { |
| 48 | 48 |
| 49 const size_t maxEncodingNameLength = 63; | 49 const size_t maxEncodingNameLength = 63; |
| 50 | 50 |
| 51 // Hash for all-ASCII strings that does case folding. | 51 // Hash for all-ASCII strings that does case folding. |
| 52 struct TextEncodingNameHash { | 52 struct TextEncodingNameHash { |
| 53 static bool equal(const char* s1, const char* s2) | 53 static bool equal(const char* s1, const char* s2) { |
| 54 { | 54 char c1; |
| 55 char c1; | 55 char c2; |
| 56 char c2; | 56 do { |
| 57 do { | |
| 58 #if defined(_MSC_FULL_VER) && _MSC_FULL_VER == 170051106 | 57 #if defined(_MSC_FULL_VER) && _MSC_FULL_VER == 170051106 |
| 59 // Workaround for a bug in the VS2012 Update 1 optimizer, remove onc
e the fix is released. | 58 // Workaround for a bug in the VS2012 Update 1 optimizer, remove once the
fix is released. |
| 60 // https://connect.microsoft.com/VisualStudio/feedback/details/77753
3/vs2012-c-optimizing-bug-when-using-inline-and-char-return-type-x86-target-only | 59 // https://connect.microsoft.com/VisualStudio/feedback/details/777533/vs20
12-c-optimizing-bug-when-using-inline-and-char-return-type-x86-target-only |
| 61 c1 = toASCIILower(*s1++); | 60 c1 = toASCIILower(*s1++); |
| 62 c2 = toASCIILower(*s2++); | 61 c2 = toASCIILower(*s2++); |
| 63 if (c1 != c2) | 62 if (c1 != c2) |
| 64 return false; | 63 return false; |
| 65 #else | 64 #else |
| 66 c1 = *s1++; | 65 c1 = *s1++; |
| 67 c2 = *s2++; | 66 c2 = *s2++; |
| 68 if (toASCIILower(c1) != toASCIILower(c2)) | 67 if (toASCIILower(c1) != toASCIILower(c2)) |
| 69 return false; | 68 return false; |
| 70 #endif | 69 #endif |
| 71 } while (c1 && c2); | 70 } while (c1 && c2); |
| 72 return !c1 && !c2; | 71 return !c1 && !c2; |
| 72 } |
| 73 |
| 74 // This algorithm is the one-at-a-time hash from: |
| 75 // http://burtleburtle.net/bob/hash/hashfaq.html |
| 76 // http://burtleburtle.net/bob/hash/doobs.html |
| 77 static unsigned hash(const char* s) { |
| 78 unsigned h = WTF::stringHashingStartValue; |
| 79 for (;;) { |
| 80 char c = *s++; |
| 81 if (!c) { |
| 82 h += (h << 3); |
| 83 h ^= (h >> 11); |
| 84 h += (h << 15); |
| 85 return h; |
| 86 } |
| 87 h += toASCIILower(c); |
| 88 h += (h << 10); |
| 89 h ^= (h >> 6); |
| 73 } | 90 } |
| 91 } |
| 74 | 92 |
| 75 // This algorithm is the one-at-a-time hash from: | 93 static const bool safeToCompareToEmptyOrDeleted = false; |
| 76 // http://burtleburtle.net/bob/hash/hashfaq.html | |
| 77 // http://burtleburtle.net/bob/hash/doobs.html | |
| 78 static unsigned hash(const char* s) | |
| 79 { | |
| 80 unsigned h = WTF::stringHashingStartValue; | |
| 81 for (;;) { | |
| 82 char c = *s++; | |
| 83 if (!c) { | |
| 84 h += (h << 3); | |
| 85 h ^= (h >> 11); | |
| 86 h += (h << 15); | |
| 87 return h; | |
| 88 } | |
| 89 h += toASCIILower(c); | |
| 90 h += (h << 10); | |
| 91 h ^= (h >> 6); | |
| 92 } | |
| 93 } | |
| 94 | |
| 95 static const bool safeToCompareToEmptyOrDeleted = false; | |
| 96 }; | 94 }; |
| 97 | 95 |
| 98 struct TextCodecFactory { | 96 struct TextCodecFactory { |
| 99 NewTextCodecFunction function; | 97 NewTextCodecFunction function; |
| 100 const void* additionalData; | 98 const void* additionalData; |
| 101 TextCodecFactory(NewTextCodecFunction f = 0, const void* d = 0) : function(f
), additionalData(d) { } | 99 TextCodecFactory(NewTextCodecFunction f = 0, const void* d = 0) |
| 100 : function(f), additionalData(d) {} |
| 102 }; | 101 }; |
| 103 | 102 |
| 104 typedef HashMap<const char*, const char*, TextEncodingNameHash> TextEncodingName
Map; | 103 typedef HashMap<const char*, const char*, TextEncodingNameHash> TextEncodingName
Map; |
| 105 typedef HashMap<const char*, TextCodecFactory> TextCodecMap; | 104 typedef HashMap<const char*, TextCodecFactory> TextCodecMap; |
| 106 | 105 |
| 107 static Mutex& encodingRegistryMutex() | 106 static Mutex& encodingRegistryMutex() { |
| 108 { | 107 // We don't have to use AtomicallyInitializedStatic here because |
| 109 // We don't have to use AtomicallyInitializedStatic here because | 108 // this function is called on the main thread for any page before |
| 110 // this function is called on the main thread for any page before | 109 // it is used in worker threads. |
| 111 // it is used in worker threads. | 110 DEFINE_STATIC_LOCAL(Mutex, mutex, ()); |
| 112 DEFINE_STATIC_LOCAL(Mutex, mutex, ()); | 111 return mutex; |
| 113 return mutex; | |
| 114 } | 112 } |
| 115 | 113 |
| 116 static TextEncodingNameMap* textEncodingNameMap; | 114 static TextEncodingNameMap* textEncodingNameMap; |
| 117 static TextCodecMap* textCodecMap; | 115 static TextCodecMap* textCodecMap; |
| 118 | 116 |
| 119 namespace { | 117 namespace { |
| 120 static unsigned didExtendTextCodecMaps = 0; | 118 static unsigned didExtendTextCodecMaps = 0; |
| 121 | 119 |
| 122 ALWAYS_INLINE unsigned atomicDidExtendTextCodecMaps() | 120 ALWAYS_INLINE unsigned atomicDidExtendTextCodecMaps() { |
| 123 { | 121 return acquireLoad(&didExtendTextCodecMaps); |
| 124 return acquireLoad(&didExtendTextCodecMaps); | |
| 125 } | 122 } |
| 126 | 123 |
| 127 ALWAYS_INLINE void atomicSetDidExtendTextCodemMaps() | 124 ALWAYS_INLINE void atomicSetDidExtendTextCodemMaps() { |
| 128 { | 125 releaseStore(&didExtendTextCodecMaps, 1); |
| 129 releaseStore(&didExtendTextCodecMaps, 1); | |
| 130 } | 126 } |
| 131 } // namespace | 127 } // namespace |
| 132 | 128 |
| 133 static const char textEncodingNameBlacklist[][6] = { "UTF-7" }; | 129 static const char textEncodingNameBlacklist[][6] = {"UTF-7"}; |
| 134 | 130 |
| 135 #if ERROR_DISABLED | 131 #if ERROR_DISABLED |
| 136 | 132 |
| 137 static inline void checkExistingName(const char*, const char*) { } | 133 static inline void checkExistingName(const char*, const char*) {} |
| 138 | 134 |
| 139 #else | 135 #else |
| 140 | 136 |
| 141 static void checkExistingName(const char* alias, const char* atomicName) | 137 static void checkExistingName(const char* alias, const char* atomicName) { |
| 142 { | 138 const char* oldAtomicName = textEncodingNameMap->get(alias); |
| 143 const char* oldAtomicName = textEncodingNameMap->get(alias); | 139 if (!oldAtomicName) |
| 144 if (!oldAtomicName) | 140 return; |
| 145 return; | 141 if (oldAtomicName == atomicName) |
| 146 if (oldAtomicName == atomicName) | 142 return; |
| 147 return; | 143 // Keep the warning silent about one case where we know this will happen. |
| 148 // Keep the warning silent about one case where we know this will happen. | 144 if (strcmp(alias, "ISO-8859-8-I") == 0 && strcmp(oldAtomicName, "ISO-8859-8-I"
) == 0 && strcasecmp(atomicName, "iso-8859-8") == 0) |
| 149 if (strcmp(alias, "ISO-8859-8-I") == 0 | 145 return; |
| 150 && strcmp(oldAtomicName, "ISO-8859-8-I") == 0 | 146 WTF_LOG_ERROR("alias %s maps to %s already, but someone is trying to make it m
ap to %s", alias, oldAtomicName, atomicName); |
| 151 && strcasecmp(atomicName, "iso-8859-8") == 0) | |
| 152 return; | |
| 153 WTF_LOG_ERROR("alias %s maps to %s already, but someone is trying to make it
map to %s", alias, oldAtomicName, atomicName); | |
| 154 } | 147 } |
| 155 | 148 |
| 156 #endif | 149 #endif |
| 157 | 150 |
| 158 static bool isUndesiredAlias(const char* alias) | 151 static bool isUndesiredAlias(const char* alias) { |
| 159 { | 152 // Reject aliases with version numbers that are supported by some back-ends (s
uch as "ISO_2022,locale=ja,version=0" in ICU). |
| 160 // Reject aliases with version numbers that are supported by some back-ends
(such as "ISO_2022,locale=ja,version=0" in ICU). | 153 for (const char* p = alias; *p; ++p) { |
| 161 for (const char* p = alias; *p; ++p) { | 154 if (*p == ',') |
| 162 if (*p == ',') | 155 return true; |
| 163 return true; | 156 } |
| 164 } | 157 // 8859_1 is known to (at least) ICU, but other browsers don't support this na
me - and having it caused a compatibility |
| 165 // 8859_1 is known to (at least) ICU, but other browsers don't support this
name - and having it caused a compatibility | 158 // problem, see bug 43554. |
| 166 // problem, see bug 43554. | 159 if (0 == strcmp(alias, "8859_1")) |
| 167 if (0 == strcmp(alias, "8859_1")) | 160 return true; |
| 168 return true; | 161 return false; |
| 169 return false; | |
| 170 } | 162 } |
| 171 | 163 |
| 172 static void addToTextEncodingNameMap(const char* alias, const char* name) | 164 static void addToTextEncodingNameMap(const char* alias, const char* name) { |
| 173 { | 165 ASSERT(strlen(alias) <= maxEncodingNameLength); |
| 174 ASSERT(strlen(alias) <= maxEncodingNameLength); | 166 if (isUndesiredAlias(alias)) |
| 175 if (isUndesiredAlias(alias)) | 167 return; |
| 176 return; | 168 const char* atomicName = textEncodingNameMap->get(name); |
| 177 const char* atomicName = textEncodingNameMap->get(name); | 169 ASSERT(strcmp(alias, name) == 0 || atomicName); |
| 178 ASSERT(strcmp(alias, name) == 0 || atomicName); | 170 if (!atomicName) |
| 179 if (!atomicName) | 171 atomicName = name; |
| 180 atomicName = name; | 172 checkExistingName(alias, atomicName); |
| 181 checkExistingName(alias, atomicName); | 173 textEncodingNameMap->add(alias, atomicName); |
| 182 textEncodingNameMap->add(alias, atomicName); | |
| 183 } | 174 } |
| 184 | 175 |
| 185 static void addToTextCodecMap(const char* name, NewTextCodecFunction function, c
onst void* additionalData) | 176 static void addToTextCodecMap(const char* name, NewTextCodecFunction function, c
onst void* additionalData) { |
| 186 { | 177 const char* atomicName = textEncodingNameMap->get(name); |
| 187 const char* atomicName = textEncodingNameMap->get(name); | 178 ASSERT(atomicName); |
| 188 ASSERT(atomicName); | 179 textCodecMap->add(atomicName, TextCodecFactory(function, additionalData)); |
| 189 textCodecMap->add(atomicName, TextCodecFactory(function, additionalData)); | |
| 190 } | 180 } |
| 191 | 181 |
| 192 static void pruneBlacklistedCodecs() | 182 static void pruneBlacklistedCodecs() { |
| 193 { | 183 for (size_t i = 0; i < WTF_ARRAY_LENGTH(textEncodingNameBlacklist); ++i) { |
| 194 for (size_t i = 0; i < WTF_ARRAY_LENGTH(textEncodingNameBlacklist); ++i) { | 184 const char* atomicName = textEncodingNameMap->get(textEncodingNameBlacklist[
i]); |
| 195 const char* atomicName = textEncodingNameMap->get(textEncodingNameBlackl
ist[i]); | 185 if (!atomicName) |
| 196 if (!atomicName) | 186 continue; |
| 197 continue; | |
| 198 | 187 |
| 199 Vector<const char*> names; | 188 Vector<const char*> names; |
| 200 TextEncodingNameMap::const_iterator it = textEncodingNameMap->begin(); | 189 TextEncodingNameMap::const_iterator it = textEncodingNameMap->begin(); |
| 201 TextEncodingNameMap::const_iterator end = textEncodingNameMap->end(); | 190 TextEncodingNameMap::const_iterator end = textEncodingNameMap->end(); |
| 202 for (; it != end; ++it) { | 191 for (; it != end; ++it) { |
| 203 if (it->value == atomicName) | 192 if (it->value == atomicName) |
| 204 names.append(it->key); | 193 names.append(it->key); |
| 205 } | 194 } |
| 206 | 195 |
| 207 textEncodingNameMap->removeAll(names); | 196 textEncodingNameMap->removeAll(names); |
| 208 | 197 |
| 209 textCodecMap->remove(atomicName); | 198 textCodecMap->remove(atomicName); |
| 210 } | 199 } |
| 211 } | 200 } |
| 212 | 201 |
| 213 static void buildBaseTextCodecMaps() | 202 static void buildBaseTextCodecMaps() { |
| 214 { | 203 ASSERT(isMainThread()); |
| 215 ASSERT(isMainThread()); | 204 ASSERT(!textCodecMap); |
| 216 ASSERT(!textCodecMap); | 205 ASSERT(!textEncodingNameMap); |
| 217 ASSERT(!textEncodingNameMap); | |
| 218 | 206 |
| 219 textCodecMap = new TextCodecMap; | 207 textCodecMap = new TextCodecMap; |
| 220 textEncodingNameMap = new TextEncodingNameMap; | 208 textEncodingNameMap = new TextEncodingNameMap; |
| 221 | 209 |
| 222 TextCodecLatin1::registerEncodingNames(addToTextEncodingNameMap); | 210 TextCodecLatin1::registerEncodingNames(addToTextEncodingNameMap); |
| 223 TextCodecLatin1::registerCodecs(addToTextCodecMap); | 211 TextCodecLatin1::registerCodecs(addToTextCodecMap); |
| 224 | 212 |
| 225 TextCodecUTF8::registerEncodingNames(addToTextEncodingNameMap); | 213 TextCodecUTF8::registerEncodingNames(addToTextEncodingNameMap); |
| 226 TextCodecUTF8::registerCodecs(addToTextCodecMap); | 214 TextCodecUTF8::registerCodecs(addToTextCodecMap); |
| 227 | 215 |
| 228 TextCodecUTF16::registerEncodingNames(addToTextEncodingNameMap); | 216 TextCodecUTF16::registerEncodingNames(addToTextEncodingNameMap); |
| 229 TextCodecUTF16::registerCodecs(addToTextCodecMap); | 217 TextCodecUTF16::registerCodecs(addToTextCodecMap); |
| 230 | 218 |
| 231 TextCodecUserDefined::registerEncodingNames(addToTextEncodingNameMap); | 219 TextCodecUserDefined::registerEncodingNames(addToTextEncodingNameMap); |
| 232 TextCodecUserDefined::registerCodecs(addToTextCodecMap); | 220 TextCodecUserDefined::registerCodecs(addToTextCodecMap); |
| 233 } | 221 } |
| 234 | 222 |
| 235 bool isReplacementEncoding(const char* alias) | 223 bool isReplacementEncoding(const char* alias) { |
| 236 { | 224 return alias && !strcasecmp(alias, "replacement"); |
| 237 return alias && !strcasecmp(alias, "replacement"); | |
| 238 } | 225 } |
| 239 | 226 |
| 240 bool isReplacementEncoding(const String& alias) | 227 bool isReplacementEncoding(const String& alias) { |
| 241 { | 228 return alias == "replacement"; |
| 242 return alias == "replacement"; | |
| 243 } | 229 } |
| 244 | 230 |
| 245 static void extendTextCodecMaps() | 231 static void extendTextCodecMaps() { |
| 246 { | 232 TextCodecReplacement::registerEncodingNames(addToTextEncodingNameMap); |
| 247 TextCodecReplacement::registerEncodingNames(addToTextEncodingNameMap); | 233 TextCodecReplacement::registerCodecs(addToTextCodecMap); |
| 248 TextCodecReplacement::registerCodecs(addToTextCodecMap); | |
| 249 | 234 |
| 250 TextCodecICU::registerEncodingNames(addToTextEncodingNameMap); | 235 TextCodecICU::registerEncodingNames(addToTextEncodingNameMap); |
| 251 TextCodecICU::registerCodecs(addToTextCodecMap); | 236 TextCodecICU::registerCodecs(addToTextCodecMap); |
| 252 | 237 |
| 253 pruneBlacklistedCodecs(); | 238 pruneBlacklistedCodecs(); |
| 254 } | 239 } |
| 255 | 240 |
| 256 PassOwnPtr<TextCodec> newTextCodec(const TextEncoding& encoding) | 241 PassOwnPtr<TextCodec> newTextCodec(const TextEncoding& encoding) { |
| 257 { | 242 MutexLocker lock(encodingRegistryMutex()); |
| 258 MutexLocker lock(encodingRegistryMutex()); | |
| 259 | 243 |
| 260 | 244 ASSERT(textCodecMap); |
| 261 ASSERT(textCodecMap); | 245 TextCodecFactory factory = textCodecMap->get(encoding.name()); |
| 262 TextCodecFactory factory = textCodecMap->get(encoding.name()); | 246 ASSERT(factory.function); |
| 263 ASSERT(factory.function); | 247 return factory.function(encoding, factory.additionalData); |
| 264 return factory.function(encoding, factory.additionalData); | |
| 265 } | 248 } |
| 266 | 249 |
| 267 const char* atomicCanonicalTextEncodingName(const char* name) | 250 const char* atomicCanonicalTextEncodingName(const char* name) { |
| 268 { | 251 if (!name || !name[0]) |
| 269 if (!name || !name[0]) | 252 return 0; |
| 270 return 0; | 253 if (!textEncodingNameMap) |
| 271 if (!textEncodingNameMap) | 254 buildBaseTextCodecMaps(); |
| 272 buildBaseTextCodecMaps(); | |
| 273 | 255 |
| 274 MutexLocker lock(encodingRegistryMutex()); | 256 MutexLocker lock(encodingRegistryMutex()); |
| 275 | 257 |
| 276 if (const char* atomicName = textEncodingNameMap->get(name)) | 258 if (const char* atomicName = textEncodingNameMap->get(name)) |
| 277 return atomicName; | 259 return atomicName; |
| 278 if (atomicDidExtendTextCodecMaps()) | 260 if (atomicDidExtendTextCodecMaps()) |
| 279 return 0; | 261 return 0; |
| 280 extendTextCodecMaps(); | 262 extendTextCodecMaps(); |
| 281 atomicSetDidExtendTextCodemMaps(); | 263 atomicSetDidExtendTextCodemMaps(); |
| 282 return textEncodingNameMap->get(name); | 264 return textEncodingNameMap->get(name); |
| 283 } | 265 } |
| 284 | 266 |
| 285 template <typename CharacterType> | 267 template <typename CharacterType> |
| 286 const char* atomicCanonicalTextEncodingName(const CharacterType* characters, siz
e_t length) | 268 const char* atomicCanonicalTextEncodingName(const CharacterType* characters, siz
e_t length) { |
| 287 { | 269 char buffer[maxEncodingNameLength + 1]; |
| 288 char buffer[maxEncodingNameLength + 1]; | 270 size_t j = 0; |
| 289 size_t j = 0; | 271 for (size_t i = 0; i < length; ++i) { |
| 290 for (size_t i = 0; i < length; ++i) { | 272 char c = static_cast<char>(characters[i]); |
| 291 char c = static_cast<char>(characters[i]); | 273 if (j == maxEncodingNameLength || c != characters[i]) |
| 292 if (j == maxEncodingNameLength || c != characters[i]) | 274 return 0; |
| 293 return 0; | 275 buffer[j++] = c; |
| 294 buffer[j++] = c; | 276 } |
| 295 } | 277 buffer[j] = 0; |
| 296 buffer[j] = 0; | 278 return atomicCanonicalTextEncodingName(buffer); |
| 297 return atomicCanonicalTextEncodingName(buffer); | |
| 298 } | 279 } |
| 299 | 280 |
| 300 const char* atomicCanonicalTextEncodingName(const String& alias) | 281 const char* atomicCanonicalTextEncodingName(const String& alias) { |
| 301 { | 282 if (!alias.length()) |
| 302 if (!alias.length()) | 283 return 0; |
| 303 return 0; | |
| 304 | 284 |
| 305 if (alias.contains(static_cast<UChar>('\0'))) | 285 if (alias.contains(static_cast<UChar>('\0'))) |
| 306 return 0; | 286 return 0; |
| 307 | 287 |
| 308 if (alias.is8Bit()) | 288 if (alias.is8Bit()) |
| 309 return atomicCanonicalTextEncodingName<LChar>(alias.characters8(), alias
.length()); | 289 return atomicCanonicalTextEncodingName<LChar>(alias.characters8(), alias.len
gth()); |
| 310 | 290 |
| 311 return atomicCanonicalTextEncodingName<UChar>(alias.characters16(), alias.le
ngth()); | 291 return atomicCanonicalTextEncodingName<UChar>(alias.characters16(), alias.leng
th()); |
| 312 } | 292 } |
| 313 | 293 |
| 314 bool noExtendedTextEncodingNameUsed() | 294 bool noExtendedTextEncodingNameUsed() { |
| 315 { | 295 return !atomicDidExtendTextCodecMaps(); |
| 316 return !atomicDidExtendTextCodecMaps(); | |
| 317 } | 296 } |
| 318 | 297 |
| 319 #ifndef NDEBUG | 298 #ifndef NDEBUG |
| 320 void dumpTextEncodingNameMap() | 299 void dumpTextEncodingNameMap() { |
| 321 { | 300 unsigned size = textEncodingNameMap->size(); |
| 322 unsigned size = textEncodingNameMap->size(); | 301 fprintf(stderr, "Dumping %u entries in WTF::TextEncodingNameMap...\n", size); |
| 323 fprintf(stderr, "Dumping %u entries in WTF::TextEncodingNameMap...\n", size)
; | |
| 324 | 302 |
| 325 MutexLocker lock(encodingRegistryMutex()); | 303 MutexLocker lock(encodingRegistryMutex()); |
| 326 | 304 |
| 327 TextEncodingNameMap::const_iterator it = textEncodingNameMap->begin(); | 305 TextEncodingNameMap::const_iterator it = textEncodingNameMap->begin(); |
| 328 TextEncodingNameMap::const_iterator end = textEncodingNameMap->end(); | 306 TextEncodingNameMap::const_iterator end = textEncodingNameMap->end(); |
| 329 for (; it != end; ++it) | 307 for (; it != end; ++it) |
| 330 fprintf(stderr, "'%s' => '%s'\n", it->key, it->value); | 308 fprintf(stderr, "'%s' => '%s'\n", it->key, it->value); |
| 331 } | 309 } |
| 332 #endif | 310 #endif |
| 333 | 311 |
| 334 } // namespace WTF | 312 } // namespace WTF |
| OLD | NEW |