PageRenderTime 34ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 1ms

/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
  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;
  1519. if (precision == 16)
  1520. numberBuffer[--endIndex] = (byte) '.';
  1521. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1522. num /= 10;
  1523. if (num <= 0 && endIndex <= maxEnd)
  1524. return endIndex;
  1525. if (precision == 17)
  1526. numberBuffer[--endIndex] = (byte) '.';
  1527. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1528. num /= 10;
  1529. if (num <= 0 && endIndex <= maxEnd)
  1530. return endIndex;
  1531. if (precision == 18)
  1532. numberBuffer[--endIndex] = (byte) '.';
  1533. numberBuffer[--endIndex] = (byte) (num % 10L + '0');
  1534. return endIndex;
  1535. }
  1536. @NotNull
  1537. @Override
  1538. public ByteStringAppender append(@NotNull MutableDecimal md) {
  1539. StringBuilder sb = acquireUtfReader();
  1540. assert sb != null;
  1541. md.toString(sb);
  1542. append(sb);
  1543. return this;
  1544. }
  1545. @SuppressWarnings("unchecked")
  1546. @Override
  1547. public <E> E parseEnum(@NotNull Class<E> eClass, @NotNull StopCharTester tester) {
  1548. EnumeratedMarshaller<E> em = chronicle().acquireMarshaller(eClass);
  1549. return em.parse(this, tester);
  1550. }
  1551. @NotNull
  1552. @Override
  1553. public DirectChronicle chronicle() {
  1554. return chronicle;
  1555. }
  1556. @Override
  1557. public <E> void writeEnums(@NotNull Collection<E> eList) {
  1558. writeInt(eList.size());
  1559. for (E e : eList)
  1560. writeEnum(e);
  1561. }
  1562. @SuppressWarnings("unchecked")
  1563. @Override
  1564. public <E> void writeEnum(@Nullable E e) {
  1565. Class aClass;
  1566. if (e == null || e instanceof CharSequence)
  1567. aClass = String.class;
  1568. else
  1569. aClass = (Class) e.getClass();
  1570. EnumeratedMarshaller<E> em = chronicle().acquireMarshaller(aClass);
  1571. em.write(this, e);
  1572. }
  1573. @Override
  1574. public <E> void writeList(@NotNull Collection<E> list) {
  1575. writeInt(list.size());
  1576. for (E e : list)
  1577. writeObject(e);
  1578. }
  1579. @SuppressWarnings("unchecked")
  1580. @Override
  1581. public void writeObject(@Nullable Object obj) {
  1582. if (obj == null) {
  1583. writeByte(NULL);
  1584. return;
  1585. }
  1586. Class<?> clazz = obj.getClass();
  1587. EnumeratedMarshaller em = chronicle.getMarshaller(clazz);
  1588. if (em == null && autoGenerateMarshaller(obj))
  1589. em = chronicle.acquireMarshaller(clazz);
  1590. if (em != null) {
  1591. writeByte(ENUMED);
  1592. writeEnum(clazz);
  1593. em.write(this, obj);
  1594. return;
  1595. }
  1596. writeByte(SERIALIZED);
  1597. int pos = position();
  1598. writeInt(0); // padding
  1599. // TODO this is the lame implementation, but it works.
  1600. try {
  1601. ObjectOutputStream oos = new ObjectOutputStream(this.outputStream());
  1602. oos.writeObject(obj);
  1603. } catch (IOException e) {
  1604. throw new IllegalStateException(e);
  1605. }
  1606. // save the length for later.
  1607. writeInt(pos, position() - pos - 4);
  1608. checkEndOfBuffer();
  1609. }
  1610. @NotNull
  1611. @Override
  1612. public OutputStream outputStream() {
  1613. if (outputStream == null)
  1614. outputStream = new ExcerptOutputStream();
  1615. return outputStream;
  1616. }
  1617. private long checkEndOfBuffer() {
  1618. long length = position - start;
  1619. if (length < MIN_SIZE)
  1620. length = MIN_SIZE;
  1621. if (position > limit)
  1622. throw new IllegalStateException("Capacity allowed: " + capacity + " data read/written: " + length);
  1623. if (readLong(0) == 0)
  1624. throw new IllegalStateException("The first 8 bytes cannot be all zero");
  1625. return length;
  1626. }
  1627. private boolean autoGenerateMarshaller(Object obj) {
  1628. return (obj instanceof Comparable && obj.getClass().getPackage().getName().startsWith("java"))
  1629. || obj instanceof Externalizable
  1630. || obj instanceof ExcerptMarshaller;
  1631. }
  1632. @Override
  1633. public <K, V> void writeMap(@NotNull Map<K, V> map) {
  1634. writeInt(map.size());
  1635. for (Map.Entry<K, V> entry : map.entrySet()) {
  1636. writeEnum(entry.getKey());
  1637. writeEnum(entry.getValue());
  1638. }
  1639. }
  1640. @Override
  1641. public <E> void readEnums(@NotNull Class<E> eClass, @NotNull List<E> eList) {
  1642. eList.clear();
  1643. int len = readInt();
  1644. if (len == 0)
  1645. return;
  1646. for (int i = 0; i < len; i++)
  1647. eList.add(readEnum(eClass));
  1648. }
  1649. @SuppressWarnings("unchecked")
  1650. @Override
  1651. public <E> E readEnum(@NotNull Class<E> eClass) {
  1652. EnumeratedMarshaller<E> em = chronicle().acquireMarshaller(eClass);
  1653. return em.read(this);
  1654. }
  1655. @Override
  1656. public <E> void readList(@NotNull Collection<E> list) {
  1657. int len = readInt();
  1658. list.clear();
  1659. for (int i = 0; i < len; i++) {
  1660. @SuppressWarnings("unchecked")
  1661. E e = (E) readObject();
  1662. list.add(e);
  1663. }
  1664. }
  1665. @Nullable
  1666. @Override
  1667. public Object readObject() {
  1668. int type = readByte();
  1669. switch (type) {
  1670. case NULL:
  1671. return null;
  1672. case ENUMED: {
  1673. Class clazz = readEnum(Class.class);
  1674. assert clazz != null;
  1675. return readEnum(clazz);
  1676. }
  1677. case SERIALIZED: {
  1678. try {
  1679. int length = readInt();
  1680. if (length < 0 || length > 16 << 20)
  1681. throw new IllegalStateException("Unexpected length: " + length);
  1682. int end = position() + length;
  1683. Object o = new ObjectInputStream(this.inputStream()).readObject();
  1684. assert position() == end : "index: " + index + ", position: " + position() + ", end: " + end + " o: " + o;
  1685. return o;
  1686. } catch (Exception e) {
  1687. throw new IllegalStateException(e);
  1688. }
  1689. }
  1690. default:
  1691. throw new IllegalStateException("Unknown type " + (char) type);
  1692. }
  1693. }
  1694. @Nullable
  1695. @Override
  1696. public <T> T readObject(Class<T> tClass) throws IllegalStateException {
  1697. Object o = readObject();
  1698. if (o == null || tClass.isInstance(o))
  1699. return (T) o;
  1700. throw new ClassCastException("Cannot convert " + o.getClass().getName() + " to " + tClass.getName() + " was " + o);
  1701. }
  1702. @NotNull
  1703. @Override
  1704. public InputStream inputStream() {
  1705. if (inputStream == null)
  1706. inputStream = new ExcerptInputStream();
  1707. return inputStream;
  1708. }
  1709. @NotNull
  1710. @Override
  1711. public <K, V> Map<K, V> readMap(@NotNull Class<K> kClass, @NotNull Class<V> vClass) {
  1712. int len = readInt();
  1713. if (len == 0)
  1714. return Collections.emptyMap();
  1715. Map<K, V> map = new LinkedHashMap<K, V>(len * 10 / 7);
  1716. for (int i = 0; i < len; i++)
  1717. map.put(readEnum(kClass), readEnum(vClass));
  1718. return map;
  1719. }
  1720. @Override
  1721. public int available() {
  1722. return remaining();
  1723. }
  1724. @Override
  1725. public int read() {
  1726. return remaining() > 0 ? readByte() : -1;
  1727. }
  1728. @Override
  1729. public int read(@NotNull byte[] b) {
  1730. return read(b, 0, b.length);
  1731. }
  1732. @Override
  1733. public abstract int read(@NotNull byte[] b, int off, int len);
  1734. @Override
  1735. public long skip(long n) {
  1736. if (n < 0)
  1737. throw new IllegalArgumentException("Skip bytes out of range, was " + n);
  1738. if (n > remaining())
  1739. n = remaining();
  1740. skipBytes((int) n);
  1741. return n;
  1742. }
  1743. @Override
  1744. public int skipBytes(int n) {
  1745. int position = position();
  1746. int n2 = Math.min(n, capacity - position);
  1747. position(position + n2);
  1748. return n2;
  1749. }
  1750. @Override
  1751. public void close() {
  1752. if (!isFinished())
  1753. finish();
  1754. }
  1755. @Override
  1756. public boolean isFinished() {
  1757. return buffer == null;
  1758. }
  1759. @Override
  1760. public void finish() {
  1761. assert chronicle.multiThreaded() || checkThread();
  1762. long length = checkEndOfBuffer();
  1763. if (forWrite) {
  1764. if (chronicle.synchronousMode()) {
  1765. assert buffer != null;
  1766. buffer.force();
  1767. }
  1768. final long endPosition = startPosition + length;
  1769. chronicle.setIndexData(index + 1, endPosition);
  1770. chronicle.incrementSize(index + 1);
  1771. capacity = (int) length;
  1772. assert capacity >= MIN_SIZE : "len=" + length;
  1773. writeMemoryBarrier();
  1774. }
  1775. buffer = null;
  1776. }
  1777. private void writeMemoryBarrier() {
  1778. barrier.lazySet(true);
  1779. }
  1780. @SuppressWarnings("SameReturnValue")
  1781. private boolean checkThread() {
  1782. Thread thread = Thread.currentThread();
  1783. if (lastThread == null)
  1784. lastThread = thread;
  1785. else if (lastThread != thread)
  1786. throw new AssertionError("Excerpt used by two threads " + thread + " and " + lastThread);
  1787. return true;
  1788. }
  1789. @Override
  1790. public void flush() {
  1791. checkEndOfBuffer();
  1792. }
  1793. @NotNull
  1794. @Override
  1795. public Excerpt toStart() {
  1796. index(-1);
  1797. return this;
  1798. }
  1799. @NotNull
  1800. @Override
  1801. public Excerpt toEnd() {
  1802. index(size() - 1);
  1803. return this;
  1804. }
  1805. @Override
  1806. public long size() {
  1807. readMemoryBarrier();
  1808. long size = this.size - 1;
  1809. do {
  1810. size++;
  1811. } while (chronicle.getIndexData(size + 1) != 0);
  1812. return this.size = size;
  1813. }
  1814. @Override
  1815. public long findMatch(ExcerptComparator comparator) {
  1816. long lo = 0, hi = size() - 1;
  1817. while (lo <= hi) {
  1818. long mid = (hi + lo) >>> 1;
  1819. boolean found = index(mid);
  1820. assert found;
  1821. int cmp = comparator.compare(this);
  1822. finish();
  1823. if (cmp < 0)
  1824. lo = mid + 1;
  1825. else if (cmp > 0)
  1826. hi = mid - 1;
  1827. else
  1828. return mid; // key found
  1829. }
  1830. return ~lo; // -(lo + 1)
  1831. }
  1832. @Override
  1833. public void findRange(long[] startEnd, ExcerptComparator comparator) {
  1834. // lower search range
  1835. long lo1 = 0, hi1 = size() - 1;
  1836. // upper search range
  1837. long lo2 = 0, hi2 = hi1;
  1838. boolean both = true;
  1839. // search for the low values.
  1840. while (lo1 <= hi1) {
  1841. long mid = (hi1 + lo1) >>> 1;
  1842. boolean found = index(mid);
  1843. assert found;
  1844. int cmp = comparator.compare(this);
  1845. finish();
  1846. if (cmp < 0) {
  1847. lo1 = mid + 1;
  1848. if (both)
  1849. lo2 = lo1;
  1850. } else if (cmp > 0) {
  1851. hi1 = mid - 1;
  1852. if (both)
  1853. hi2 = hi1;
  1854. } else {
  1855. hi1 = mid - 1;
  1856. if (both)
  1857. lo2 = mid + 1;
  1858. both = false;
  1859. }
  1860. }
  1861. // search for the high values.
  1862. while (lo2 <= hi2) {
  1863. long mid = (hi2 + lo2) >>> 1;
  1864. if (!index(mid)) {
  1865. if (mid > lo2)
  1866. index(--mid);
  1867. else
  1868. break;
  1869. }
  1870. int cmp = comparator.compare(this);
  1871. finish();
  1872. if (cmp <= 0) {
  1873. lo2 = mid + 1;
  1874. } else {
  1875. hi2 = mid - 1;
  1876. }
  1877. }
  1878. startEnd[0] = lo1; // inclusive
  1879. startEnd[1] = lo2; // exclusive
  1880. }
  1881. protected class ExcerptInputStream extends InputStream {
  1882. private int mark = 0;
  1883. @Override
  1884. public int available() throws IOException {
  1885. return remaining();
  1886. }
  1887. @Override
  1888. public void close() throws IOException {
  1889. finish();
  1890. }
  1891. @Override
  1892. public void mark(int readlimit) {
  1893. mark = position();
  1894. }
  1895. @Override
  1896. public boolean markSupported() {
  1897. return true;
  1898. }
  1899. @Override
  1900. public int read(byte[] b, int off, int len) throws IOException {
  1901. return AbstractExcerpt.this.read(b, off, len);
  1902. }
  1903. @Override
  1904. public void reset() throws IOException {
  1905. position(mark);
  1906. }
  1907. @Override
  1908. public long skip(long n) throws IOException {
  1909. if (n > Integer.MAX_VALUE)
  1910. throw new IOException("Skip too large");
  1911. return skipBytes((int) n);
  1912. }
  1913. @Override
  1914. public int read() throws IOException {
  1915. if (remaining() > 0)
  1916. return readUnsignedByte();
  1917. return -1;
  1918. }
  1919. }
  1920. protected class ExcerptOutputStream extends OutputStream {
  1921. @Override
  1922. public void close() throws IOException {
  1923. finish();
  1924. }
  1925. @Override
  1926. public void write(@NotNull byte[] b) throws IOException {
  1927. AbstractExcerpt.this.write(b);
  1928. }
  1929. @Override
  1930. public void write(byte[] b, int off, int len) throws IOException {
  1931. AbstractExcerpt.this.write(b, off, len);
  1932. }
  1933. @Override
  1934. public void write(int b) throws IOException {
  1935. writeUnsignedByte(b);
  1936. }
  1937. }
  1938. }