@@ -43,6 +43,10 @@ public class FastDoubleParser(private val parserOptions: ParserOptions) {
43
43
44
44
private val parser = ConfigurableDoubleParser (/* symbols = */ setupNumberFormatSymbols(), /* ignoreCase = */ true )
45
45
46
+ // Fix for Java 8 RTL languages minus sign not being recognized
47
+ private val minusSignIsFormatSymbol =
48
+ Character .getType(localDecimalFormatSymbols.minusSign) == Character .FORMAT .toInt()
49
+
46
50
/* *
47
51
* Sets up the [NumberFormatSymbols] for the [ConfigurableDoubleParser] based on
48
52
* [localDecimalFormatSymbols] with fallbacks from [fallbackDecimalFormatSymbols].
@@ -177,6 +181,17 @@ public class FastDoubleParser(private val parserOptions: ParserOptions) {
177
181
): Double? {
178
182
if (parserOptions.useFastDoubleParser && charset in supportedFastCharsets) {
179
183
try {
184
+ // Fixes RTL minus sign not being recognized
185
+ if (minusSignIsFormatSymbol && ba.toString(charset).startsWith(localDecimalFormatSymbols.minusSign)) {
186
+ val localMinusSize = localDecimalFormatSymbols.minusSign.toString().toByteArray(charset).size
187
+ val fallbackMinusSize = fallbackDecimalFormatSymbols.minusSign.toString().toByteArray(charset).size
188
+ val newOffset = (localMinusSize - fallbackMinusSize).coerceAtLeast(0 )
189
+ val newBa = ba.copyOf()
190
+ fallbackDecimalFormatSymbols.minusSign.toString().toByteArray(charset)
191
+ .copyInto(destination = newBa, destinationOffset = newOffset)
192
+
193
+ return parser.parseDouble(newBa, newOffset, length - newOffset)
194
+ }
180
195
return parser.parseDouble(ba, offset, length)
181
196
} catch (e: Exception ) {
182
197
logger.debug(e) {
@@ -199,6 +214,15 @@ public class FastDoubleParser(private val parserOptions: ParserOptions) {
199
214
public fun parseOrNull (cs : CharSequence ): Double? {
200
215
if (parserOptions.useFastDoubleParser) {
201
216
try {
217
+ // Fixes RTL minus sign not being recognized
218
+ if (minusSignIsFormatSymbol && cs.startsWith(localDecimalFormatSymbols.minusSign)) {
219
+ val newCs = cs.toString().replaceFirst(
220
+ localDecimalFormatSymbols.minusSign,
221
+ fallbackDecimalFormatSymbols.minusSign,
222
+ )
223
+ return parser.parseDouble(newCs)
224
+ }
225
+
202
226
return parser.parseDouble(cs)
203
227
} catch (e: Exception ) {
204
228
logger.debug(e) {
@@ -219,6 +243,12 @@ public class FastDoubleParser(private val parserOptions: ParserOptions) {
219
243
public fun parseOrNull (ca : CharArray , offset : Int = 0, length : Int = ca.size): Double? {
220
244
if (parserOptions.useFastDoubleParser) {
221
245
try {
246
+ // Fixes RTL minus sign not being recognized.
247
+ if (minusSignIsFormatSymbol && ca.firstOrNull() == localDecimalFormatSymbols.minusSign) {
248
+ val newCa = ca.copyOf()
249
+ newCa[0 ] = fallbackDecimalFormatSymbols.minusSign
250
+ return parser.parseDouble(newCa, offset, length)
251
+ }
222
252
return parser.parseDouble(ca, offset, length)
223
253
} catch (e: Exception ) {
224
254
logger.debug(e) {
0 commit comments