quickfix_ruby 1.14.3.1 → 1.15.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/ext/quickfix/Acceptor.h +2 -0
  3. data/ext/quickfix/AtomicCount.h +82 -12
  4. data/ext/quickfix/DOMDocument.h +9 -7
  5. data/ext/quickfix/DataDictionary.cpp +77 -14
  6. data/ext/quickfix/DataDictionary.h +90 -16
  7. data/ext/quickfix/Dictionary.cpp +1 -2
  8. data/ext/quickfix/Exceptions.h +3 -5
  9. data/ext/quickfix/Field.h +83 -32
  10. data/ext/quickfix/FieldConvertors.cpp +93 -0
  11. data/ext/quickfix/FieldConvertors.h +129 -275
  12. data/ext/quickfix/FieldMap.cpp +53 -13
  13. data/ext/quickfix/FieldMap.h +200 -62
  14. data/ext/quickfix/FieldTypes.cpp +10 -10
  15. data/ext/quickfix/FieldTypes.h +293 -44
  16. data/ext/quickfix/FileLog.cpp +6 -10
  17. data/ext/quickfix/FileLog.h +4 -10
  18. data/ext/quickfix/FileStore.cpp +19 -6
  19. data/ext/quickfix/FileStore.h +4 -0
  20. data/ext/quickfix/FixFieldNumbers.h +1462 -1461
  21. data/ext/quickfix/FixFields.h +1462 -1461
  22. data/ext/quickfix/FixValues.h +3230 -3227
  23. data/ext/quickfix/HttpConnection.cpp +1 -1
  24. data/ext/quickfix/Initiator.cpp +7 -1
  25. data/ext/quickfix/Initiator.h +2 -0
  26. data/ext/quickfix/Log.h +6 -12
  27. data/ext/quickfix/Message.cpp +186 -57
  28. data/ext/quickfix/Message.h +109 -47
  29. data/ext/quickfix/MySQLConnection.h +1 -1
  30. data/ext/quickfix/PostgreSQLConnection.h +1 -1
  31. data/ext/quickfix/QuickfixRuby.cpp +79141 -77959
  32. data/ext/quickfix/QuickfixRuby.h +1 -1
  33. data/ext/quickfix/SSLSocketAcceptor.cpp +410 -0
  34. data/ext/quickfix/SSLSocketAcceptor.h +185 -0
  35. data/ext/quickfix/SSLSocketConnection.cpp +427 -0
  36. data/ext/quickfix/SSLSocketConnection.h +206 -0
  37. data/ext/quickfix/SSLSocketInitiator.cpp +485 -0
  38. data/ext/quickfix/SSLSocketInitiator.h +196 -0
  39. data/ext/quickfix/Session.cpp +113 -20
  40. data/ext/quickfix/Session.h +18 -4
  41. data/ext/quickfix/SessionFactory.cpp +10 -3
  42. data/ext/quickfix/SessionSettings.cpp +5 -3
  43. data/ext/quickfix/SessionSettings.h +97 -5
  44. data/ext/quickfix/Settings.cpp +72 -2
  45. data/ext/quickfix/Settings.h +3 -0
  46. data/ext/quickfix/SharedArray.h +140 -6
  47. data/ext/quickfix/SocketConnection.cpp +2 -2
  48. data/ext/quickfix/SocketConnector.cpp +5 -2
  49. data/ext/quickfix/SocketConnector.h +3 -2
  50. data/ext/quickfix/SocketInitiator.cpp +28 -4
  51. data/ext/quickfix/SocketInitiator.h +1 -1
  52. data/ext/quickfix/SocketMonitor.cpp +5 -5
  53. data/ext/quickfix/ThreadedSSLSocketAcceptor.cpp +455 -0
  54. data/ext/quickfix/ThreadedSSLSocketAcceptor.h +217 -0
  55. data/ext/quickfix/ThreadedSSLSocketConnection.cpp +404 -0
  56. data/ext/quickfix/ThreadedSSLSocketConnection.h +189 -0
  57. data/ext/quickfix/ThreadedSSLSocketInitiator.cpp +469 -0
  58. data/ext/quickfix/ThreadedSSLSocketInitiator.h +201 -0
  59. data/ext/quickfix/ThreadedSocketAcceptor.cpp +5 -1
  60. data/ext/quickfix/ThreadedSocketConnection.cpp +8 -2
  61. data/ext/quickfix/ThreadedSocketConnection.h +4 -1
  62. data/ext/quickfix/ThreadedSocketInitiator.cpp +24 -4
  63. data/ext/quickfix/ThreadedSocketInitiator.h +1 -1
  64. data/ext/quickfix/Utility.cpp +23 -1
  65. data/ext/quickfix/Utility.h +28 -2
  66. data/ext/quickfix/UtilitySSL.cpp +1733 -0
  67. data/ext/quickfix/UtilitySSL.h +277 -0
  68. data/ext/quickfix/config-all.h +10 -0
  69. data/ext/quickfix/dirent_windows.h +838 -0
  70. data/ext/quickfix/double-conversion/bignum-dtoa.cc +641 -0
  71. data/ext/quickfix/double-conversion/bignum-dtoa.h +84 -0
  72. data/ext/quickfix/double-conversion/bignum.cc +766 -0
  73. data/ext/quickfix/double-conversion/bignum.h +144 -0
  74. data/ext/quickfix/double-conversion/cached-powers.cc +176 -0
  75. data/ext/quickfix/double-conversion/cached-powers.h +64 -0
  76. data/ext/quickfix/double-conversion/diy-fp.cc +57 -0
  77. data/ext/quickfix/double-conversion/diy-fp.h +118 -0
  78. data/ext/quickfix/double-conversion/double-conversion.cc +994 -0
  79. data/ext/quickfix/double-conversion/double-conversion.h +543 -0
  80. data/ext/quickfix/double-conversion/fast-dtoa.cc +665 -0
  81. data/ext/quickfix/double-conversion/fast-dtoa.h +88 -0
  82. data/ext/quickfix/double-conversion/fixed-dtoa.cc +404 -0
  83. data/ext/quickfix/double-conversion/fixed-dtoa.h +56 -0
  84. data/ext/quickfix/double-conversion/ieee.h +402 -0
  85. data/ext/quickfix/double-conversion/strtod.cc +557 -0
  86. data/ext/quickfix/double-conversion/strtod.h +45 -0
  87. data/ext/quickfix/double-conversion/utils.h +372 -0
  88. data/ext/quickfix/stdint_msvc.h +254 -0
  89. data/lib/quickfix44.rb +3329 -10
  90. data/lib/quickfix50.rb +6649 -81
  91. data/lib/quickfix50sp1.rb +8054 -142
  92. data/lib/quickfix50sp2.rb +10900 -234
  93. data/lib/quickfix_fields.rb +7662 -7649
  94. data/spec/FIX40.xml +28 -28
  95. data/spec/FIX41.xml +29 -29
  96. data/spec/FIX42.xml +47 -47
  97. data/spec/FIX43.xml +148 -148
  98. data/spec/FIX44.xml +1078 -1081
  99. data/spec/FIX50.xml +1292 -1289
  100. data/spec/FIX50SP1.xml +1811 -1802
  101. data/spec/FIX50SP2.xml +1948 -1939
  102. data/spec/FIXT11.xml +5 -8
  103. data/test/test_FieldBaseTestCase.rb +1 -1
  104. data/test/test_MessageTestCase.rb +2 -2
  105. metadata +42 -6
