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,88 @@
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
+ #ifndef DOUBLE_CONVERSION_FAST_DTOA_H_
29
+ #define DOUBLE_CONVERSION_FAST_DTOA_H_
30
+
31
+ #include "double-conversion/utils.h"
32
+
33
+ namespace double_conversion {
34
+
35
+ enum FastDtoaMode {
36
+ // Computes the shortest representation of the given input. The returned
37
+ // result will be the most accurate number of this length. Longer
38
+ // representations might be more accurate.
39
+ FAST_DTOA_SHORTEST,
40
+ // Same as FAST_DTOA_SHORTEST but for single-precision floats.
41
+ FAST_DTOA_SHORTEST_SINGLE,
42
+ // Computes a representation where the precision (number of digits) is
43
+ // given as input. The precision is independent of the decimal point.
44
+ FAST_DTOA_PRECISION
45
+ };
46
+
47
+ // FastDtoa will produce at most kFastDtoaMaximalLength digits. This does not
48
+ // include the terminating '\0' character.
49
+ static const int kFastDtoaMaximalLength = 17;
50
+ // Same for single-precision numbers.
51
+ static const int kFastDtoaMaximalSingleLength = 9;
52
+
53
+ // Provides a decimal representation of v.
54
+ // The result should be interpreted as buffer * 10^(point - length).
55
+ //
56
+ // Precondition:
57
+ // * v must be a strictly positive finite double.
58
+ //
59
+ // Returns true if it succeeds, otherwise the result can not be trusted.
60
+ // There will be *length digits inside the buffer followed by a null terminator.
61
+ // If the function returns true and mode equals
62
+ // - FAST_DTOA_SHORTEST, then
63
+ // the parameter requested_digits is ignored.
64
+ // The result satisfies
65
+ // v == (double) (buffer * 10^(point - length)).
66
+ // The digits in the buffer are the shortest representation possible. E.g.
67
+ // if 0.099999999999 and 0.1 represent the same double then "1" is returned
68
+ // with point = 0.
69
+ // The last digit will be closest to the actual v. That is, even if several
70
+ // digits might correctly yield 'v' when read again, the buffer will contain
71
+ // the one closest to v.
72
+ // - FAST_DTOA_PRECISION, then
73
+ // the buffer contains requested_digits digits.
74
+ // the difference v - (buffer * 10^(point-length)) is closest to zero for
75
+ // all possible representations of requested_digits digits.
76
+ // If there are two values that are equally close, then FastDtoa returns
77
+ // false.
78
+ // For both modes the buffer must be large enough to hold the result.
79
+ bool FastDtoa(double d,
80
+ FastDtoaMode mode,
81
+ int requested_digits,
82
+ Vector<char> buffer,
83
+ int* length,
84
+ int* decimal_point);
85
+
86
+ } // namespace double_conversion
87
+
88
+ #endif // DOUBLE_CONVERSION_FAST_DTOA_H_
@@ -0,0 +1,404 @@
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 <math.h>
29
+
30
+ #include "fixed-dtoa.h"
31
+ #include "ieee.h"
32
+
33
+ namespace double_conversion {
34
+
35
+ // Represents a 128bit type. This class should be replaced by a native type on
36
+ // platforms that support 128bit integers.
37
+ class UInt128 {
38
+ public:
39
+ UInt128() : high_bits_(0), low_bits_(0) { }
40
+ UInt128(uint64_t high, uint64_t low) : high_bits_(high), low_bits_(low) { }
41
+
42
+ void Multiply(uint32_t multiplicand) {
43
+ uint64_t accumulator;
44
+
45
+ accumulator = (low_bits_ & kMask32) * multiplicand;
46
+ uint32_t part = static_cast<uint32_t>(accumulator & kMask32);
47
+ accumulator >>= 32;
48
+ accumulator = accumulator + (low_bits_ >> 32) * multiplicand;
49
+ low_bits_ = (accumulator << 32) + part;
50
+ accumulator >>= 32;
51
+ accumulator = accumulator + (high_bits_ & kMask32) * multiplicand;
52
+ part = static_cast<uint32_t>(accumulator & kMask32);
53
+ accumulator >>= 32;
54
+ accumulator = accumulator + (high_bits_ >> 32) * multiplicand;
55
+ high_bits_ = (accumulator << 32) + part;
56
+ ASSERT((accumulator >> 32) == 0);
57
+ }
58
+
59
+ void Shift(int shift_amount) {
60
+ ASSERT(-64 <= shift_amount && shift_amount <= 64);
61
+ if (shift_amount == 0) {
62
+ return;
63
+ } else if (shift_amount == -64) {
64
+ high_bits_ = low_bits_;
65
+ low_bits_ = 0;
66
+ } else if (shift_amount == 64) {
67
+ low_bits_ = high_bits_;
68
+ high_bits_ = 0;
69
+ } else if (shift_amount <= 0) {
70
+ high_bits_ <<= -shift_amount;
71
+ high_bits_ += low_bits_ >> (64 + shift_amount);
72
+ low_bits_ <<= -shift_amount;
73
+ } else {
74
+ low_bits_ >>= shift_amount;
75
+ low_bits_ += high_bits_ << (64 - shift_amount);
76
+ high_bits_ >>= shift_amount;
77
+ }
78
+ }
79
+
80
+ // Modifies *this to *this MOD (2^power).
81
+ // Returns *this DIV (2^power).
82
+ int DivModPowerOf2(int power) {
83
+ if (power >= 64) {
84
+ int result = static_cast<int>(high_bits_ >> (power - 64));
85
+ high_bits_ -= static_cast<uint64_t>(result) << (power - 64);
86
+ return result;
87
+ } else {
88
+ uint64_t part_low = low_bits_ >> power;
89
+ uint64_t part_high = high_bits_ << (64 - power);
90
+ int result = static_cast<int>(part_low + part_high);
91
+ high_bits_ = 0;
92
+ low_bits_ -= part_low << power;
93
+ return result;
94
+ }
95
+ }
96
+
97
+ bool IsZero() const {
98
+ return high_bits_ == 0 && low_bits_ == 0;
99
+ }
100
+
101
+ int BitAt(int position) {
102
+ if (position >= 64) {
103
+ return static_cast<int>(high_bits_ >> (position - 64)) & 1;
104
+ } else {
105
+ return static_cast<int>(low_bits_ >> position) & 1;
106
+ }
107
+ }
108
+
109
+ private:
110
+ static const uint64_t kMask32 = 0xFFFFFFFF;
111
+ // Value == (high_bits_ << 64) + low_bits_
112
+ uint64_t high_bits_;
113
+ uint64_t low_bits_;
114
+ };
115
+
116
+
117
+ static const int kDoubleSignificandSize = 53; // Includes the hidden bit.
118
+
119
+
120
+ static void FillDigits32FixedLength(uint32_t number, int requested_length,
121
+ Vector<char> buffer, int* length) {
122
+ for (int i = requested_length - 1; i >= 0; --i) {
123
+ buffer[(*length) + i] = '0' + number % 10;
124
+ number /= 10;
125
+ }
126
+ *length += requested_length;
127
+ }
128
+
129
+
130
+ static void FillDigits32(uint32_t number, Vector<char> buffer, int* length) {
131
+ int number_length = 0;
132
+ // We fill the digits in reverse order and exchange them afterwards.
133
+ while (number != 0) {
134
+ int digit = number % 10;
135
+ number /= 10;
136
+ buffer[(*length) + number_length] = static_cast<char>('0' + digit);
137
+ number_length++;
138
+ }
139
+ // Exchange the digits.
140
+ int i = *length;
141
+ int j = *length + number_length - 1;
142
+ while (i < j) {
143
+ char tmp = buffer[i];
144
+ buffer[i] = buffer[j];
145
+ buffer[j] = tmp;
146
+ i++;
147
+ j--;
148
+ }
149
+ *length += number_length;
150
+ }
151
+
152
+
153
+ static void FillDigits64FixedLength(uint64_t number,
154
+ Vector<char> buffer, int* length) {
155
+ const uint32_t kTen7 = 10000000;
156
+ // For efficiency cut the number into 3 uint32_t parts, and print those.
157
+ uint32_t part2 = static_cast<uint32_t>(number % kTen7);
158
+ number /= kTen7;
159
+ uint32_t part1 = static_cast<uint32_t>(number % kTen7);
160
+ uint32_t part0 = static_cast<uint32_t>(number / kTen7);
161
+
162
+ FillDigits32FixedLength(part0, 3, buffer, length);
163
+ FillDigits32FixedLength(part1, 7, buffer, length);
164
+ FillDigits32FixedLength(part2, 7, buffer, length);
165
+ }
166
+
167
+
168
+ static void FillDigits64(uint64_t number, Vector<char> buffer, int* length) {
169
+ const uint32_t kTen7 = 10000000;
170
+ // For efficiency cut the number into 3 uint32_t parts, and print those.
171
+ uint32_t part2 = static_cast<uint32_t>(number % kTen7);
172
+ number /= kTen7;
173
+ uint32_t part1 = static_cast<uint32_t>(number % kTen7);
174
+ uint32_t part0 = static_cast<uint32_t>(number / kTen7);
175
+
176
+ if (part0 != 0) {
177
+ FillDigits32(part0, buffer, length);
178
+ FillDigits32FixedLength(part1, 7, buffer, length);
179
+ FillDigits32FixedLength(part2, 7, buffer, length);
180
+ } else if (part1 != 0) {
181
+ FillDigits32(part1, buffer, length);
182
+ FillDigits32FixedLength(part2, 7, buffer, length);
183
+ } else {
184
+ FillDigits32(part2, buffer, length);
185
+ }
186
+ }
187
+
188
+
189
+ static void RoundUp(Vector<char> buffer, int* length, int* decimal_point) {
190
+ // An empty buffer represents 0.
191
+ if (*length == 0) {
192
+ buffer[0] = '1';
193
+ *decimal_point = 1;
194
+ *length = 1;
195
+ return;
196
+ }
197
+ // Round the last digit until we either have a digit that was not '9' or until
198
+ // we reached the first digit.
199
+ buffer[(*length) - 1]++;
200
+ for (int i = (*length) - 1; i > 0; --i) {
201
+ if (buffer[i] != '0' + 10) {
202
+ return;
203
+ }
204
+ buffer[i] = '0';
205
+ buffer[i - 1]++;
206
+ }
207
+ // If the first digit is now '0' + 10, we would need to set it to '0' and add
208
+ // a '1' in front. However we reach the first digit only if all following
209
+ // digits had been '9' before rounding up. Now all trailing digits are '0' and
210
+ // we simply switch the first digit to '1' and update the decimal-point
211
+ // (indicating that the point is now one digit to the right).
212
+ if (buffer[0] == '0' + 10) {
213
+ buffer[0] = '1';
214
+ (*decimal_point)++;
215
+ }
216
+ }
217
+
218
+
219
+ // The given fractionals number represents a fixed-point number with binary
220
+ // point at bit (-exponent).
221
+ // Preconditions:
222
+ // -128 <= exponent <= 0.
223
+ // 0 <= fractionals * 2^exponent < 1
224
+ // The buffer holds the result.
225
+ // The function will round its result. During the rounding-process digits not
226
+ // generated by this function might be updated, and the decimal-point variable
227
+ // might be updated. If this function generates the digits 99 and the buffer
228
+ // already contained "199" (thus yielding a buffer of "19999") then a
229
+ // rounding-up will change the contents of the buffer to "20000".
230
+ static void FillFractionals(uint64_t fractionals, int exponent,
231
+ int fractional_count, Vector<char> buffer,
232
+ int* length, int* decimal_point) {
233
+ ASSERT(-128 <= exponent && exponent <= 0);
234
+ // 'fractionals' is a fixed-point number, with binary point at bit
235
+ // (-exponent). Inside the function the non-converted remainder of fractionals
236
+ // is a fixed-point number, with binary point at bit 'point'.
237
+ if (-exponent <= 64) {
238
+ // One 64 bit number is sufficient.
239
+ ASSERT(fractionals >> 56 == 0);
240
+ int point = -exponent;
241
+ for (int i = 0; i < fractional_count; ++i) {
242
+ if (fractionals == 0) break;
243
+ // Instead of multiplying by 10 we multiply by 5 and adjust the point
244
+ // location. This way the fractionals variable will not overflow.
245
+ // Invariant at the beginning of the loop: fractionals < 2^point.
246
+ // Initially we have: point <= 64 and fractionals < 2^56
247
+ // After each iteration the point is decremented by one.
248
+ // Note that 5^3 = 125 < 128 = 2^7.
249
+ // Therefore three iterations of this loop will not overflow fractionals
250
+ // (even without the subtraction at the end of the loop body). At this
251
+ // time point will satisfy point <= 61 and therefore fractionals < 2^point
252
+ // and any further multiplication of fractionals by 5 will not overflow.
253
+ fractionals *= 5;
254
+ point--;
255
+ int digit = static_cast<int>(fractionals >> point);
256
+ ASSERT(digit <= 9);
257
+ buffer[*length] = static_cast<char>('0' + digit);
258
+ (*length)++;
259
+ fractionals -= static_cast<uint64_t>(digit) << point;
260
+ }
261
+ // If the first bit after the point is set we have to round up.
262
+ if (((fractionals >> (point - 1)) & 1) == 1) {
263
+ RoundUp(buffer, length, decimal_point);
264
+ }
265
+ } else { // We need 128 bits.
266
+ ASSERT(64 < -exponent && -exponent <= 128);
267
+ UInt128 fractionals128 = UInt128(fractionals, 0);
268
+ fractionals128.Shift(-exponent - 64);
269
+ int point = 128;
270
+ for (int i = 0; i < fractional_count; ++i) {
271
+ if (fractionals128.IsZero()) break;
272
+ // As before: instead of multiplying by 10 we multiply by 5 and adjust the
273
+ // point location.
274
+ // This multiplication will not overflow for the same reasons as before.
275
+ fractionals128.Multiply(5);
276
+ point--;
277
+ int digit = fractionals128.DivModPowerOf2(point);
278
+ ASSERT(digit <= 9);
279
+ buffer[*length] = static_cast<char>('0' + digit);
280
+ (*length)++;
281
+ }
282
+ if (fractionals128.BitAt(point - 1) == 1) {
283
+ RoundUp(buffer, length, decimal_point);
284
+ }
285
+ }
286
+ }
287
+
288
+
289
+ // Removes leading and trailing zeros.
290
+ // If leading zeros are removed then the decimal point position is adjusted.
291
+ static void TrimZeros(Vector<char> buffer, int* length, int* decimal_point) {
292
+ while (*length > 0 && buffer[(*length) - 1] == '0') {
293
+ (*length)--;
294
+ }
295
+ int first_non_zero = 0;
296
+ while (first_non_zero < *length && buffer[first_non_zero] == '0') {
297
+ first_non_zero++;
298
+ }
299
+ if (first_non_zero != 0) {
300
+ for (int i = first_non_zero; i < *length; ++i) {
301
+ buffer[i - first_non_zero] = buffer[i];
302
+ }
303
+ *length -= first_non_zero;
304
+ *decimal_point -= first_non_zero;
305
+ }
306
+ }
307
+
308
+
309
+ bool FastFixedDtoa(double v,
310
+ int fractional_count,
311
+ Vector<char> buffer,
312
+ int* length,
313
+ int* decimal_point) {
314
+ const uint32_t kMaxUInt32 = 0xFFFFFFFF;
315
+ uint64_t significand = Double(v).Significand();
316
+ int exponent = Double(v).Exponent();
317
+ // v = significand * 2^exponent (with significand a 53bit integer).
318
+ // If the exponent is larger than 20 (i.e. we may have a 73bit number) then we
319
+ // don't know how to compute the representation. 2^73 ~= 9.5*10^21.
320
+ // If necessary this limit could probably be increased, but we don't need
321
+ // more.
322
+ if (exponent > 20) return false;
323
+ if (fractional_count > 20) return false;
324
+ *length = 0;
325
+ // At most kDoubleSignificandSize bits of the significand are non-zero.
326
+ // Given a 64 bit integer we have 11 0s followed by 53 potentially non-zero
327
+ // bits: 0..11*..0xxx..53*..xx
328
+ if (exponent + kDoubleSignificandSize > 64) {
329
+ // The exponent must be > 11.
330
+ //
331
+ // We know that v = significand * 2^exponent.
332
+ // And the exponent > 11.
333
+ // We simplify the task by dividing v by 10^17.
334
+ // The quotient delivers the first digits, and the remainder fits into a 64
335
+ // bit number.
336
+ // Dividing by 10^17 is equivalent to dividing by 5^17*2^17.
337
+ const uint64_t kFive17 = UINT64_2PART_C(0xB1, A2BC2EC5); // 5^17
338
+ uint64_t divisor = kFive17;
339
+ int divisor_power = 17;
340
+ uint64_t dividend = significand;
341
+ uint32_t quotient;
342
+ uint64_t remainder;
343
+ // Let v = f * 2^e with f == significand and e == exponent.
344
+ // Then need q (quotient) and r (remainder) as follows:
345
+ // v = q * 10^17 + r
346
+ // f * 2^e = q * 10^17 + r
347
+ // f * 2^e = q * 5^17 * 2^17 + r
348
+ // If e > 17 then
349
+ // f * 2^(e-17) = q * 5^17 + r/2^17
350
+ // else
351
+ // f = q * 5^17 * 2^(17-e) + r/2^e
352
+ if (exponent > divisor_power) {
353
+ // We only allow exponents of up to 20 and therefore (17 - e) <= 3
354
+ dividend <<= exponent - divisor_power;
355
+ quotient = static_cast<uint32_t>(dividend / divisor);
356
+ remainder = (dividend % divisor) << divisor_power;
357
+ } else {
358
+ divisor <<= divisor_power - exponent;
359
+ quotient = static_cast<uint32_t>(dividend / divisor);
360
+ remainder = (dividend % divisor) << exponent;
361
+ }
362
+ FillDigits32(quotient, buffer, length);
363
+ FillDigits64FixedLength(remainder, buffer, length);
364
+ *decimal_point = *length;
365
+ } else if (exponent >= 0) {
366
+ // 0 <= exponent <= 11
367
+ significand <<= exponent;
368
+ FillDigits64(significand, buffer, length);
369
+ *decimal_point = *length;
370
+ } else if (exponent > -kDoubleSignificandSize) {
371
+ // We have to cut the number.
372
+ uint64_t integrals = significand >> -exponent;
373
+ uint64_t fractionals = significand - (integrals << -exponent);
374
+ if (integrals > kMaxUInt32) {
375
+ FillDigits64(integrals, buffer, length);
376
+ } else {
377
+ FillDigits32(static_cast<uint32_t>(integrals), buffer, length);
378
+ }
379
+ *decimal_point = *length;
380
+ FillFractionals(fractionals, exponent, fractional_count,
381
+ buffer, length, decimal_point);
382
+ } else if (exponent < -128) {
383
+ // This configuration (with at most 20 digits) means that all digits must be
384
+ // 0.
385
+ ASSERT(fractional_count <= 20);
386
+ buffer[0] = '\0';
387
+ *length = 0;
388
+ *decimal_point = -fractional_count;
389
+ } else {
390
+ *decimal_point = 0;
391
+ FillFractionals(significand, exponent, fractional_count,
392
+ buffer, length, decimal_point);
393
+ }
394
+ TrimZeros(buffer, length, decimal_point);
395
+ buffer[*length] = '\0';
396
+ if ((*length) == 0) {
397
+ // The string is empty and the decimal_point thus has no importance. Mimick
398
+ // Gay's dtoa and and set it to -fractional_count.
399
+ *decimal_point = -fractional_count;
400
+ }
401
+ return true;
402
+ }
403
+
404
+ } // namespace double_conversion