| OLD | NEW |
| 1 /* | 1 /* |
| 2 * (C) 1999 Lars Knoll (knoll@kde.org) | 2 * (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 2012 Apple Inc. All rights
reserved. | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 2012 Apple Inc. All rights
reserved. |
| 4 * Copyright (C) 2007-2009 Torch Mobile, Inc. | 4 * Copyright (C) 2007-2009 Torch Mobile, Inc. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 913 } | 913 } |
| 914 | 914 |
| 915 String String::fromUTF8WithLatin1Fallback(const LChar* string, size_t size) | 915 String String::fromUTF8WithLatin1Fallback(const LChar* string, size_t size) |
| 916 { | 916 { |
| 917 String utf8 = fromUTF8(string, size); | 917 String utf8 = fromUTF8(string, size); |
| 918 if (!utf8) | 918 if (!utf8) |
| 919 return String(string, size); | 919 return String(string, size); |
| 920 return utf8; | 920 return utf8; |
| 921 } | 921 } |
| 922 | 922 |
| 923 // String Operations | |
| 924 | |
| 925 static bool isCharacterAllowedInBase(UChar c, int base) | |
| 926 { | |
| 927 if (c > 0x7F) | |
| 928 return false; | |
| 929 if (isASCIIDigit(c)) | |
| 930 return c - '0' < base; | |
| 931 if (isASCIIAlpha(c)) { | |
| 932 if (base > 36) | |
| 933 base = 36; | |
| 934 return (c >= 'a' && c < 'a' + base - 10) | |
| 935 || (c >= 'A' && c < 'A' + base - 10); | |
| 936 } | |
| 937 return false; | |
| 938 } | |
| 939 | |
| 940 template <typename IntegralType, typename CharType> | |
| 941 static inline IntegralType toIntegralType(const CharType* data, size_t length, b
ool* ok, int base) | |
| 942 { | |
| 943 static const IntegralType integralMax = std::numeric_limits<IntegralType>::m
ax(); | |
| 944 static const bool isSigned = std::numeric_limits<IntegralType>::is_signed; | |
| 945 const IntegralType maxMultiplier = integralMax / base; | |
| 946 | |
| 947 IntegralType value = 0; | |
| 948 bool isOk = false; | |
| 949 bool isNegative = false; | |
| 950 | |
| 951 if (!data) | |
| 952 goto bye; | |
| 953 | |
| 954 // skip leading whitespace | |
| 955 while (length && isSpaceOrNewline(*data)) { | |
| 956 --length; | |
| 957 ++data; | |
| 958 } | |
| 959 | |
| 960 if (isSigned && length && *data == '-') { | |
| 961 --length; | |
| 962 ++data; | |
| 963 isNegative = true; | |
| 964 } else if (length && *data == '+') { | |
| 965 --length; | |
| 966 ++data; | |
| 967 } | |
| 968 | |
| 969 if (!length || !isCharacterAllowedInBase(*data, base)) | |
| 970 goto bye; | |
| 971 | |
| 972 while (length && isCharacterAllowedInBase(*data, base)) { | |
| 973 --length; | |
| 974 IntegralType digitValue; | |
| 975 CharType c = *data; | |
| 976 if (isASCIIDigit(c)) | |
| 977 digitValue = c - '0'; | |
| 978 else if (c >= 'a') | |
| 979 digitValue = c - 'a' + 10; | |
| 980 else | |
| 981 digitValue = c - 'A' + 10; | |
| 982 | |
| 983 if (value > maxMultiplier || (value == maxMultiplier && digitValue > (in
tegralMax % base) + isNegative)) | |
| 984 goto bye; | |
| 985 | |
| 986 value = base * value + digitValue; | |
| 987 ++data; | |
| 988 } | |
| 989 | |
| 990 #if COMPILER(MSVC) | |
| 991 #pragma warning(push, 0) | |
| 992 #pragma warning(disable:4146) | |
| 993 #endif | |
| 994 | |
| 995 if (isNegative) | |
| 996 value = -value; | |
| 997 | |
| 998 #if COMPILER(MSVC) | |
| 999 #pragma warning(pop) | |
| 1000 #endif | |
| 1001 | |
| 1002 // skip trailing space | |
| 1003 while (length && isSpaceOrNewline(*data)) { | |
| 1004 --length; | |
| 1005 ++data; | |
| 1006 } | |
| 1007 | |
| 1008 if (!length) | |
| 1009 isOk = true; | |
| 1010 bye: | |
| 1011 if (ok) | |
| 1012 *ok = isOk; | |
| 1013 return isOk ? value : 0; | |
| 1014 } | |
| 1015 | |
| 1016 template <typename CharType> | |
| 1017 static unsigned lengthOfCharactersAsInteger(const CharType* data, size_t length) | |
| 1018 { | |
| 1019 size_t i = 0; | |
| 1020 | |
| 1021 // Allow leading spaces. | |
| 1022 for (; i != length; ++i) { | |
| 1023 if (!isSpaceOrNewline(data[i])) | |
| 1024 break; | |
| 1025 } | |
| 1026 | |
| 1027 // Allow sign. | |
| 1028 if (i != length && (data[i] == '+' || data[i] == '-')) | |
| 1029 ++i; | |
| 1030 | |
| 1031 // Allow digits. | |
| 1032 for (; i != length; ++i) { | |
| 1033 if (!isASCIIDigit(data[i])) | |
| 1034 break; | |
| 1035 } | |
| 1036 | |
| 1037 return i; | |
| 1038 } | |
| 1039 | |
| 1040 int charactersToIntStrict(const LChar* data, size_t length, bool* ok, int base) | |
| 1041 { | |
| 1042 return toIntegralType<int, LChar>(data, length, ok, base); | |
| 1043 } | |
| 1044 | |
| 1045 int charactersToIntStrict(const UChar* data, size_t length, bool* ok, int base) | |
| 1046 { | |
| 1047 return toIntegralType<int, UChar>(data, length, ok, base); | |
| 1048 } | |
| 1049 | |
| 1050 unsigned charactersToUIntStrict(const LChar* data, size_t length, bool* ok, int
base) | |
| 1051 { | |
| 1052 return toIntegralType<unsigned, LChar>(data, length, ok, base); | |
| 1053 } | |
| 1054 | |
| 1055 unsigned charactersToUIntStrict(const UChar* data, size_t length, bool* ok, int
base) | |
| 1056 { | |
| 1057 return toIntegralType<unsigned, UChar>(data, length, ok, base); | |
| 1058 } | |
| 1059 | |
| 1060 int64_t charactersToInt64Strict(const LChar* data, size_t length, bool* ok, int
base) | |
| 1061 { | |
| 1062 return toIntegralType<int64_t, LChar>(data, length, ok, base); | |
| 1063 } | |
| 1064 | |
| 1065 int64_t charactersToInt64Strict(const UChar* data, size_t length, bool* ok, int
base) | |
| 1066 { | |
| 1067 return toIntegralType<int64_t, UChar>(data, length, ok, base); | |
| 1068 } | |
| 1069 | |
| 1070 uint64_t charactersToUInt64Strict(const LChar* data, size_t length, bool* ok, in
t base) | |
| 1071 { | |
| 1072 return toIntegralType<uint64_t, LChar>(data, length, ok, base); | |
| 1073 } | |
| 1074 | |
| 1075 uint64_t charactersToUInt64Strict(const UChar* data, size_t length, bool* ok, in
t base) | |
| 1076 { | |
| 1077 return toIntegralType<uint64_t, UChar>(data, length, ok, base); | |
| 1078 } | |
| 1079 | |
| 1080 int charactersToInt(const LChar* data, size_t length, bool* ok) | |
| 1081 { | |
| 1082 return toIntegralType<int, LChar>(data, lengthOfCharactersAsInteger<LChar>(d
ata, length), ok, 10); | |
| 1083 } | |
| 1084 | |
| 1085 int charactersToInt(const UChar* data, size_t length, bool* ok) | |
| 1086 { | |
| 1087 return toIntegralType<int, UChar>(data, lengthOfCharactersAsInteger(data, le
ngth), ok, 10); | |
| 1088 } | |
| 1089 | |
| 1090 unsigned charactersToUInt(const LChar* data, size_t length, bool* ok) | |
| 1091 { | |
| 1092 return toIntegralType<unsigned, LChar>(data, lengthOfCharactersAsInteger<LCh
ar>(data, length), ok, 10); | |
| 1093 } | |
| 1094 | |
| 1095 unsigned charactersToUInt(const UChar* data, size_t length, bool* ok) | |
| 1096 { | |
| 1097 return toIntegralType<unsigned, UChar>(data, lengthOfCharactersAsInteger<UCh
ar>(data, length), ok, 10); | |
| 1098 } | |
| 1099 | |
| 1100 int64_t charactersToInt64(const LChar* data, size_t length, bool* ok) | |
| 1101 { | |
| 1102 return toIntegralType<int64_t, LChar>(data, lengthOfCharactersAsInteger<LCha
r>(data, length), ok, 10); | |
| 1103 } | |
| 1104 | |
| 1105 int64_t charactersToInt64(const UChar* data, size_t length, bool* ok) | |
| 1106 { | |
| 1107 return toIntegralType<int64_t, UChar>(data, lengthOfCharactersAsInteger<UCha
r>(data, length), ok, 10); | |
| 1108 } | |
| 1109 | |
| 1110 uint64_t charactersToUInt64(const LChar* data, size_t length, bool* ok) | |
| 1111 { | |
| 1112 return toIntegralType<uint64_t, LChar>(data, lengthOfCharactersAsInteger<LCh
ar>(data, length), ok, 10); | |
| 1113 } | |
| 1114 | |
| 1115 uint64_t charactersToUInt64(const UChar* data, size_t length, bool* ok) | |
| 1116 { | |
| 1117 return toIntegralType<uint64_t, UChar>(data, lengthOfCharactersAsInteger<UCh
ar>(data, length), ok, 10); | |
| 1118 } | |
| 1119 | |
| 1120 enum TrailingJunkPolicy { DisallowTrailingJunk, AllowTrailingJunk }; | |
| 1121 | |
| 1122 template <typename CharType, TrailingJunkPolicy policy> | |
| 1123 static inline double toDoubleType(const CharType* data, size_t length, bool* ok,
size_t& parsedLength) | |
| 1124 { | |
| 1125 size_t leadingSpacesLength = 0; | |
| 1126 while (leadingSpacesLength < length && isASCIISpace(data[leadingSpacesLength
])) | |
| 1127 ++leadingSpacesLength; | |
| 1128 | |
| 1129 double number = parseDouble(data + leadingSpacesLength, length - leadingSpac
esLength, parsedLength); | |
| 1130 if (!parsedLength) { | |
| 1131 if (ok) | |
| 1132 *ok = false; | |
| 1133 return 0.0; | |
| 1134 } | |
| 1135 | |
| 1136 parsedLength += leadingSpacesLength; | |
| 1137 if (ok) | |
| 1138 *ok = policy == AllowTrailingJunk || parsedLength == length; | |
| 1139 return number; | |
| 1140 } | |
| 1141 | |
| 1142 double charactersToDouble(const LChar* data, size_t length, bool* ok) | |
| 1143 { | |
| 1144 size_t parsedLength; | |
| 1145 return toDoubleType<LChar, DisallowTrailingJunk>(data, length, ok, parsedLen
gth); | |
| 1146 } | |
| 1147 | |
| 1148 double charactersToDouble(const UChar* data, size_t length, bool* ok) | |
| 1149 { | |
| 1150 size_t parsedLength; | |
| 1151 return toDoubleType<UChar, DisallowTrailingJunk>(data, length, ok, parsedLen
gth); | |
| 1152 } | |
| 1153 | |
| 1154 double charactersToDouble(const LChar* data, size_t length, size_t& parsedLength
) | |
| 1155 { | |
| 1156 return toDoubleType<LChar, AllowTrailingJunk>(data, length, nullptr, parsedL
ength); | |
| 1157 } | |
| 1158 | |
| 1159 double charactersToDouble(const UChar* data, size_t length, size_t& parsedLength
) | |
| 1160 { | |
| 1161 return toDoubleType<UChar, AllowTrailingJunk>(data, length, nullptr, parsedL
ength); | |
| 1162 } | |
| 1163 | |
| 1164 float charactersToFloat(const LChar* data, size_t length, bool* ok) | |
| 1165 { | |
| 1166 // FIXME: This will return ok even when the string fits into a double but | |
| 1167 // not a float. | |
| 1168 size_t parsedLength; | |
| 1169 return static_cast<float>(toDoubleType<LChar, DisallowTrailingJunk>(data, le
ngth, ok, parsedLength)); | |
| 1170 } | |
| 1171 | |
| 1172 float charactersToFloat(const UChar* data, size_t length, bool* ok) | |
| 1173 { | |
| 1174 // FIXME: This will return ok even when the string fits into a double but | |
| 1175 // not a float. | |
| 1176 size_t parsedLength; | |
| 1177 return static_cast<float>(toDoubleType<UChar, DisallowTrailingJunk>(data, le
ngth, ok, parsedLength)); | |
| 1178 } | |
| 1179 | |
| 1180 float charactersToFloat(const LChar* data, size_t length, size_t& parsedLength) | |
| 1181 { | |
| 1182 // FIXME: This will return ok even when the string fits into a double but | |
| 1183 // not a float. | |
| 1184 return static_cast<float>(toDoubleType<LChar, AllowTrailingJunk>(data, lengt
h, 0, parsedLength)); | |
| 1185 } | |
| 1186 | |
| 1187 float charactersToFloat(const UChar* data, size_t length, size_t& parsedLength) | |
| 1188 { | |
| 1189 // FIXME: This will return ok even when the string fits into a double but | |
| 1190 // not a float. | |
| 1191 return static_cast<float>(toDoubleType<UChar, AllowTrailingJunk>(data, lengt
h, 0, parsedLength)); | |
| 1192 } | |
| 1193 | |
| 1194 const String& emptyString() | 923 const String& emptyString() |
| 1195 { | 924 { |
| 1196 DEFINE_STATIC_LOCAL(String, emptyString, (StringImpl::empty())); | 925 DEFINE_STATIC_LOCAL(String, emptyString, (StringImpl::empty())); |
| 1197 return emptyString; | 926 return emptyString; |
| 1198 } | 927 } |
| 1199 | 928 |
| 1200 const String& emptyString16Bit() | 929 const String& emptyString16Bit() |
| 1201 { | 930 { |
| 1202 DEFINE_STATIC_LOCAL(String, emptyString, (StringImpl::empty16Bit())); | 931 DEFINE_STATIC_LOCAL(String, emptyString, (StringImpl::empty16Bit())); |
| 1203 return emptyString; | 932 return emptyString; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1286 buffer.append('\0'); | 1015 buffer.append('\0'); |
| 1287 return buffer; | 1016 return buffer; |
| 1288 } | 1017 } |
| 1289 | 1018 |
| 1290 Vector<char> asciiDebug(String& string) | 1019 Vector<char> asciiDebug(String& string) |
| 1291 { | 1020 { |
| 1292 return asciiDebug(string.impl()); | 1021 return asciiDebug(string.impl()); |
| 1293 } | 1022 } |
| 1294 | 1023 |
| 1295 #endif | 1024 #endif |
| OLD | NEW |