PageRenderTime 56ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/chronicle/src/main/java/com/higherfrequencytrading/chronicle/impl/AbstractExcerpt.java

http://github.com/peter-lawrey/Java-Chronicle
Java | 2145 lines | 1878 code | 207 blank | 60 comment | 433 complexity | 804a0f091d2d5fad3dce7ffa22dd988b MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright 2013 Peter Lawrey
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.higherfrequencytrading.chronicle.impl;
  17. import com.higherfrequencytrading.chronicle.ByteStringAppender;
  18. import com.higherfrequencytrading.chronicle.EnumeratedMarshaller;
  19. import com.higherfrequencytrading.chronicle.Excerpt;
  20. import com.higherfrequencytrading.chronicle.StopCharTester;
  21. import com.higherfrequencytrading.chronicle.math.MutableDecimal;
  22. import org.jetbrains.annotations.NotNull;
  23. import org.jetbrains.annotations.Nullable;
  24. import java.io.*;
  25. import java.nio.ByteBuffer;
  26. import java.nio.ByteOrder;
  27. import java.nio.MappedByteBuffer;
  28. import java.nio.charset.Charset;
  29. import java.text.SimpleDateFormat;
  30. import java.util.*;
  31. import java.util.concurrent.atomic.AtomicBoolean;
  32. /**
  33. * @author peter.lawrey
  34. */
  35. public abstract class AbstractExcerpt implements Excerpt {
  36. public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
  37. public static final int UNSIGNED_BYTE_MASK = 0xFF;
  38. public static final int UNSIGNED_SHORT_MASK = 0xFFFF;
  39. public static final long UNSIGNED_INT_MASK = 0xFFFFFFFFL;
  40. // extra 1 for decimal place.
  41. static final int MAX_NUMBER_LENGTH = 1 + (int) Math.ceil(Math.log10(Long.MAX_VALUE));
  42. private static final int MIN_SIZE = 8;
  43. private static final byte[] MIN_VALUE_TEXT = ("" + Long.MIN_VALUE).getBytes();
  44. private static final byte[] Infinity = "Infinity".getBytes();
  45. private static final byte[] NaN = "NaN".getBytes();
  46. private static final long MAX_VALUE_DIVIDE_5 = Long.MAX_VALUE / 5;
  47. private static final byte BYTE_MIN_VALUE = Byte.MIN_VALUE;
  48. private static final byte BYTE_EXTENDED = Byte.MIN_VALUE + 1;
  49. private static final byte BYTE_MAX_VALUE = Byte.MIN_VALUE + 2;
  50. private static final short UBYTE_EXTENDED = 0xff;
  51. private static final short SHORT_MIN_VALUE = Short.MIN_VALUE;
  52. private static final short SHORT_EXTENDED = Short.MIN_VALUE + 1;
  53. private static final short SHORT_MAX_VALUE = Short.MIN_VALUE + 2;
  54. private static final int USHORT_EXTENDED = 0xFFFF;
  55. private static final int INT_MIN_VALUE = Integer.MIN_VALUE;
  56. private static final int INT_EXTENDED = Integer.MIN_VALUE + 1;
  57. private static final int INT_MAX_VALUE = Integer.MIN_VALUE + 2;
  58. private static final long MAX_VALUE_DIVIDE_10 = Long.MAX_VALUE / 10;
  59. private static final long[] TENS = new long[19];
  60. static {
  61. TENS[0] = 1;
  62. for (int i = 1; i < TENS.length; i++)
  63. TENS[i] = TENS[i - 1] * 10;
  64. }
  65. private static final byte NULL = 'N';
  66. private static final byte ENUMED = 'E';
  67. private static final byte SERIALIZED = 'S';
  68. protected final DirectChronicle chronicle;
  69. private final byte[] numberBuffer = new byte[MAX_NUMBER_LENGTH];
  70. private final AtomicBoolean barrier = new AtomicBoolean();
  71. protected long index = -1;
  72. protected long start = 0;
  73. protected long position = 0;
  74. protected long limit = 0;
  75. protected long startPosition;
  76. protected long size = 0;
  77. @Nullable
  78. protected MappedByteBuffer buffer;
  79. private int capacity = 0;
  80. private boolean forWrite = false;
  81. @Nullable
  82. private ExcerptInputStream inputStream = null;
  83. @Nullable
  84. private ExcerptOutputStream outputStream = null;
  85. @Nullable
  86. private Thread lastThread = null;
  87. @Nullable
  88. private StringBuilder utfReader = null;
  89. @Nullable
  90. private SimpleDateFormat dateFormat = null;
  91. // RandomDataInput
  92. private long lastDay = Long.MIN_VALUE;
  93. @Nullable
  94. private byte[] lastDateStr = null;
  95. protected AbstractExcerpt(DirectChronicle chronicle) {
  96. this.chronicle = chronicle;
  97. }
  98. private static double asDouble(long value, int exp, boolean negative, int decimalPlaces) {
  99. if (decimalPlaces > 0 && value < Long.MAX_VALUE / 2) {
  100. if (value < Long.MAX_VALUE / (1L << 32)) {
  101. exp -= 32;
  102. value <<= 32;
  103. }
  104. if (value < Long.MAX_VALUE / (1L << 16)) {
  105. exp -= 16;
  106. value <<= 16;
  107. }
  108. if (value < Long.MAX_VALUE / (1L << 8)) {
  109. exp -= 8;
  110. value <<= 8;
  111. }
  112. if (value < Long.MAX_VALUE / (1L << 4)) {
  113. exp -= 4;
  114. value <<= 4;
  115. }
  116. if (value < Long.MAX_VALUE / (1L << 2)) {
  117. exp -= 2;
  118. value <<= 2;
  119. }
  120. if (value < Long.MAX_VALUE / (1L << 1)) {
  121. exp -= 1;
  122. value <<= 1;
  123. }
  124. }
  125. for (; decimalPlaces > 0; decimalPlaces--) {
  126. exp--;
  127. long mod = value % 5;
  128. value /= 5;
  129. int modDiv = 1;
  130. if (value < Long.MAX_VALUE / (1L << 4)) {
  131. exp -= 4;
  132. value <<= 4;
  133. modDiv <<= 4;
  134. }
  135. if (value < Long.MAX_VALUE / (1L << 2)) {
  136. exp -= 2;
  137. value <<= 2;
  138. modDiv <<= 2;
  139. }
  140. if (value < Long.MAX_VALUE / (1L << 1)) {
  141. exp -= 1;
  142. value <<= 1;
  143. modDiv <<= 1;
  144. }
  145. if (decimalPlaces > 1)
  146. value += modDiv * mod / 5;
  147. else
  148. value += (modDiv * mod + 4) / 5;
  149. }
  150. final double d = Math.scalb((double) value, exp);
  151. return negative ? -d : d;
  152. }
  153. @Override
  154. public boolean nextIndex() {
  155. chronicle.checkNotClosed();
  156. return index(index() + 1);
  157. }
  158. @Override
  159. public long index() {
  160. return index;
  161. }
  162. @Override
  163. public boolean index(long index) throws IndexOutOfBoundsException {
  164. forWrite = false;
  165. readMemoryBarrier();
  166. long endPosition = chronicle.getIndexData(index + 1);
  167. if (endPosition == 0) {
  168. capacity = 0;
  169. buffer = null;
  170. // System.out.println("ep");
  171. // rewind?
  172. if (index == -1) {
  173. this.index = -1;
  174. limit = startPosition = position = capacity = 0;
  175. return true;
  176. }
  177. return false;
  178. }
  179. long startPosition = chronicle.getIndexData(index);
  180. capacity = (int) (endPosition - startPosition);
  181. assert capacity >= MIN_SIZE : "end=" + endPosition + ", start=" + startPosition;
  182. index0(index, startPosition, endPosition);
  183. // TODO Assumes the start of the record won't be all 0's
  184. // TODO Need to determine whether this is required as a safety check or not.
  185. long l = readLong(0);
  186. return l != 0L;
  187. }
  188. protected abstract void index0(long index, long startPosition, long endPosition);
  189. private void readMemoryBarrier() {
  190. barrier.get();
  191. }
  192. @Override
  193. public boolean hasNextIndex() {
  194. readMemoryBarrier();
  195. long nextIndex = index + 1;
  196. long endPosition = chronicle.getIndexData(nextIndex + 1);
  197. return endPosition != 0;
  198. }
  199. @Override
  200. public void startExcerpt(int capacity) {
  201. this.capacity = capacity < MIN_SIZE ? MIN_SIZE : capacity;
  202. long startPosition = chronicle.startExcerpt(this, capacity);
  203. long endPosition = startPosition + capacity;
  204. index0(chronicle.size(), startPosition, endPosition);
  205. forWrite = true;
  206. index = chronicle.size();
  207. }
  208. @Override
  209. public void readFully(@NotNull byte[] b) {
  210. readFully(b, 0, b.length);
  211. }
  212. @Override
  213. public void readFully(@NotNull byte[] b, int off, int len) {
  214. if (len-- <= 0)
  215. return;
  216. do {
  217. b[off++] = readByte();
  218. } while (len-- > 0);
  219. }
  220. @Override
  221. public boolean readBoolean() {
  222. return readByte() != 0;
  223. }
  224. @Override
  225. public boolean readBoolean(int offset) {
  226. return readByte(offset) != 0;
  227. }
  228. @Override
  229. public int readUnsignedByte() {
  230. return readByte() & UNSIGNED_BYTE_MASK;
  231. }
  232. @Override
  233. public int readUnsignedByte(int offset) {
  234. return readByte(offset) & UNSIGNED_BYTE_MASK;
  235. }
  236. @Override
  237. public int readUnsignedShort() {
  238. return readShort() & UNSIGNED_SHORT_MASK;
  239. }
  240. @Override
  241. public int readUnsignedShort(int offset) {
  242. return readShort(offset) & UNSIGNED_SHORT_MASK;
  243. }
  244. @NotNull
  245. @Override
  246. public String readLine() {
  247. StringBuilder input = acquireUtfReader();
  248. EOL:
  249. while (position() < capacity()) {
  250. int c = readUnsignedByte();
  251. switch (c) {
  252. case '\n':
  253. break EOL;
  254. case '\r':
  255. int cur = position();
  256. if (cur < capacity() && readByte(cur) == '\n')
  257. position(cur + 1);
  258. break EOL;
  259. default:
  260. input.append((char) c);
  261. break;
  262. }
  263. }
  264. return chronicle.stringInterner().intern(input);
  265. }
  266. @Override
  267. public int capacity() {
  268. return (int) (limit - start);
  269. }
  270. @Override
  271. public int position() {
  272. return (int) (position - start);
  273. }
  274. @NotNull
  275. @Override
  276. public Excerpt position(int position) {
  277. if (position < 0 || position > capacity())
  278. throw new IndexOutOfBoundsException();
  279. this.position = start + position; // start has to be added
  280. return this;
  281. }
  282. @Override
  283. public boolean readUTF(@NotNull Appendable appendable) {
  284. return appendUTF(appendable);
  285. }
  286. @Override
  287. public boolean appendUTF(@NotNull Appendable appendable) {
  288. try {
  289. return appendUTF0(appendable);
  290. } catch (IOException unexpected) {
  291. throw new AssertionError(unexpected);
  292. }
  293. }
  294. private boolean appendUTF0(@NotNull Appendable appendable) throws IOException {
  295. long len = readStopBit();
  296. if (len < -1 || len > Integer.MAX_VALUE)
  297. throw new StreamCorruptedException("UTF length invalid " + len);
  298. if (len == -1)
  299. return false;
  300. int utflen = (int) len;
  301. int count = 0;
  302. while (count < utflen) {
  303. int c = readByte();
  304. if (c < 0) {
  305. position(position() - 1);
  306. break;
  307. }
  308. count++;
  309. appendable.append((char) c);
  310. }
  311. if (count < utflen) {
  312. append1(appendable, utflen, count);
  313. }
  314. return true;
  315. }
  316. @Override
  317. public long readStopBit() {
  318. long b;
  319. if ((b = readByte()) >= 0)
  320. return b;
  321. return readStopBit0(b);
  322. }
  323. private long readStopBit0(long b) {
  324. long l = 0;
  325. int count = 0;
  326. do {
  327. l |= (b & 0x7FL) << count;
  328. count += 7;
  329. } while ((b = readByte()) < 0);
  330. if (b == 0 && count > 0)
  331. return ~l;
  332. return l | (b << count);
  333. }
  334. private void append1(@NotNull Appendable appendable, int utflen, int count) throws IOException {
  335. do {
  336. int c = readUnsignedByte();
  337. switch (c >> 4) {
  338. case 0:
  339. case 1:
  340. case 2:
  341. case 3:
  342. case 4:
  343. case 5:
  344. case 6:
  345. case 7:
  346. /* 0xxxxxxx */
  347. count++;
  348. appendable.append((char) c);
  349. break;
  350. case 12:
  351. case 13: {
  352. /* 110x xxxx 10xx xxxx */
  353. count += 2;
  354. if (count > utflen)
  355. throw new UTFDataFormatException(
  356. "malformed input: partial character at end");
  357. int char2 = readUnsignedByte();
  358. if ((char2 & 0xC0) != 0x80)
  359. throw new UTFDataFormatException(
  360. "malformed input around byte " + count);
  361. int c2 = (char) (((c & 0x1F) << 6) |
  362. (char2 & 0x3F));
  363. appendable.append((char) c2);
  364. break;
  365. }
  366. case 14: {
  367. /* 1110 xxxx 10xx xxxx 10xx xxxx */
  368. count += 3;
  369. if (count > utflen)
  370. throw new UTFDataFormatException(
  371. "malformed input: partial character at end");
  372. int char2 = readUnsignedByte();
  373. int char3 = readUnsignedByte();
  374. if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
  375. throw new UTFDataFormatException(
  376. "malformed input around byte " + (count - 1));
  377. int c3 = (char) (((c & 0x0F) << 12) |
  378. ((char2 & 0x3F) << 6) |
  379. (char3 & 0x3F));
  380. appendable.append((char) c3);
  381. break;
  382. }
  383. default:
  384. /* 10xx xxxx, 1111 xxxx */
  385. throw new UTFDataFormatException(
  386. "malformed input around byte " + count);
  387. }
  388. } while (count < utflen);
  389. }
  390. @NotNull
  391. @Override
  392. public String parseUTF(@NotNull StopCharTester tester) {
  393. StringBuilder sb = acquireUtfReader();
  394. parseUTF(sb, tester);
  395. return chronicle.stringInterner().intern(sb);
  396. }
  397. @Override
  398. public void parseUTF(@NotNull Appendable builder, @NotNull StopCharTester tester) {
  399. try {
  400. readUTF0(builder, tester);
  401. } catch (IOException e) {
  402. throw new AssertionError(e);
  403. }
  404. }
  405. private void readUTF0(@NotNull Appendable appendable, @NotNull StopCharTester tester) throws IOException {
  406. while (remaining() > 0) {
  407. int c = readByte();
  408. if (c < 0) {
  409. position(position() - 1);
  410. break;
  411. }
  412. if (tester.isStopChar(c))
  413. return;
  414. appendable.append((char) c);
  415. }
  416. if (remaining() > 0) {
  417. readUTF1(appendable, tester);
  418. }
  419. }
  420. private void readUTF1(@NotNull Appendable appendable, @NotNull StopCharTester tester) throws IOException {
  421. do {
  422. int c = readUnsignedByte();
  423. switch (c >> 4) {
  424. case 0:
  425. case 1:
  426. case 2:
  427. case 3:
  428. case 4:
  429. case 5:
  430. case 6:
  431. case 7:
  432. /* 0xxxxxxx */
  433. if (tester.isStopChar(c))
  434. return;
  435. appendable.append((char) c);
  436. break;
  437. case 12:
  438. case 13: {
  439. /* 110x xxxx 10xx xxxx */
  440. int char2 = readUnsignedByte();
  441. if ((char2 & 0xC0) != 0x80)
  442. throw new UTFDataFormatException(
  443. "malformed input around byte");
  444. int c2 = (char) (((c & 0x1F) << 6) |
  445. (char2 & 0x3F));
  446. if (tester.isStopChar(c2))
  447. return;
  448. appendable.append((char) c2);
  449. break;
  450. }
  451. case 14: {
  452. /* 1110 xxxx 10xx xxxx 10xx xxxx */
  453. int char2 = readUnsignedByte();
  454. int char3 = readUnsignedByte();
  455. if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
  456. throw new UTFDataFormatException(
  457. "malformed input around byte ");
  458. int c3 = (char) (((c & 0x0F) << 12) |
  459. ((char2 & 0x3F) << 6) |
  460. (char3 & 0x3F));
  461. if (tester.isStopChar(c3))
  462. return;
  463. appendable.append((char) c3);
  464. break;
  465. }
  466. default:
  467. /* 10xx xxxx, 1111 xxxx */
  468. throw new UTFDataFormatException(
  469. "malformed input around byte ");
  470. }
  471. } while (remaining() > 0);
  472. }
  473. @Override
  474. public int remaining() {
  475. return (int) (limit - position);
  476. }
  477. @NotNull
  478. private StringBuilder acquireUtfReader() {
  479. if (utfReader == null)
  480. utfReader = new StringBuilder();
  481. utfReader.setLength(0);
  482. return utfReader;
  483. }
  484. @Override
  485. public boolean stepBackAndSkipTo(@NotNull StopCharTester tester) {
  486. if (position() > 0)
  487. position(position() - 1);
  488. return skipTo(tester);
  489. }
  490. @Override
  491. public boolean skipTo(@NotNull StopCharTester tester) {
  492. if (remaining() <= 0) {
  493. return false;
  494. }
  495. do {
  496. int ch = readByte();
  497. if (tester.isStopChar(ch))
  498. return true;
  499. } while (remaining() > 0);
  500. return false;
  501. }
  502. @Nullable
  503. @Override
  504. public String readUTF(int offset) {
  505. long oldPosition = position;
  506. position = offset;
  507. try {
  508. return readUTF();
  509. } finally {
  510. position = oldPosition;
  511. }
  512. }
  513. @Nullable
  514. @Override
  515. public String readUTF() {
  516. StringBuilder sb = acquireUtfReader();
  517. if (readUTF(sb)) {
  518. return chronicle.stringInterner().intern(sb);
  519. }
  520. return null;
  521. }
  522. @Override
  523. public boolean readUTF(@NotNull StringBuilder stringBuilder) {
  524. try {
  525. stringBuilder.setLength(0);
  526. return appendUTF0(stringBuilder);
  527. } catch (IOException unexpected) {
  528. throw new AssertionError(unexpected);
  529. }
  530. }
  531. @Override
  532. public short readCompactShort() {
  533. byte b = readByte();
  534. switch (b) {
  535. case BYTE_MIN_VALUE:
  536. return Short.MIN_VALUE;
  537. case BYTE_MAX_VALUE:
  538. return Short.MAX_VALUE;
  539. case BYTE_EXTENDED:
  540. return readShort();
  541. default:
  542. return b;
  543. }
  544. }
  545. @Override
  546. public int readCompactUnsignedShort() {
  547. int b = readUnsignedByte();
  548. if (b == UBYTE_EXTENDED)
  549. return readUnsignedShort();
  550. return b;
  551. }
  552. @Override
  553. public int readInt24() {
  554. int b = readUnsignedByte();
  555. int s = readUnsignedShort();
  556. if (byteOrder() == ByteOrder.BIG_ENDIAN)
  557. return ((b << 24) + (s << 8)) >> 8;
  558. // extra shifting to get sign extension.
  559. return ((b << 8) + (s << 16)) >> 8;
  560. }
  561. private ByteOrder byteOrder() {
  562. return chronicle().byteOrder();
  563. }
  564. @Override
  565. public int readInt24(int offset) {
  566. int b = readUnsignedByte(offset);
  567. int s = readUnsignedShort(offset + 1);
  568. if (byteOrder() == ByteOrder.BIG_ENDIAN)
  569. return ((b << 24) + (s << 8)) >> 8;
  570. // extra shifting to get sign extension.
  571. return ((b << 8) + (s << 16)) >> 8;
  572. }
  573. @Override
  574. public long readUnsignedInt() {
  575. return readInt() & UNSIGNED_INT_MASK;
  576. }
  577. @Override
  578. public long readUnsignedInt(int offset) {
  579. return readInt(offset) & UNSIGNED_INT_MASK;
  580. }
  581. @Override
  582. public int readCompactInt() {
  583. short b = readShort();
  584. switch (b) {
  585. case SHORT_MIN_VALUE:
  586. return Integer.MIN_VALUE;
  587. case SHORT_MAX_VALUE:
  588. return Integer.MAX_VALUE;
  589. case SHORT_EXTENDED:
  590. return readInt();
  591. default:
  592. return b;
  593. }
  594. }
  595. @Override
  596. public long readCompactUnsignedInt() {
  597. int b = readUnsignedShort();
  598. if (b == USHORT_EXTENDED)
  599. return readUnsignedInt();
  600. return b;
  601. }
  602. // RandomDataOutput
  603. @Override
  604. public long readInt48() {
  605. long s = readUnsignedShort();
  606. long l = readUnsignedInt();
  607. if (byteOrder() == ByteOrder.BIG_ENDIAN)
  608. return ((s << 48) + (l << 16)) >> 16;
  609. // extra shifting to get sign extension.
  610. return ((s << 16) + (l << 32)) >> 16;
  611. }
  612. @Override
  613. public long readInt48(int offset) {
  614. long s = readUnsignedShort(offset);
  615. long l = readUnsignedInt(offset + 2);
  616. if (byteOrder() == ByteOrder.BIG_ENDIAN)
  617. return ((s << 48) + (l << 16)) >> 16;
  618. // extra shifting to get sign extension.
  619. return ((s << 16) + (l << 32)) >> 16;
  620. }
  621. @Override
  622. public long readCompactLong() {
  623. int b = readInt();
  624. switch (b) {
  625. case INT_MIN_VALUE:
  626. return Long.MIN_VALUE;
  627. case INT_MAX_VALUE:
  628. return Long.MAX_VALUE;
  629. case INT_EXTENDED:
  630. return readLong();
  631. default:
  632. return b;
  633. }
  634. }
  635. @Override
  636. public double readCompactDouble() {
  637. float f = readFloat();
  638. if (Float.isNaN(f))
  639. return readDouble();
  640. return f;
  641. }
  642. @Override
  643. public void readByteString(@NotNull StringBuilder sb) {
  644. sb.setLength(0);
  645. int len = readByte() & 0xFF;
  646. for (int i = 0; i < len; i++)
  647. sb.append(readByte());
  648. }
  649. @Override
  650. public int readByteString(int offset, @NotNull StringBuilder sb) {
  651. sb.setLength(0);
  652. int len = readByte(offset) & 0xFF;
  653. for (int i = 1; i <= len; i++)
  654. sb.append(readByte(offset + i));
  655. return offset + len + 1;
  656. }
  657. @NotNull
  658. @SuppressWarnings("deprecation")
  659. @Override
  660. public String readByteString() {
  661. int len = readByte() & 0xFF;
  662. if (len == 0)
  663. return "";
  664. byte[] bytes = new byte[len];
  665. for (int i = 0; i < len; i++)
  666. bytes[i] = readByte();
  667. return new String(bytes, 0);
  668. }
  669. @Override
  670. public void readChars(@NotNull StringBuilder sb) {
  671. int len = readChar();
  672. sb.setLength(0);
  673. for (int i = 0; i < len; i++)
  674. sb.append(readChar());
  675. }
  676. @NotNull
  677. @Override
  678. public String readChars() {
  679. int len = readChar();
  680. if (len == 0)
  681. return "";
  682. char[] chars = new char[len];
  683. for (int i = 0; i < len; i++)
  684. chars[i] = readChar();
  685. return new String(chars);
  686. }
  687. @Override
  688. public void read(@NotNull ByteBuffer bb) {
  689. int len = Math.min(bb.remaining(), remaining());
  690. if (bb.order() == order()) {
  691. while (len >= 8) {
  692. bb.putLong(readLong());
  693. len -= 8;
  694. }
  695. }
  696. while (len > 0) {
  697. bb.put(readByte());
  698. len--;
  699. }
  700. }
  701. @NotNull
  702. @Override
  703. public ByteOrder order() {
  704. assert buffer != null;
  705. return buffer.order();
  706. }
  707. @Override
  708. public void writeBoolean(boolean v) {
  709. write(v ? -1 : 0);
  710. }
  711. @Override
  712. public void writeBoolean(int offset, boolean v) {
  713. write(offset, v ? -1 : 0);
  714. }
  715. @Override
  716. public void writeBytes(@NotNull String s) {
  717. writeBytes((CharSequence) s);
  718. }
  719. @Override
  720. public void writeBytes(@NotNull CharSequence s) {
  721. int len = s.length();
  722. if (len > 255)
  723. throw new IllegalArgumentException("Len cannot be " + len + " > 255");
  724. write(len);
  725. for (int i = 0; i < len; i++)
  726. write(s.charAt(i));
  727. }
  728. @Override
  729. public void writeBytes(int offset, @NotNull CharSequence s) {
  730. int len = s.length();
  731. if (len > 255)
  732. throw new IllegalArgumentException("Len cannot be " + len + " > 255");
  733. write(offset, len);
  734. for (int i = 0; i < len; i++)
  735. write(s.charAt(i));
  736. for (int i = 0; i < len; i++)
  737. write(offset + 1 + i, s.charAt(i));
  738. }
  739. @Override
  740. public void writeChars(@NotNull String s) {
  741. writeChars((CharSequence) s);
  742. }
  743. @Override
  744. public void writeChars(@NotNull CharSequence s) {
  745. int len = s.length();
  746. if (len > 65535)
  747. throw new IllegalArgumentException("Len cannot be " + len + " > 65535");
  748. writeChar(len);
  749. for (int i = 0; i < len; i++)
  750. writeChar(s.charAt(i));
  751. }
  752. @Override
  753. public void writeChars(int offset, @NotNull CharSequence s) {
  754. int len = s.length();
  755. if (len > 65535)
  756. throw new IllegalArgumentException("Len cannot be " + len + " > 65535");
  757. writeChar(offset + len);
  758. for (int i = 0; i < len; i++)
  759. writeChar(offset + 2 + i, s.charAt(i));
  760. }
  761. @Override
  762. public void writeUTF(@Nullable String s) {
  763. writeUTF((CharSequence) s);
  764. }
  765. @Override
  766. public void writeUTF(@Nullable CharSequence str) {
  767. if (str == null) {
  768. writeStopBit(-1);
  769. return;
  770. }
  771. long strlen = str.length();
  772. int utflen = 0;
  773. int c;
  774. /* use charAt instead of copying String to char array */
  775. for (int i = 0; i < strlen; i++) {
  776. c = str.charAt(i);
  777. if ((c >= 0x0001) && (c <= 0x007F)) {
  778. utflen++;
  779. } else if (c > 0x07FF) {
  780. utflen += 3;
  781. } else {
  782. utflen += 2;
  783. }
  784. }
  785. if (utflen > remaining())
  786. throw new IllegalArgumentException(
  787. "encoded string too long: " + utflen + " bytes, remaining=" + remaining());
  788. writeStopBit(utflen);
  789. int i;
  790. for (i = 0; i < strlen; i++) {
  791. c = str.charAt(i);
  792. if (!((c >= 0x0001) && (c <= 0x007F)))
  793. break;
  794. write(c);
  795. }
  796. for (; i < strlen; i++) {
  797. c = str.charAt(i);
  798. if ((c >= 0x0001) && (c <= 0x007F)) {
  799. write(c);
  800. } else if (c > 0x07FF) {
  801. write((byte) (0xE0 | ((c >> 12) & 0x0F)));
  802. write((byte) (0x80 | ((c >> 6) & 0x3F)));
  803. write((byte) (0x80 | (c & 0x3F)));
  804. } else {
  805. write((byte) (0xC0 | ((c >> 6) & 0x1F)));
  806. write((byte) (0x80 | c & 0x3F));
  807. }
  808. }
  809. }
  810. @Override
  811. public void writeByte(int v) {
  812. write(v);
  813. }
  814. @Override
  815. public void write(int offset, @NotNull byte[] b) {
  816. for (int i = 0; i < b.length; i++)
  817. write(offset + i, b[i]);
  818. }
  819. @Override
  820. public void writeUnsignedByte(int v) {
  821. writeByte(v);
  822. }
  823. @Override
  824. public void writeUnsignedByte(int offset, int v) {
  825. write(offset, v);
  826. }
  827. @Override
  828. public void writeUnsignedShort(int v) {
  829. writeShort(v);
  830. }
  831. @Override
  832. public void writeUnsignedShort(int offset, int v) {
  833. writeShort(offset, v);
  834. }
  835. @Override
  836. public void writeCompactShort(int v) {
  837. if (v > BYTE_MAX_VALUE && v <= Byte.MAX_VALUE)
  838. writeByte(v);
  839. else
  840. switch (v) {
  841. case Short.MIN_VALUE:
  842. writeByte(BYTE_MIN_VALUE);
  843. break;
  844. case Short.MAX_VALUE:
  845. writeByte(BYTE_MAX_VALUE);
  846. break;
  847. default:
  848. writeByte(BYTE_EXTENDED);
  849. writeShort(v);
  850. break;
  851. }
  852. }
  853. @Override
  854. public void writeCompactUnsignedShort(int v) {
  855. if (v >= 0 && v < USHORT_EXTENDED) {
  856. writeByte(v);
  857. } else {
  858. writeUnsignedShort(USHORT_EXTENDED);
  859. writeUnsignedShort(v);
  860. }
  861. }
  862. @Override
  863. public void writeInt24(int v) {
  864. if (chronicle.byteOrder() == ByteOrder.BIG_ENDIAN) {
  865. writeUnsignedByte(v >>> 16);
  866. writeUnsignedShort(v);
  867. } else {
  868. writeUnsignedByte(v);
  869. writeUnsignedShort(v >>> 8);
  870. }
  871. }
  872. @Override
  873. public void writeInt24(int offset, int v) {
  874. if (chronicle.byteOrder() == ByteOrder.BIG_ENDIAN) {
  875. writeUnsignedByte(offset, v >>> 16);
  876. writeUnsignedShort(offset + 1, v);
  877. } else {
  878. writeUnsignedByte(offset, v);
  879. writeUnsignedShort(offset + 1, v >>> 8);
  880. }
  881. }
  882. @Override
  883. public void writeUnsignedInt(long v) {
  884. writeInt((int) v);
  885. }
  886. @Override
  887. public void writeUnsignedInt(int offset, long v) {
  888. writeInt(offset, (int) v);
  889. }
  890. @Override
  891. public void writeCompactInt(int v) {
  892. if (v > SHORT_MAX_VALUE && v <= Short.MAX_VALUE)
  893. writeShort(v);
  894. else
  895. switch (v) {
  896. case Integer.MIN_VALUE:
  897. writeShort(SHORT_MIN_VALUE);
  898. break;
  899. case Integer.MAX_VALUE:
  900. writeShort(SHORT_MAX_VALUE);
  901. break;
  902. default:
  903. writeShort(SHORT_EXTENDED);
  904. writeInt(v);
  905. break;
  906. }
  907. }
  908. @Override
  909. public void writeCompactUnsignedInt(long v) {
  910. if (v >= 0 && v < USHORT_EXTENDED) {
  911. writeShort((int) v);
  912. } else {
  913. writeShort(USHORT_EXTENDED);
  914. writeUnsignedInt(v);
  915. }
  916. }
  917. @Override
  918. public void writeInt48(long v) {
  919. if (chronicle.byteOrder() == ByteOrder.BIG_ENDIAN) {
  920. writeUnsignedShort((int) (v >>> 32));
  921. writeUnsignedInt(v);
  922. } else {
  923. writeUnsignedShort((int) v);
  924. writeUnsignedInt(v >>> 16);
  925. }
  926. }
  927. @Override
  928. public void writeInt48(int offset, long v) {
  929. if (chronicle.byteOrder() == ByteOrder.BIG_ENDIAN) {
  930. writeUnsignedShort(offset, (int) (v >>> 32));
  931. writeUnsignedInt(offset + 2, v);
  932. } else {
  933. writeUnsignedShort(offset, (int) v);
  934. writeUnsignedInt(offset + 2, v >>> 16);
  935. }
  936. }
  937. @Override
  938. public void writeCompactLong(long v) {
  939. if (v > INT_MAX_VALUE && v <= Integer.MAX_VALUE) {
  940. writeInt((int) v);
  941. } else if (v == Long.MIN_VALUE) {
  942. writeInt(INT_MIN_VALUE);
  943. } else if (v == Long.MAX_VALUE) {
  944. writeInt(INT_MAX_VALUE);
  945. } else {
  946. writeInt(INT_EXTENDED);
  947. writeLong(v);
  948. }
  949. }
  950. @Override
  951. public void writeStopBit(long n) {
  952. boolean neg = false;
  953. if (n < 0) {
  954. neg = true;
  955. n = ~n;
  956. }
  957. while (true) {
  958. long n2 = n >>> 7;
  959. if (n2 != 0) {
  960. writeByte((byte) (0x80 | (n & 0x7F)));
  961. n = n2;
  962. } else {
  963. if (neg) {
  964. writeByte((byte) (0x80 | (n & 0x7F)));
  965. writeByte(0);
  966. } else {
  967. writeByte((byte) (n & 0x7F));
  968. }
  969. break;
  970. }
  971. }
  972. }
  973. // // ByteStringAppender
  974. @Override
  975. public void writeCompactDouble(double v) {
  976. float f = (float) v;
  977. if (f == v) {
  978. writeFloat(f);
  979. } else {
  980. writeFloat(Float.NaN);
  981. writeDouble(v);
  982. }
  983. }
  984. @Override
  985. public void write(@NotNull ByteBuffer bb) {
  986. if (bb.order() == order())
  987. while (bb.remaining() >= 8)
  988. writeLong(bb.getLong());
  989. while (bb.remaining() >= 1)
  990. writeByte(bb.get());
  991. }
  992. @Override
  993. public int length() {
  994. return position();
  995. }
  996. @NotNull
  997. @Override
  998. public ByteStringAppender append(@NotNull CharSequence s, int start, int end) {
  999. for (int i = start, len = Math.min(end, s.length()); i < len; i++)
  1000. writeByte(s.charAt(i));
  1001. return this;
  1002. }
  1003. @NotNull
  1004. @Override
  1005. public ByteStringAppender append(@NotNull Enum value) {
  1006. return append(value.toString());
  1007. }
  1008. @NotNull
  1009. @Override
  1010. public ByteStringAppender append(@NotNull CharSequence s) {
  1011. for (int i = 0, len = s.length(); i < len; i++)
  1012. writeByte(s.charAt(i));
  1013. return this;
  1014. }
  1015. @NotNull
  1016. @Override
  1017. public ByteStringAppender append(@NotNull byte[] str, int offset, int len) {
  1018. write(str, offset, len);
  1019. return this;
  1020. }
  1021. @Override
  1022. public void write(byte[] b, int off, int len) {
  1023. for (int i = 0; i < len; i++)
  1024. write(b[off + i]);
  1025. }
  1026. @NotNull
  1027. @Override
  1028. public ByteStringAppender append(boolean b) {
  1029. append(b ? "true" : "false");
  1030. return this;
  1031. }
  1032. @NotNull
  1033. @Override
  1034. public ByteStringAppender append(char c) {
  1035. writeByte(c);
  1036. return this;
  1037. }
  1038. @NotNull
  1039. @Override
  1040. public ByteStringAppender append(int num) {
  1041. return append((long) num);
  1042. }
  1043. @NotNull
  1044. @Override
  1045. public ByteStringAppender append(long num) {
  1046. if (num < 0) {
  1047. if (num == Long.MIN_VALUE) {
  1048. write(MIN_VALUE_TEXT);
  1049. return this;
  1050. }
  1051. writeByte('-');
  1052. num = -num;
  1053. }
  1054. if (num == 0) {
  1055. writeByte('0');
  1056. } else {
  1057. appendLong0(num);
  1058. }
  1059. return this;
  1060. }
  1061. @NotNull
  1062. @Override
  1063. public ByteStringAppender appendDate(long timeInMS) {
  1064. if (dateFormat == null) {
  1065. dateFormat = new SimpleDateFormat("yyyy/MM/dd");
  1066. dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
  1067. }
  1068. long date = timeInMS / 86400000;
  1069. if (lastDay != date) {
  1070. lastDateStr = dateFormat.format(new Date(timeInMS)).getBytes(ISO_8859_1);
  1071. lastDay = date;
  1072. }
  1073. assert lastDateStr != null;
  1074. append(lastDateStr);
  1075. return this;
  1076. }
  1077. @NotNull
  1078. @Override
  1079. public ByteStringAppender append(@NotNull byte[] str) {
  1080. write(str);
  1081. return this;
  1082. }
  1083. // // RandomOutputStream
  1084. @Override
  1085. public void write(@NotNull byte[] b) {
  1086. write(b, 0, b.length);
  1087. }
  1088. @NotNull
  1089. @Override
  1090. public ByteStringAppender appendDateTime(long timeInMS) {
  1091. appendDate(timeInMS);
  1092. writeByte('T');
  1093. appendTime(timeInMS);
  1094. return this;
  1095. }
  1096. @NotNull
  1097. @Override
  1098. public ByteStringAppender appendTime(long timeInMS) {
  1099. int hours = (int) (timeInMS / (60 * 60 * 1000));
  1100. if (hours > 99) {
  1101. appendLong0(hours); // can have over 24 hours.
  1102. } else {
  1103. writeByte((char) (hours / 10 + '0'));
  1104. writeByte((char) (hours % 10 + '0'));
  1105. }
  1106. writeByte(':');
  1107. int minutes = (int) ((timeInMS / (60 * 1000)) % 60);
  1108. writeByte((char) (minutes / 10 + '0'));
  1109. writeByte((char) (minutes % 10 + '0'));
  1110. writeByte(':');
  1111. int seconds = (int) ((timeInMS / 1000) % 60);
  1112. writeByte((char) (seconds / 10 + '0'));
  1113. writeByte((char) (seconds % 10 + '0'));
  1114. writeByte('.');
  1115. int millis = (int) (timeInMS % 1000);
  1116. writeByte((char) (millis / 100 + '0'));
  1117. writeByte((char) (millis / 10 % 10 + '0'));
  1118. writeByte((char) (millis % 10 + '0'));
  1119. return this;
  1120. }
  1121. @NotNull
  1122. @Override
  1123. public ByteStringAppender append(double d) {
  1124. long val = Double.doubleToRawLongBits(d);
  1125. int sign = (int) (val >>> 63);
  1126. int exp = (int) ((val >>> 52) & 2047);
  1127. long mantissa = val & ((1L << 52) - 1);
  1128. if (sign != 0) {
  1129. writeByte('-');
  1130. }
  1131. if (exp == 0 && mantissa == 0) {
  1132. writeByte('0');
  1133. return this;
  1134. } else if (exp == 2047) {
  1135. if (mantissa == 0) {
  1136. append(Infinity);
  1137. } else {
  1138. append(NaN);
  1139. }
  1140. return this;
  1141. } else if (exp > 0) {
  1142. mantissa += 1L << 52;
  1143. }
  1144. final int shift = (1023 + 52) - exp;
  1145. if (shift > 0) {
  1146. // integer and faction
  1147. if (shift < 53) {
  1148. long intValue = mantissa >> shift;
  1149. appendLong0(intValue);
  1150. mantissa -= intValue << shift;
  1151. if (mantissa > 0) {
  1152. writeByte('.');
  1153. mantissa <<= 1;
  1154. mantissa++;
  1155. int precision = shift + 1;
  1156. long error = 1;
  1157. long value = intValue;
  1158. int decimalPlaces = 0;
  1159. while (mantissa > error) {
  1160. // times 5*2 = 10
  1161. mantissa *= 5;
  1162. error *= 5;
  1163. precision--;
  1164. long num = (mantissa >> precision);
  1165. value = value * 10 + num;
  1166. writeByte((char) ('0' + num));
  1167. mantissa -= num << precision;
  1168. final double parsedValue = asDouble(value, 0, sign != 0, ++decimalPlaces);
  1169. if (parsedValue == d)
  1170. break;
  1171. }
  1172. }
  1173. return this;
  1174. } else {
  1175. // faction.
  1176. writeByte('0');
  1177. writeByte('.');
  1178. mantissa <<= 6;
  1179. mantissa += (1 << 5);
  1180. int precision = shift + 6;
  1181. long error = (1 << 5);
  1182. long value = 0;
  1183. int decimalPlaces = 0;
  1184. while (mantissa > error) {
  1185. while (mantissa > MAX_VALUE_DIVIDE_5) {
  1186. mantissa >>>= 1;
  1187. error = (error + 1) >>> 1;
  1188. precision--;
  1189. }
  1190. // times 5*2 = 10
  1191. mantissa *= 5;
  1192. error *= 5;
  1193. precision--;
  1194. if (precision >= 64) {
  1195. decimalPlaces++;
  1196. writeByte('0');
  1197. continue;
  1198. }
  1199. long num = (mantissa >>> precision);
  1200. value = value * 10 + num;
  1201. final char c = (char) ('0' + num);
  1202. assert !(c < '0' || c > '9');
  1203. writeByte(c);
  1204. mantissa -= num << precision;
  1205. final double parsedValue = asDouble(value, 0, sign != 0, ++decimalPlaces);
  1206. if (parsedValue == d)
  1207. break;
  1208. }
  1209. return this;
  1210. }
  1211. }
  1212. // large number
  1213. mantissa <<= 10;
  1214. int precision = -10 - shift;
  1215. int digits = 0;
  1216. while ((precision > 53 || mantissa > Long.MAX_VALUE >> precision) && precision > 0) {
  1217. digits++;
  1218. precision--;
  1219. long mod = mantissa % 5;
  1220. mantissa /= 5;
  1221. int modDiv = 1;
  1222. while (mantissa < MAX_VALUE_DIVIDE_5 && precision > 1) {
  1223. precision -= 1;
  1224. mantissa <<= 1;
  1225. modDiv <<= 1;
  1226. }
  1227. mantissa += modDiv * mod / 5;
  1228. }
  1229. long val2 = precision > 0 ? mantissa << precision : mantissa >>> -precision;
  1230. appendLong0(val2);
  1231. for (int i = 0; i < digits; i++)
  1232. writeByte('0');
  1233. return this;
  1234. }
  1235. @Override
  1236. public double parseDouble() {
  1237. long value = 0;
  1238. int exp = 0;
  1239. boolean negative = false;
  1240. int decimalPlaces = Integer.MIN_VALUE;
  1241. while (true) {
  1242. byte ch = readByte();
  1243. if (ch >= '0' && ch <= '9') {
  1244. while (value >= MAX_VALUE_DIVIDE_10) {
  1245. value >>>= 1;
  1246. exp++;
  1247. }
  1248. value = value * 10 + (ch - '0');
  1249. decimalPlaces++;
  1250. } else if (ch == '-') {
  1251. negative = true;
  1252. } else if (ch == '.') {
  1253. decimalPlaces = 0;
  1254. } else {
  1255. break;
  1256. }
  1257. }
  1258. return asDouble(value, exp, negative, decimalPlaces);
  1259. }
  1260. private void appendLong0(long num) {
  1261. // Extract digits into the end of the numberBuffer
  1262. int endIndex = appendLong1(num);
  1263. // Bulk copy the digits into the front of the buffer
  1264. write(numberBuffer, endIndex, MAX_NUMBER_LENGTH - endIndex);
  1265. }
  1266. private int appendLong1(long num) {
  1267. numberBuffer[19] = (byte) (num % 10L + '0');
  1268. num /= 10;
  1269. if (num <= 0)
  1270. return 19;
  1271. numberBuffer[18] = (byte) (num % 10L + '0');
  1272. num /= 10;
  1273. if (num <= 0)
  1274. return 18;
  1275. numberBuffer[17] = (byte) (num % 10L + '0');
  1276. num /= 10;
  1277. if (num <= 0)
  1278. return 17;
  1279. numberBuffer[16] = (byte) (num % 10L + '0');
  1280. num /= 10;
  1281. if (num <= 0)
  1282. return 16;
  1283. numberBuffer[15] = (byte) (num % 10L + '0');
  1284. num /= 10;
  1285. if (num <= 0)
  1286. return 15;
  1287. numberBuffer[14] = (byte) (num % 10L + '0');
  1288. num /= 10;
  1289. if (num <= 0)
  1290. return 14;
  1291. numberBuffer[13] = (byte) (num % 10L + '0');
  1292. num /= 10;
  1293. if (num <= 0)
  1294. return 13;
  1295. numberBuffer[12] = (byte) (num % 10L + '0');
  1296. num /= 10;
  1297. if (num <= 0)
  1298. return 12;
  1299. numberBuffer[11] = (byte) (num % 10L + '0');
  1300. num /= 10;
  1301. if (num <= 0)
  1302. return 11;
  1303. numberBuffer[10] = (byte) (num % 10L + '0');
  1304. num /= 10;
  1305. if (num <= 0)
  1306. return 10;
  1307. numberBuffer[9] = (byte) (num % 10L + '0');
  1308. num /= 10;
  1309. if (num <= 0)
  1310. return 9;
  1311. numberBuffer[8] = (byte) (num % 10L + '0');
  1312. num /= 10;
  1313. if (num <= 0)
  1314. return 8;
  1315. numberBuffer[7] = (byte) (num % 10L + '0');
  1316. num /= 10;
  1317. if (num <= 0)
  1318. return 7;
  1319. numberBuffer[6] = (byte) (num % 10L + '0');
  1320. num /= 10;
  1321. if (num <= 0)
  1322. return 6;
  1323. numberBuffer[5] = (byte) (num % 10L + '0');
  1324. num /= 10;
  1325. if (num <= 0)
  1326. return 5;
  1327. numberBuffer[4] = (byte) (num % 10L + '0');
  1328. num /= 10;
  1329. if (num <= 0)
  1330. return 4;
  1331. numberBuffer[3] = (byte) (num % 10L + '0');
  1332. num /= 10;
  1333. if (num <= 0)
  1334. return 3;
  1335. numberBuffer[2] = (byte) (num % 10L + '0');
  1336. num /= 10;
  1337. if (num <= 0)
  1338. return 2;
  1339. numberBuffer[1] = (byte) (num % 10L + '0');
  1340. num /= 10;
  1341. return 1;
  1342. }
  1343. @NotNull
  1344. @Override
  1345. public MutableDecimal parseDecimal(@NotNull MutableDecimal decimal) {
  1346. long num = 0, scale = Long.MIN_VALUE;
  1347. boolean negative = false;
  1348. do {
  1349. byte b = readByte();
  1350. // if (b >= '0' && b <= '9')
  1351. if ((b - ('0' + Integer.MIN_VALUE)) <= 9 + Integer.MIN_VALUE) {
  1352. num = num * 10 + b - '0';
  1353. scale++;
  1354. } else if (b == '.') {
  1355. scale = 0;
  1356. } else if (b == '-') {
  1357. negative = true;
  1358. } else {
  1359. break;
  1360. }
  1361. } while (true);
  1362. if (negative)
  1363. num = -num;
  1364. decimal.set(num, scale > 0 ? (int) scale : 0);
  1365. return decimal;
  1366. }
  1367. @Override
  1368. public long parseLong() {
  1369. long num = 0;
  1370. boolean negative = false;
  1371. do {
  1372. byte b = readByte();
  1373. // if (b >= '0' && b <= '9')
  1374. if ((b - ('0' + Integer.MIN_VALUE)) <= 9 + Integer.MIN_VALUE)
  1375. num = num * 10 + b - '0';
  1376. else if (b == '-')
  1377. negative = true;
  1378. else
  1379. break;
  1380. } while (true);
  1381. return negative ? -num : num;
  1382. }
  1383. @NotNull
  1384. @Override
  1385. public ByteStringAppender append(double d, int precision) {
  1386. if (precision < 0)
  1387. precision = 0;
  1388. if (precision >= TENS.length)
  1389. precision = TENS.length - 1;
  1390. long power10 = TENS[precision];
  1391. if (d < 0) {
  1392. d = -d;
  1393. writeByte('-');
  1394. }
  1395. double d2 = d * power10;
  1396. if (d2 > Long.MAX_VALUE || d2 < Long.MIN_VALUE + 1)
  1397. return append(d);
  1398. long val = (long) (d2 + 0.5);
  1399. while (precision > 1 && val % 10 == 0) {
  1400. val /= 10;
  1401. precision--;
  1402. }
  1403. if (precision > 0 && val % 10 == 0) {
  1404. val = (val + 5) / 10;
  1405. precision--;
  1406. }
  1407. if (precision > 0)
  1408. appendDouble0(val, precision);
  1409. else
  1410. appendLong0(val);
  1411. return this;
  1412. }
  1413. private void appendDouble0(long num, int precision) {
  1414. // Extract digits into the end of the numberBuffer
  1415. // Once desired precision is reached, write the '.'
  1416. int endIndex = appendDouble1(num, precision);
  1417. // Bulk copy the digits into the front of the buffer
  1418. // TODO: Can this be avoided with use of correctly offset bulk appends on Excerpt?
  1419. // Uses (numberBufferIdx - 1) because index was advanced one too many times
  1420. write(numberBuffer, endIndex, MAX_NUMBER_LENGTH - endIndex);
  1421. }
  1422. private int appendDouble1(long num, int precision) {
  1423. int endIndex = MAX_NUMBER_LENGTH;
  1424. int maxEnd = MAX_NUMBER_LENGTH - precision - 2;
  1425. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1426. num /= 10;
  1427. if (num <= 0 && endIndex <= maxEnd)
  1428. return endIndex;
  1429. if (precision == 1)
  1430. numberBuffer[--endIndex] = (byte) '.';
  1431. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1432. num /= 10;
  1433. if (num <= 0 && endIndex <= maxEnd)
  1434. return endIndex;
  1435. if (precision == 2)
  1436. numberBuffer[--endIndex] = (byte) '.';
  1437. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1438. num /= 10;
  1439. if (num <= 0 && endIndex <= maxEnd)
  1440. return endIndex;
  1441. if (precision == 3)
  1442. numberBuffer[--endIndex] = (byte) '.';
  1443. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1444. num /= 10;
  1445. if (num <= 0 && endIndex <= maxEnd)
  1446. return endIndex;
  1447. if (precision == 4)
  1448. numberBuffer[--endIndex] = (byte) '.';
  1449. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1450. num /= 10;
  1451. if (num <= 0 && endIndex <= maxEnd)
  1452. return endIndex;
  1453. if (precision == 5)
  1454. numberBuffer[--endIndex] = (byte) '.';
  1455. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1456. num /= 10;
  1457. if (num <= 0 && endIndex <= maxEnd)
  1458. return endIndex;
  1459. if (precision == 6)
  1460. numberBuffer[--endIndex] = (byte) '.';
  1461. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1462. num /= 10;
  1463. if (num <= 0 && endIndex <= maxEnd)
  1464. return endIndex;
  1465. if (precision == 7)
  1466. numberBuffer[--endIndex] = (byte) '.';
  1467. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1468. num /= 10;
  1469. if (num <= 0 && endIndex <= maxEnd)
  1470. return endIndex;
  1471. if (precision == 8)
  1472. numberBuffer[--endIndex] = (byte) '.';
  1473. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1474. num /= 10;
  1475. if (num <= 0 && endIndex <= maxEnd)
  1476. return endIndex;
  1477. if (precision == 9)
  1478. numberBuffer[--endIndex] = (byte) '.';
  1479. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1480. num /= 10;
  1481. if (num <= 0 && endIndex <= maxEnd)
  1482. return endIndex;
  1483. if (precision == 10)
  1484. numberBuffer[--endIndex] = (byte) '.';
  1485. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1486. num /= 10;
  1487. if (num <= 0 && endIndex <= maxEnd)
  1488. return endIndex;
  1489. if (precision == 11)
  1490. numberBuffer[--endIndex] = (byte) '.';
  1491. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1492. num /= 10;
  1493. if (num <= 0 && endIndex <= maxEnd)
  1494. return endIndex;
  1495. if (precision == 12)
  1496. numberBuffer[--endIndex] = (byte) '.';
  1497. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1498. num /= 10;
  1499. if (num <= 0 && endIndex <= maxEnd)
  1500. return endIndex;
  1501. if (precision == 13)
  1502. numberBuffer[--endIndex] = (byte) '.';
  1503. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1504. num /= 10;
  1505. if (num <= 0 && endIndex <= maxEnd)
  1506. return endIndex;
  1507. if (precision == 14)
  1508. numberBuffer[--endIndex] = (byte) '.';
  1509. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1510. num /= 10;
  1511. if (num <= 0 && endIndex <= maxEnd)
  1512. return endIndex;
  1513. if (precision == 15)
  1514. numberBuffer[--endIndex] = (byte) '.';
  1515. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1516. num /= 10;
  1517. if (num <= 0 && endIndex <= maxEnd)
  1518. return endIndex;

Large files files are truncated, but you can click here to view the full file