@@ -0,0 +1,994 @@
1
+ // Copyright 2010 the V8 project authors. All rights reserved.
2
+ // Redistribution and use in source and binary forms, with or without
3
+ // modification, are permitted provided that the following conditions are
4
+ // met:
5
+ //
6
+ // * Redistributions of source code must retain the above copyright
7
+ // notice, this list of conditions and the following disclaimer.
8
+ // * Redistributions in binary form must reproduce the above
9
+ // copyright notice, this list of conditions and the following
10
+ // disclaimer in the documentation and/or other materials provided
11
+ // with the distribution.
12
+ // * Neither the name of Google Inc. nor the names of its
13
+ // contributors may be used to endorse or promote products derived
14
+ // from this software without specific prior written permission.
15
+ //
16
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
28
+ #include <limits.h>
29
+ #include <math.h>
30
+
31
+ #include "double-conversion/double-conversion.h"
32
+
33
+ #include "double-conversion/bignum-dtoa.h"
34
+ #include "double-conversion/fast-dtoa.h"
35
+ #include "double-conversion/fixed-dtoa.h"
36
+ #include "double-conversion/ieee.h"
37
+ #include "double-conversion/strtod.h"
38
+ #include "double-conversion/utils.h"
39
+
40
+ namespace double_conversion {
41
+
42
+ const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
43
+ int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
44
+ static DoubleToStringConverter converter(flags,
45
+ "Infinity",
46
+ "NaN",
47
+ 'e',
48
+ -6, 21,
49
+ 6, 0);
50
+ return converter;
51
+ }
52
+
53
+
54
+ bool DoubleToStringConverter::HandleSpecialValues(
55
+ double value,
56
+ StringBuilder* result_builder) const {
57
+ Double double_inspect(value);
58
+ if (double_inspect.IsInfinite()) {
59
+ if (infinity_symbol_ == NULL) return false;
60
+ if (value < 0) {
61
+ result_builder->AddCharacter('-');
62
+ }
63
+ result_builder->AddString(infinity_symbol_);
64
+ return true;
65
+ }
66
+ if (double_inspect.IsNan()) {
67
+ if (nan_symbol_ == NULL) return false;
68
+ result_builder->AddString(nan_symbol_);
69
+ return true;
70
+ }
71
+ return false;
72
+ }
73
+
74
+
75
+ void DoubleToStringConverter::CreateExponentialRepresentation(
76
+ const char* decimal_digits,
77
+ int length,
78
+ int exponent,
79
+ StringBuilder* result_builder) const {
80
+ ASSERT(length != 0);
81
+ result_builder->AddCharacter(decimal_digits[0]);
82
+ if (length != 1) {
83
+ result_builder->AddCharacter('.');
84
+ result_builder->AddSubstring(&decimal_digits[1], length-1);
85
+ }
86
+ result_builder->AddCharacter(exponent_character_);
87
+ if (exponent < 0) {
88
+ result_builder->AddCharacter('-');
89
+ exponent = -exponent;
90
+ } else {
91
+ if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
92
+ result_builder->AddCharacter('+');
93
+ }
94
+ }
95
+ if (exponent == 0) {
96
+ result_builder->AddCharacter('0');
97
+ return;
98
+ }
99
+ ASSERT(exponent < 1e4);
100
+ const int kMaxExponentLength = 5;
101
+ char buffer[kMaxExponentLength + 1];
102
+ buffer[kMaxExponentLength] = '\0';
103
+ int first_char_pos = kMaxExponentLength;
104
+ while (exponent > 0) {
105
+ buffer[--first_char_pos] = '0' + (exponent % 10);
106
+ exponent /= 10;
107
+ }
108
+ result_builder->AddSubstring(&buffer[first_char_pos],
109
+ kMaxExponentLength - first_char_pos);
110
+ }
111
+
112
+
113
+ void DoubleToStringConverter::CreateDecimalRepresentation(
114
+ const char* decimal_digits,
115
+ int length,
116
+ int decimal_point,
117
+ int digits_after_point,
118
+ StringBuilder* result_builder) const {
119
+ // Create a representation that is padded with zeros if needed.
120
+ if (decimal_point <= 0) {
121
+ // "0.00000decimal_rep".
122
+ result_builder->AddCharacter('0');
123
+ if (digits_after_point > 0) {
124
+ result_builder->AddCharacter('.');
125
+ result_builder->AddPadding('0', -decimal_point);
126
+ ASSERT(length <= digits_after_point - (-decimal_point));
127
+ result_builder->AddSubstring(decimal_digits, length);
128
+ int remaining_digits = digits_after_point - (-decimal_point) - length;
129
+ result_builder->AddPadding('0', remaining_digits);
130
+ }
131
+ } else if (decimal_point >= length) {
132
+ // "decimal_rep0000.00000" or "decimal_rep.0000"
133
+ result_builder->AddSubstring(decimal_digits, length);
134
+ result_builder->AddPadding('0', decimal_point - length);
135
+ if (digits_after_point > 0) {
136
+ result_builder->AddCharacter('.');
137
+ result_builder->AddPadding('0', digits_after_point);
138
+ }
139
+ } else {
140
+ // "decima.l_rep000"
141
+ ASSERT(digits_after_point > 0);
142
+ result_builder->AddSubstring(decimal_digits, decimal_point);
143
+ result_builder->AddCharacter('.');
144
+ ASSERT(length - decimal_point <= digits_after_point);
145
+ result_builder->AddSubstring(&decimal_digits[decimal_point],
146
+ length - decimal_point);
147
+ int remaining_digits = digits_after_point - (length - decimal_point);
148
+ result_builder->AddPadding('0', remaining_digits);
149
+ }
150
+ if (digits_after_point == 0) {
151
+ if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
152
+ result_builder->AddCharacter('.');
153
+ }
154
+ if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
155
+ result_builder->AddCharacter('0');
156
+ }
157
+ }
158
+ }
159
+
160
+
161
+ bool DoubleToStringConverter::ToShortestIeeeNumber(
162
+ double value,
163
+ StringBuilder* result_builder,
164
+ DoubleToStringConverter::DtoaMode mode) const {
165
+ ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE);
166
+ if (Double(value).IsSpecial()) {
167
+ return HandleSpecialValues(value, result_builder);
168
+ }
169
+
170
+ int decimal_point;
171
+ bool sign;
172
+ const int kDecimalRepCapacity = kBase10MaximalLength + 1;
173
+ char decimal_rep[kDecimalRepCapacity];
174
+ int decimal_rep_length;
175
+
176
+ DoubleToAscii(value, mode, 0, decimal_rep, kDecimalRepCapacity,
177
+ &sign, &decimal_rep_length, &decimal_point);
178
+
179
+ bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
180
+ if (sign && (value != 0.0 || !unique_zero)) {
181
+ result_builder->AddCharacter('-');
182
+ }
183
+
184
+ int exponent = decimal_point - 1;
185
+ if ((decimal_in_shortest_low_ <= exponent) &&
186
+ (exponent < decimal_in_shortest_high_)) {
187
+ CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
188
+ decimal_point,
189
+ Max(0, decimal_rep_length - decimal_point),
190
+ result_builder);
191
+ } else {
192
+ CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
193
+ result_builder);
194
+ }
195
+ return true;
196
+ }
197
+
198
+
199
+ bool DoubleToStringConverter::ToFixed(double value,
200
+ int requested_digits,
201
+ StringBuilder* result_builder) const {
202
+ ASSERT(kMaxFixedDigitsBeforePoint == 60);
203
+ const double kFirstNonFixed = 1e60;
204
+
205
+ if (Double(value).IsSpecial()) {
206
+ return HandleSpecialValues(value, result_builder);
207
+ }
208
+
209
+ if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
210
+ if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
211
+
212
+ // Find a sufficiently precise decimal representation of n.
213
+ int decimal_point;
214
+ bool sign;
215
+ // Add space for the '\0' byte.
216
+ const int kDecimalRepCapacity =
217
+ kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
218
+ char decimal_rep[kDecimalRepCapacity];
219
+ int decimal_rep_length;
220
+ DoubleToAscii(value, FIXED, requested_digits,
221
+ decimal_rep, kDecimalRepCapacity,
222
+ &sign, &decimal_rep_length, &decimal_point);
223
+
224
+ bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
225
+ if (sign && (value != 0.0 || !unique_zero)) {
226
+ result_builder->AddCharacter('-');
227
+ }
228
+
229
+ CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
230
+ requested_digits, result_builder);
231
+ return true;
232
+ }
233
+
234
+
235
+ bool DoubleToStringConverter::ToExponential(
236
+ double value,
237
+ int requested_digits,
238
+ StringBuilder* result_builder) const {
239
+ if (Double(value).IsSpecial()) {
240
+ return HandleSpecialValues(value, result_builder);
241
+ }
242
+
243
+ if (requested_digits < -1) return false;
244
+ if (requested_digits > kMaxExponentialDigits) return false;
245
+
246
+ int decimal_point;
247
+ bool sign;
248
+ // Add space for digit before the decimal point and the '\0' character.
249
+ const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
250
+ ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
251
+ char decimal_rep[kDecimalRepCapacity];
252
+ int decimal_rep_length;
253
+
254
+ if (requested_digits == -1) {
255
+ DoubleToAscii(value, SHORTEST, 0,
256
+ decimal_rep, kDecimalRepCapacity,
257
+ &sign, &decimal_rep_length, &decimal_point);
258
+ } else {
259
+ DoubleToAscii(value, PRECISION, requested_digits + 1,
260
+ decimal_rep, kDecimalRepCapacity,
261
+ &sign, &decimal_rep_length, &decimal_point);
262
+ ASSERT(decimal_rep_length <= requested_digits + 1);
263
+
264
+ for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
265
+ decimal_rep[i] = '0';
266
+ }
267
+ decimal_rep_length = requested_digits + 1;
268
+ }
269
+
270
+ bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
271
+ if (sign && (value != 0.0 || !unique_zero)) {
272
+ result_builder->AddCharacter('-');
273
+ }
274
+
275
+ int exponent = decimal_point - 1;
276
+ CreateExponentialRepresentation(decimal_rep,
277
+ decimal_rep_length,
278
+ exponent,
279
+ result_builder);
280
+ return true;
281
+ }
282
+
283
+
284
+ bool DoubleToStringConverter::ToPrecision(double value,
285
+ int precision,
286
+ StringBuilder* result_builder) const {
287
+ if (Double(value).IsSpecial()) {
288
+ return HandleSpecialValues(value, result_builder);
289
+ }
290
+
291
+ if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
292
+ return false;
293
+ }
294
+
295
+ // Find a sufficiently precise decimal representation of n.
296
+ int decimal_point;
297
+ bool sign;
298
+ // Add one for the terminating null character.
299
+ const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
300
+ char decimal_rep[kDecimalRepCapacity];
301
+ int decimal_rep_length;
302
+
303
+ DoubleToAscii(value, PRECISION, precision,
304
+ decimal_rep, kDecimalRepCapacity,
305
+ &sign, &decimal_rep_length, &decimal_point);
306
+ ASSERT(decimal_rep_length <= precision);
307
+
308
+ bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
309
+ if (sign && (value != 0.0 || !unique_zero)) {
310
+ result_builder->AddCharacter('-');
311
+ }
312
+
313
+ // The exponent if we print the number as x.xxeyyy. That is with the
314
+ // decimal point after the first digit.
315
+ int exponent = decimal_point - 1;
316
+
317
+ int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
318
+ if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
319
+ (decimal_point - precision + extra_zero >
320
+ max_trailing_padding_zeroes_in_precision_mode_)) {
321
+ // Fill buffer to contain 'precision' digits.
322
+ // Usually the buffer is already at the correct length, but 'DoubleToAscii'
323
+ // is allowed to return less characters.
324
+ for (int i = decimal_rep_length; i < precision; ++i) {
325
+ decimal_rep[i] = '0';
326
+ }
327
+
328
+ CreateExponentialRepresentation(decimal_rep,
329
+ precision,
330
+ exponent,
331
+ result_builder);
332
+ } else {
333
+ CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
334
+ Max(0, precision - decimal_point),
335
+ result_builder);
336
+ }
337
+ return true;
338
+ }
339
+
340
+
341
+ static BignumDtoaMode DtoaToBignumDtoaMode(
342
+ DoubleToStringConverter::DtoaMode dtoa_mode) {
343
+ switch (dtoa_mode) {
344
+ case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST;
345
+ case DoubleToStringConverter::SHORTEST_SINGLE:
346
+ return BIGNUM_DTOA_SHORTEST_SINGLE;
347
+ case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED;
348
+ case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
349
+ default:
350
+ UNREACHABLE();
351
+ }
352
+
353
+ return BIGNUM_DTOA_SHORTEST;
354
+ }
355
+
356
+
357
+ void DoubleToStringConverter::DoubleToAscii(double v,
358
+ DtoaMode mode,
359
+ int requested_digits,
360
+ char* buffer,
361
+ int buffer_length,
362
+ bool* sign,
363
+ int* length,
364
+ int* point) {
365
+ Vector<char> vector(buffer, buffer_length);
366
+ ASSERT(!Double(v).IsSpecial());
367
+ ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0);
368
+
369
+ if (Double(v).Sign() < 0) {
370
+ *sign = true;
371
+ v = -v;
372
+ } else {
373
+ *sign = false;
374
+ }
375
+
376
+ if (mode == PRECISION && requested_digits == 0) {
377
+ vector[0] = '\0';
378
+ *length = 0;
379
+ return;
380
+ }
381
+
382
+ if (v == 0) {
383
+ vector[0] = '0';
384
+ vector[1] = '\0';
385
+ *length = 1;
386
+ *point = 1;
387
+ return;
388
+ }
389
+
390
+ bool fast_worked;
391
+ switch (mode) {
392
+ case SHORTEST:
393
+ fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
394
+ break;
395
+ case SHORTEST_SINGLE:
396
+ fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0,
397
+ vector, length, point);
398
+ break;
399
+ case FIXED:
400
+ fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
401
+ break;
402
+ case PRECISION:
403
+ fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
404
+ vector, length, point);
405
+ break;
406
+ default:
407
+ fast_worked = false;
408
+ UNREACHABLE();
409
+ }
410
+ if (fast_worked) return;
411
+
412
+ // If the fast dtoa didn't succeed use the slower bignum version.
413
+ BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
414
+ BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
415
+ vector[*length] = '\0';
416
+ }
417
+
418
+
419
+ // Consumes the given substring from the iterator.
420
+ // Returns false, if the substring does not match.
421
+ template <class Iterator>
422
+ static bool ConsumeSubString(Iterator* current,
423
+ Iterator end,
424
+ const char* substring) {
425
+ ASSERT(**current == *substring);
426
+ for (substring++; *substring != '\0'; substring++) {
427
+ ++*current;
428
+ if (*current == end || **current != *substring) return false;
429
+ }
430
+ ++*current;
431
+ return true;
432
+ }
433
+
434
+
435
+ // Maximum number of significant digits in decimal representation.
436
+ // The longest possible double in decimal representation is
437
+ // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
438
+ // (768 digits). If we parse a number whose first digits are equal to a
439
+ // mean of 2 adjacent doubles (that could have up to 769 digits) the result
440
+ // must be rounded to the bigger one unless the tail consists of zeros, so
441
+ // we don't need to preserve all the digits.
442
+ const int kMaxSignificantDigits = 772;
443
+
444
+
445
+ static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 };
446
+ static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7);
447
+
448
+
449
+ static const uc16 kWhitespaceTable16[] = {
450
+ 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
451
+ 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
452
+ };
453
+ static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16);
454
+
455
+ #if defined(__SUNPRO_CC)
456
+ bool isWhitespace(int x) {
457
+ #else
458
+ static bool isWhitespace(int x) {
459
+ #endif
460
+ if (x < 128) {
461
+ for (int i = 0; i < kWhitespaceTable7Length; i++) {
462
+ if (kWhitespaceTable7[i] == x) return true;
463
+ }
464
+ } else {
465
+ for (int i = 0; i < kWhitespaceTable16Length; i++) {
466
+ if (kWhitespaceTable16[i] == x) return true;
467
+ }
468
+ }
469
+ return false;
470
+ }
471
+
472
+
473
+ // Returns true if a nonspace found and false if the end has reached.
474
+ template <class Iterator>
475
+ static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
476
+ while (*current != end) {
477
+ if (!isWhitespace(**current)) return true;
478
+ ++*current;
479
+ }
480
+ return false;
481
+ }
482
+
483
+ #if defined(__SUNPRO_CC)
484
+ bool isDigit(int x, int radix) {
485
+ #else
486
+ static bool isDigit(int x, int radix) {
487
+ #endif
488
+ return (x >= '0' && x <= '9' && x < '0' + radix)
489
+ || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
490
+ || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
491
+ }
492
+
493
+
494
+ static double SignedZero(bool sign) {
495
+ return sign ? -0.0 : 0.0;
496
+ }
497
+
498
+
499
+ // Returns true if 'c' is a decimal digit that is valid for the given radix.
500
+ //
501
+ // The function is small and could be inlined, but VS2012 emitted a warning
502
+ // because it constant-propagated the radix and concluded that the last
503
+ // condition was always true. By moving it into a separate function the
504
+ // compiler wouldn't warn anymore.
505
+ #if _MSC_VER
506
+ #pragma optimize("",off)
507
+ static bool IsDecimalDigitForRadix(int c, int radix) {
508
+ return '0' <= c && c <= '9' && (c - '0') < radix;
509
+ }
510
+ #pragma optimize("",on)
511
+ #else
512
+ static bool inline IsDecimalDigitForRadix(int c, int radix) {
513
+ return '0' <= c && c <= '9' && (c - '0') < radix;
514
+ }
515
+ #endif
516
+ // Returns true if 'c' is a character digit that is valid for the given radix.
517
+ // The 'a_character' should be 'a' or 'A'.
518
+ //
519
+ // The function is small and could be inlined, but VS2012 emitted a warning
520
+ // because it constant-propagated the radix and concluded that the first
521
+ // condition was always false. By moving it into a separate function the
522
+ // compiler wouldn't warn anymore.
523
+ #if defined(__SUNPRO_CC)
524
+ bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
525
+ #else
526
+ static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
527
+ #endif
528
+ return radix > 10 && c >= a_character && c < a_character + radix - 10;
529
+ }
530
+
531
+
532
+ // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
533
+ template <int radix_log_2, class Iterator>
534
+ static double RadixStringToIeee(Iterator* current,
535
+ Iterator end,
536
+ bool sign,
537
+ bool allow_trailing_junk,
538
+ double junk_string_value,
539
+ bool read_as_double,
540
+ bool* result_is_junk) {
541
+ ASSERT(*current != end);
542
+
543
+ const int kDoubleSize = Double::kSignificandSize;
544
+ const int kSingleSize = Single::kSignificandSize;
545
+ const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
546
+
547
+ *result_is_junk = true;
548
+
549
+ // Skip leading 0s.
550
+ while (**current == '0') {
551
+ ++(*current);
552
+ if (*current == end) {
553
+ *result_is_junk = false;
554
+ return SignedZero(sign);
555
+ }
556
+ }
557
+
558
+ int64_t number = 0;
559
+ int exponent = 0;
560
+ const int radix = (1 << radix_log_2);
561
+
562
+ do {
563
+ int digit;
564
+ if (IsDecimalDigitForRadix(**current, radix)) {
565
+ digit = static_cast<char>(**current) - '0';
566
+ } else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
567
+ digit = static_cast<char>(**current) - 'a' + 10;
568
+ } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
569
+ digit = static_cast<char>(**current) - 'A' + 10;
570
+ } else {
571
+ if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
572
+ break;
573
+ } else {
574
+ return junk_string_value;
575
+ }
576
+ }
577
+
578
+ number = number * radix + digit;
579
+ int overflow = static_cast<int>(number >> kSignificandSize);
580
+ if (overflow != 0) {
581
+ // Overflow occurred. Need to determine which direction to round the
582
+ // result.
583
+ int overflow_bits_count = 1;
584
+ while (overflow > 1) {
585
+ overflow_bits_count++;
586
+ overflow >>= 1;
587
+ }
588
+
589
+ int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
590
+ int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
591
+ number >>= overflow_bits_count;
592
+ exponent = overflow_bits_count;
593
+
594
+ bool zero_tail = true;
595
+ for (;;) {
596
+ ++(*current);
597
+ if (*current == end || !isDigit(**current, radix)) break;
598
+ zero_tail = zero_tail && **current == '0';
599
+ exponent += radix_log_2;
600
+ }
601
+
602
+ if (!allow_trailing_junk && AdvanceToNonspace(current, end)) {
603
+ return junk_string_value;
604
+ }
605
+
606
+ int middle_value = (1 << (overflow_bits_count - 1));
607
+ if (dropped_bits > middle_value) {
608
+ number++; // Rounding up.
609
+ } else if (dropped_bits == middle_value) {
610
+ // Rounding to even to consistency with decimals: half-way case rounds
611
+ // up if significant part is odd and down otherwise.
612
+ if ((number & 1) != 0 || !zero_tail) {
613
+ number++; // Rounding up.
614
+ }
615
+ }
616
+
617
+ // Rounding up may cause overflow.
618
+ if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
619
+ exponent++;
620
+ number >>= 1;
621
+ }
622
+ break;
623
+ }
624
+ ++(*current);
625
+ } while (*current != end);
626
+
627
+ ASSERT(number < ((int64_t)1 << kSignificandSize));
628
+ ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
629
+
630
+ *result_is_junk = false;
631
+
632
+ if (exponent == 0) {
633
+ if (sign) {
634
+ if (number == 0) return -0.0;
635
+ number = -number;
636
+ }
637
+ return static_cast<double>(number);
638
+ }
639
+
640
+ ASSERT(number != 0);
641
+ return Double(DiyFp(number, exponent)).value();
642
+ }
643
+
644
+
645
+ template <class Iterator>
646
+ double StringToDoubleConverter::StringToIeee(
647
+ Iterator input,
648
+ int length,
649
+ bool read_as_double,
650
+ int* processed_characters_count) const {
651
+ Iterator current = input;
652
+ Iterator end = input + length;
653
+
654
+ *processed_characters_count = 0;
655
+
656
+ const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
657
+ const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
658
+ const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
659
+ const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
660
+
661
+ // To make sure that iterator dereferencing is valid the following
662
+ // convention is used:
663
+ // 1. Each '++current' statement is followed by check for equality to 'end'.
664
+ // 2. If AdvanceToNonspace returned false then current == end.
665
+ // 3. If 'current' becomes equal to 'end' the function returns or goes to
666
+ // 'parsing_done'.
667
+ // 4. 'current' is not dereferenced after the 'parsing_done' label.
668
+ // 5. Code before 'parsing_done' may rely on 'current != end'.
669
+ if (current == end) return empty_string_value_;
670
+
671
+ if (allow_leading_spaces || allow_trailing_spaces) {
672
+ if (!AdvanceToNonspace(&current, end)) {
673
+ *processed_characters_count = static_cast<int>(current - input);
674
+ return empty_string_value_;
675
+ }
676
+ if (!allow_leading_spaces && (input != current)) {
677
+ // No leading spaces allowed, but AdvanceToNonspace moved forward.
678
+ return junk_string_value_;
679
+ }
680
+ }
681
+
682
+ // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
683
+ const int kBufferSize = kMaxSignificantDigits + 10;
684
+ char buffer[kBufferSize]; // NOLINT: size is known at compile time.
685
+ int buffer_pos = 0;
686
+
687
+ // Exponent will be adjusted if insignificant digits of the integer part
688
+ // or insignificant leading zeros of the fractional part are dropped.
689
+ int exponent = 0;
690
+ int significant_digits = 0;
691
+ int insignificant_digits = 0;
692
+ bool nonzero_digit_dropped = false;
693
+
694
+ bool sign = false;
695
+
696
+ if (*current == '+' || *current == '-') {
697
+ sign = (*current == '-');
698
+ ++current;
699
+ Iterator next_non_space = current;
700
+ // Skip following spaces (if allowed).
701
+ if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
702
+ if (!allow_spaces_after_sign && (current != next_non_space)) {
703
+ return junk_string_value_;
704
+ }
705
+ current = next_non_space;
706
+ }
707
+
708
+ if (infinity_symbol_ != NULL) {
709
+ if (*current == infinity_symbol_[0]) {
710
+ if (!ConsumeSubString(&current, end, infinity_symbol_)) {
711
+ return junk_string_value_;
712
+ }
713
+
714
+ if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
715
+ return junk_string_value_;
716
+ }
717
+ if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
718
+ return junk_string_value_;
719
+ }
720
+
721
+ ASSERT(buffer_pos == 0);
722
+ *processed_characters_count = static_cast<int>(current - input);
723
+ return sign ? -Double::Infinity() : Double::Infinity();
724
+ }
725
+ }
726
+
727
+ if (nan_symbol_ != NULL) {
728
+ if (*current == nan_symbol_[0]) {
729
+ if (!ConsumeSubString(&current, end, nan_symbol_)) {
730
+ return junk_string_value_;
731
+ }
732
+
733
+ if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
734
+ return junk_string_value_;
735
+ }
736
+ if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
737
+ return junk_string_value_;
738
+ }
739
+
740
+ ASSERT(buffer_pos == 0);
741
+ *processed_characters_count = static_cast<int>(current - input);
742
+ return sign ? -Double::NaN() : Double::NaN();
743
+ }
744
+ }
745
+
746
+ bool leading_zero = false;
747
+ if (*current == '0') {
748
+ ++current;
749
+ if (current == end) {
750
+ *processed_characters_count = static_cast<int>(current - input);
751
+ return SignedZero(sign);
752
+ }
753
+
754
+ leading_zero = true;
755
+
756
+ // It could be hexadecimal value.
757
+ if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
758
+ ++current;
759
+ if (current == end || !isDigit(*current, 16)) {
760
+ return junk_string_value_; // "0x".
761
+ }
762
+
763
+ bool result_is_junk;
764
+ double result = RadixStringToIeee<4>(&current,
765
+ end,
766
+ sign,
767
+ allow_trailing_junk,
768
+ junk_string_value_,
769
+ read_as_double,
770
+ &result_is_junk);
771
+ if (!result_is_junk) {
772
+ if (allow_trailing_spaces) AdvanceToNonspace(&current, end);
773
+ *processed_characters_count = static_cast<int>(current - input);
774
+ }
775
+ return result;
776
+ }
777
+
778
+ // Ignore leading zeros in the integer part.
779
+ while (*current == '0') {
780
+ ++current;
781
+ if (current == end) {
782
+ *processed_characters_count = static_cast<int>(current - input);
783
+ return SignedZero(sign);
784
+ }
785
+ }
786
+ }
787
+
788
+ bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
789
+
790
+ // Copy significant digits of the integer part (if any) to the buffer.
791
+ while (*current >= '0' && *current <= '9') {
792
+ if (significant_digits < kMaxSignificantDigits) {
793
+ ASSERT(buffer_pos < kBufferSize);
794
+ buffer[buffer_pos++] = static_cast<char>(*current);
795
+ significant_digits++;
796
+ // Will later check if it's an octal in the buffer.
797
+ } else {
798
+ insignificant_digits++; // Move the digit into the exponential part.
799
+ nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
800
+ }
801
+ octal = octal && *current < '8';
802
+ ++current;
803
+ if (current == end) goto parsing_done;
804
+ }
805
+
806
+ if (significant_digits == 0) {
807
+ octal = false;
808
+ }
809
+
810
+ if (*current == '.') {
811
+ if (octal && !allow_trailing_junk) return junk_string_value_;
812
+ if (octal) goto parsing_done;
813
+
814
+ ++current;
815
+ if (current == end) {
816
+ if (significant_digits == 0 && !leading_zero) {
817
+ return junk_string_value_;
818
+ } else {
819
+ goto parsing_done;
820
+ }
821
+ }
822
+
823
+ if (significant_digits == 0) {
824
+ // octal = false;
825
+ // Integer part consists of 0 or is absent. Significant digits start after
826
+ // leading zeros (if any).
827
+ while (*current == '0') {
828
+ ++current;
829
+ if (current == end) {
830
+ *processed_characters_count = static_cast<int>(current - input);
831
+ return SignedZero(sign);
832
+ }
833
+ exponent--; // Move this 0 into the exponent.
834
+ }
835
+ }
836
+
837
+ // There is a fractional part.
838
+ // We don't emit a '.', but adjust the exponent instead.
839
+ while (*current >= '0' && *current <= '9') {
840
+ if (significant_digits < kMaxSignificantDigits) {
841
+ ASSERT(buffer_pos < kBufferSize);
842
+ buffer[buffer_pos++] = static_cast<char>(*current);
843
+ significant_digits++;
844
+ exponent--;
845
+ } else {
846
+ // Ignore insignificant digits in the fractional part.
847
+ nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
848
+ }
849
+ ++current;
850
+ if (current == end) goto parsing_done;
851
+ }
852
+ }
853
+
854
+ if (!leading_zero && exponent == 0 && significant_digits == 0) {
855
+ // If leading_zeros is true then the string contains zeros.
856
+ // If exponent < 0 then string was [+-]\.0*...
857
+ // If significant_digits != 0 the string is not equal to 0.
858
+ // Otherwise there are no digits in the string.
859
+ return junk_string_value_;
860
+ }
861
+
862
+ // Parse exponential part.
863
+ if (*current == 'e' || *current == 'E') {
864
+ if (octal && !allow_trailing_junk) return junk_string_value_;
865
+ if (octal) goto parsing_done;
866
+ ++current;
867
+ if (current == end) {
868
+ if (allow_trailing_junk) {
869
+ goto parsing_done;
870
+ } else {
871
+ return junk_string_value_;
872
+ }
873
+ }
874
+ char exponen_sign = '+';
875
+ if (*current == '+' || *current == '-') {
876
+ exponen_sign = static_cast<char>(*current);
877
+ ++current;
878
+ if (current == end) {
879
+ if (allow_trailing_junk) {
880
+ goto parsing_done;
881
+ } else {
882
+ return junk_string_value_;
883
+ }
884
+ }
885
+ }
886
+
887
+ if (current == end || *current < '0' || *current > '9') {
888
+ if (allow_trailing_junk) {
889
+ goto parsing_done;
890
+ } else {
891
+ return junk_string_value_;
892
+ }
893
+ }
894
+
895
+ const int max_exponent = INT_MAX / 2;
896
+ ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
897
+ int num = 0;
898
+ do {
899
+ // Check overflow.
900
+ int digit = *current - '0';
901
+ if (num >= max_exponent / 10
902
+ && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
903
+ num = max_exponent;
904
+ } else {
905
+ num = num * 10 + digit;
906
+ }
907
+ ++current;
908
+ } while (current != end && *current >= '0' && *current <= '9');
909
+
910
+ exponent += (exponen_sign == '-' ? -num : num);
911
+ }
912
+
913
+ if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
914
+ return junk_string_value_;
915
+ }
916
+ if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
917
+ return junk_string_value_;
918
+ }
919
+ if (allow_trailing_spaces) {
920
+ AdvanceToNonspace(&current, end);
921
+ }
922
+
923
+ parsing_done:
924
+ exponent += insignificant_digits;
925
+
926
+ if (octal) {
927
+ double result;
928
+ bool result_is_junk;
929
+ char* start = buffer;
930
+ result = RadixStringToIeee<3>(&start,
931
+ buffer + buffer_pos,
932
+ sign,
933
+ allow_trailing_junk,
934
+ junk_string_value_,
935
+ read_as_double,
936
+ &result_is_junk);
937
+ ASSERT(!result_is_junk);
938
+ *processed_characters_count = static_cast<int>(current - input);
939
+ return result;
940
+ }
941
+
942
+ if (nonzero_digit_dropped) {
943
+ buffer[buffer_pos++] = '1';
944
+ exponent--;
945
+ }
946
+
947
+ ASSERT(buffer_pos < kBufferSize);
948
+ buffer[buffer_pos] = '\0';
949
+
950
+ double converted;
951
+ if (read_as_double) {
952
+ converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
953
+ } else {
954
+ converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
955
+ }
956
+ *processed_characters_count = static_cast<int>(current - input);
957
+ return sign? -converted: converted;
958
+ }
959
+
960
+
961
+ double StringToDoubleConverter::StringToDouble(
962
+ const char* buffer,
963
+ int length,
964
+ int* processed_characters_count) const {
965
+ return StringToIeee(buffer, length, true, processed_characters_count);
966
+ }
967
+
968
+
969
+ double StringToDoubleConverter::StringToDouble(
970
+ const uc16* buffer,
971
+ int length,
972
+ int* processed_characters_count) const {
973
+ return StringToIeee(buffer, length, true, processed_characters_count);
974
+ }
975
+
976
+
977
+ float StringToDoubleConverter::StringToFloat(
978
+ const char* buffer,
979
+ int length,
980
+ int* processed_characters_count) const {
981
+ return static_cast<float>(StringToIeee(buffer, length, false,
982
+ processed_characters_count));
983
+ }
984
+
985
+
986
+ float StringToDoubleConverter::StringToFloat(
987
+ const uc16* buffer,
988
+ int length,
989
+ int* processed_characters_count) const {
990
+ return static_cast<float>(StringToIeee(buffer, length, false,
991
+ processed_characters_count));
992
+ }
993
+
994
+ } // namespace double_conversion