fork(1) download
  1. /* package whatever; // don't place package name! */
  2. /**
  3. Copyright 2020 Tschallacka
  4. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  5. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  7. */
  8. import java.util.*;
  9. import java.lang.*;
  10. import java.io.*;
  11.  
  12. /* Name of the class has to be "Main" only if the class is public. */
  13. class Ideone
  14. {
  15. public static void main (String[] args) throws java.lang.Exception
  16. {
  17. java.lang.reflect.Field[] clFields = TreeMap.class.getDeclaredFields();
  18. ArrayList<java.lang.reflect.Field> list = new ArrayList<>();
  19. int mask = java.lang.reflect.Modifier.STATIC | java.lang.reflect.Modifier.TRANSIENT;
  20.  
  21. for (int i = 0; i < clFields.length; i++) {
  22. // Check for non transient and non static fields.
  23. if ((clFields[i].getModifiers() & mask) == 0) {
  24. list.add(clFields[i]);
  25. System.out.println("Found field " + clFields[i].getName());
  26. }
  27. }
  28. int size = list.size();
  29. System.out.println(size);
  30.  
  31. BlockDataInputStream bin = new BlockDataInputStream(getTreeMapInputStream());
  32. bin.setBlockDataMode(false);
  33. short s0 = bin.readShort();
  34. short s1 = bin.readShort();
  35. if (s0 != java.io.ObjectStreamConstants.STREAM_MAGIC || s1 != java.io.ObjectStreamConstants.STREAM_VERSION) {
  36. String.format("invalid stream header: %04X%04X", s0, s1));
  37. }
  38. byte b = bin.readByte();
  39. if(b == java.io.ObjectStreamConstants.TC_OBJECT) {
  40. bin.readByte();
  41. String name = bin.readUTF();
  42. System.out.println(name);
  43. System.out.println("Is string ("+name+")it a java.util.TreeMap? "+(name.equals("java.util.TreeMap") ? "yes":"no"));
  44. bin.readLong();
  45. bin.readByte();
  46. short fields = bin.readShort();
  47. for(short i = 0; i < fields; i++) {
  48. bin.readByte();
  49. System.out.println("Read field name "+bin.readUTF());
  50. }
  51. }
  52.  
  53. }
  54.  
  55. public static ByteArrayInputStream getTreeMapInputStream() throws Exception {
  56. /* This is how to declare TreeMap */
  57. TreeMap<Integer, String> tmap =
  58. new TreeMap<Integer, String>();
  59.  
  60. /*Adding elements to TreeMap*/
  61. tmap.put(1, "Data1");
  62. tmap.put(23, "Data2");
  63. tmap.put(70, "Data3");
  64. tmap.put(4, "Data4");
  65. tmap.put(2, "Data5");
  66.  
  67. oos.writeObject( tmap );
  68. oos.close();
  69. return new ByteArrayInputStream(baos.toByteArray());
  70. }
  71. }
  72.  
  73. /* =========== END MIT - BELOW LICENSE APPLICABLE ON CODE BELOW ===================
  74.  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
  75.  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  76.  *
  77.  * This code is free software; you can redistribute it and/or modify it
  78.  * under the terms of the GNU General Public License version 2 only, as
  79.  * published by the Free Software Foundation. Oracle designates this
  80.  * particular file as subject to the "Classpath" exception as provided
  81.  * by Oracle in the LICENSE file that accompanied this code.
  82.  *
  83.  * This code is distributed in the hope that it will be useful, but WITHOUT
  84.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  85.  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  86.  * version 2 for more details (a copy is included in the LICENSE file that
  87.  * accompanied this code).
  88.  *
  89.  * You should have received a copy of the GNU General Public License version
  90.  * 2 along with this work; if not, write to the Free Software Foundation,
  91.  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  92.  *
  93.  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  94.  * or visit www.oracle.com if you need additional information or have any
  95.  * questions.
  96.  */
  97. class BlockDataInputStream
  98. extends InputStream implements DataInput
  99. {
  100. boolean defaultDataEnd = false;
  101. /** maximum data block length */
  102. private static final int MAX_BLOCK_SIZE = 1024;
  103. /** maximum data block header length */
  104. private static final int MAX_HEADER_SIZE = 5;
  105. /** (tunable) length of char buffer (for reading strings) */
  106. private static final int CHAR_BUF_SIZE = 256;
  107. /** readBlockHeader() return value indicating header read may block */
  108. private static final int HEADER_BLOCKED = -2;
  109.  
  110. /** buffer for reading general/block data */
  111. private final byte[] buf = new byte[MAX_BLOCK_SIZE];
  112. /** buffer for reading block data headers */
  113. private final byte[] hbuf = new byte[MAX_HEADER_SIZE];
  114. /** char buffer for fast string reads */
  115. private final char[] cbuf = new char[CHAR_BUF_SIZE];
  116.  
  117. /** block data mode */
  118. private boolean blkmode = false;
  119.  
  120. // block data state fields; values meaningful only when blkmode true
  121. /** current offset into buf */
  122. private int pos = 0;
  123. /** end offset of valid data in buf, or -1 if no more block data */
  124. private int end = -1;
  125. /** number of bytes in current block yet to be read from stream */
  126. private int unread = 0;
  127.  
  128. /** underlying stream (wrapped in peekable filter stream) */
  129. private final PeekInputStream in;
  130. /** loopback stream (for data reads that span data blocks) */
  131. private final DataInputStream din;
  132.  
  133. /**
  134.   * Creates new BlockDataInputStream on top of given underlying stream.
  135.   * Block data mode is turned off by default.
  136.   */
  137. BlockDataInputStream(InputStream in) {
  138. this.in = new PeekInputStream(in);
  139. din = new DataInputStream(this);
  140. }
  141.  
  142. /**
  143.   * Sets block data mode to the given mode (true == on, false == off)
  144.   * and returns the previous mode value. If the new mode is the same as
  145.   * the old mode, no action is taken. Throws IllegalStateException if
  146.   * block data mode is being switched from on to off while unconsumed
  147.   * block data is still present in the stream.
  148.   */
  149. boolean setBlockDataMode(boolean newmode) throws IOException {
  150. if (blkmode == newmode) {
  151. return blkmode;
  152. }
  153. if (newmode) {
  154. pos = 0;
  155. end = 0;
  156. unread = 0;
  157. } else if (pos < end) {
  158. throw new IllegalStateException("unread block data");
  159. }
  160. blkmode = newmode;
  161. return !blkmode;
  162. }
  163.  
  164. /**
  165.   * Returns true if the stream is currently in block data mode, false
  166.   * otherwise.
  167.   */
  168. boolean getBlockDataMode() {
  169. return blkmode;
  170. }
  171.  
  172. /**
  173.   * If in block data mode, skips to the end of the current group of data
  174.   * blocks (but does not unset block data mode). If not in block data
  175.   * mode, throws an IllegalStateException.
  176.   */
  177. void skipBlockData() throws IOException {
  178. if (!blkmode) {
  179. throw new IllegalStateException("not in block data mode");
  180. }
  181. while (end >= 0) {
  182. refill();
  183. }
  184. }
  185.  
  186. /**
  187.   * Attempts to read in the next block data header (if any). If
  188.   * canBlock is false and a full header cannot be read without possibly
  189.   * blocking, returns HEADER_BLOCKED, else if the next element in the
  190.   * stream is a block data header, returns the block data length
  191.   * specified by the header, else returns -1.
  192.   */
  193. private int readBlockHeader(boolean canBlock) throws IOException {
  194. if (defaultDataEnd) {
  195. /*
  196.   * Fix for 4360508: stream is currently at the end of a field
  197.   * value block written via default serialization; since there
  198.   * is no terminating TC_ENDBLOCKDATA tag, simulate
  199.   * end-of-custom-data behavior explicitly.
  200.   */
  201. return -1;
  202. }
  203. try {
  204. for (;;) {
  205. int avail = canBlock ? Integer.MAX_VALUE : in.available();
  206. if (avail == 0) {
  207. return HEADER_BLOCKED;
  208. }
  209.  
  210. int tc = in.peek();
  211. switch (tc) {
  212. case java.io.ObjectStreamConstants.TC_BLOCKDATA:
  213. if (avail < 2) {
  214. return HEADER_BLOCKED;
  215. }
  216. in.readFully(hbuf, 0, 2);
  217. return hbuf[1] & 0xFF;
  218.  
  219. case java.io.ObjectStreamConstants.TC_BLOCKDATALONG:
  220. if (avail < 5) {
  221. return HEADER_BLOCKED;
  222. }
  223. in.readFully(hbuf, 0, 5);
  224. int len = Bits.getInt(hbuf, 1);
  225. if (len < 0) {
  226. "illegal block data header length: " +
  227. len);
  228. }
  229. return len;
  230.  
  231. /*
  232.   * TC_RESETs may occur in between data blocks.
  233.   * Unfortunately, this case must be parsed at a lower
  234.   * level than other typecodes, since primitive data
  235.   * reads may span data blocks separated by a TC_RESET.
  236.   */
  237. case java.io.ObjectStreamConstants.TC_RESET:
  238. in.read();
  239.  
  240. break;
  241.  
  242. default:
  243. if (tc >= 0 && (tc < java.io.ObjectStreamConstants.TC_BASE || tc > java.io.ObjectStreamConstants.TC_MAX)) {
  244. String.format("invalid type code: %02X",
  245. tc));
  246. }
  247. return -1;
  248. }
  249. }
  250. } catch (EOFException ex) {
  251. "unexpected EOF while reading block data header");
  252. }
  253. }
  254.  
  255. /**
  256.   * Refills internal buffer buf with block data. Any data in buf at the
  257.   * time of the call is considered consumed. Sets the pos, end, and
  258.   * unread fields to reflect the new amount of available block data; if
  259.   * the next element in the stream is not a data block, sets pos and
  260.   * unread to 0 and end to -1.
  261.   */
  262. private void refill() throws IOException {
  263. try {
  264. do {
  265. pos = 0;
  266. if (unread > 0) {
  267. int n =
  268. in.read(buf, 0, Math.min(unread, MAX_BLOCK_SIZE));
  269. if (n >= 0) {
  270. end = n;
  271. unread -= n;
  272. } else {
  273. "unexpected EOF in middle of data block");
  274. }
  275. } else {
  276. int n = readBlockHeader(true);
  277. if (n >= 0) {
  278. end = 0;
  279. unread = n;
  280. } else {
  281. end = -1;
  282. unread = 0;
  283. }
  284. }
  285. } while (pos == end);
  286. } catch (IOException ex) {
  287. pos = 0;
  288. end = -1;
  289. unread = 0;
  290. throw ex;
  291. }
  292. }
  293.  
  294. /**
  295.   * If in block data mode, returns the number of unconsumed bytes
  296.   * remaining in the current data block. If not in block data mode,
  297.   * throws an IllegalStateException.
  298.   */
  299. int currentBlockRemaining() {
  300. if (blkmode) {
  301. return (end >= 0) ? (end - pos) + unread : 0;
  302. } else {
  303. throw new IllegalStateException();
  304. }
  305. }
  306.  
  307. /**
  308.   * Peeks at (but does not consume) and returns the next byte value in
  309.   * the stream, or -1 if the end of the stream/block data (if in block
  310.   * data mode) has been reached.
  311.   */
  312. int peek() throws IOException {
  313. if (blkmode) {
  314. if (pos == end) {
  315. refill();
  316. }
  317. return (end >= 0) ? (buf[pos] & 0xFF) : -1;
  318. } else {
  319. return in.peek();
  320. }
  321. }
  322.  
  323. /**
  324.   * Peeks at (but does not consume) and returns the next byte value in
  325.   * the stream, or throws EOFException if end of stream/block data has
  326.   * been reached.
  327.   */
  328. byte peekByte() throws IOException {
  329. int val = peek();
  330. if (val < 0) {
  331. throw new EOFException();
  332. }
  333. return (byte) val;
  334. }
  335.  
  336.  
  337. /* ----------------- generic input stream methods ------------------ */
  338. /*
  339.   * The following methods are equivalent to their counterparts in
  340.   * InputStream, except that they interpret data block boundaries and
  341.   * read the requested data from within data blocks when in block data
  342.   * mode.
  343.   */
  344.  
  345. public int read() throws IOException {
  346. if (blkmode) {
  347. if (pos == end) {
  348. refill();
  349. }
  350. return (end >= 0) ? (buf[pos++] & 0xFF) : -1;
  351. } else {
  352. return in.read();
  353. }
  354. }
  355.  
  356. public int read(byte[] b, int off, int len) throws IOException {
  357. return read(b, off, len, false);
  358. }
  359.  
  360. public long skip(long len) throws IOException {
  361. long remain = len;
  362. while (remain > 0) {
  363. if (blkmode) {
  364. if (pos == end) {
  365. refill();
  366. }
  367. if (end < 0) {
  368. break;
  369. }
  370. int nread = (int) Math.min(remain, end - pos);
  371. remain -= nread;
  372. pos += nread;
  373. } else {
  374. int nread = (int) Math.min(remain, MAX_BLOCK_SIZE);
  375. if ((nread = in.read(buf, 0, nread)) < 0) {
  376. break;
  377. }
  378. remain -= nread;
  379. }
  380. }
  381. return len - remain;
  382. }
  383.  
  384. public int available() throws IOException {
  385. if (blkmode) {
  386. if ((pos == end) && (unread == 0)) {
  387. int n;
  388. while ((n = readBlockHeader(false)) == 0) ;
  389. switch (n) {
  390. case HEADER_BLOCKED:
  391. break;
  392.  
  393. case -1:
  394. pos = 0;
  395. end = -1;
  396. break;
  397.  
  398. default:
  399. pos = 0;
  400. end = 0;
  401. unread = n;
  402. break;
  403. }
  404. }
  405. // avoid unnecessary call to in.available() if possible
  406. int unreadAvail = (unread > 0) ?
  407. Math.min(in.available(), unread) : 0;
  408. return (end >= 0) ? (end - pos) + unreadAvail : 0;
  409. } else {
  410. return in.available();
  411. }
  412. }
  413.  
  414. public void close() throws IOException {
  415. if (blkmode) {
  416. pos = 0;
  417. end = -1;
  418. unread = 0;
  419. }
  420. in.close();
  421. }
  422.  
  423. /**
  424.   * Attempts to read len bytes into byte array b at offset off. Returns
  425.   * the number of bytes read, or -1 if the end of stream/block data has
  426.   * been reached. If copy is true, reads values into an intermediate
  427.   * buffer before copying them to b (to avoid exposing a reference to
  428.   * b).
  429.   */
  430. int read(byte[] b, int off, int len, boolean copy) throws IOException {
  431. if (len == 0) {
  432. return 0;
  433. } else if (blkmode) {
  434. if (pos == end) {
  435. refill();
  436. }
  437. if (end < 0) {
  438. return -1;
  439. }
  440. int nread = Math.min(len, end - pos);
  441. System.arraycopy(buf, pos, b, off, nread);
  442. pos += nread;
  443. return nread;
  444. } else if (copy) {
  445. int nread = in.read(buf, 0, Math.min(len, MAX_BLOCK_SIZE));
  446. if (nread > 0) {
  447. System.arraycopy(buf, 0, b, off, nread);
  448. }
  449. return nread;
  450. } else {
  451. return in.read(b, off, len);
  452. }
  453. }
  454.  
  455. /* ----------------- primitive data input methods ------------------ */
  456. /*
  457.   * The following methods are equivalent to their counterparts in
  458.   * DataInputStream, except that they interpret data block boundaries
  459.   * and read the requested data from within data blocks when in block
  460.   * data mode.
  461.   */
  462.  
  463. public void readFully(byte[] b) throws IOException {
  464. readFully(b, 0, b.length, false);
  465. }
  466.  
  467. public void readFully(byte[] b, int off, int len) throws IOException {
  468. readFully(b, off, len, false);
  469. }
  470.  
  471. public void readFully(byte[] b, int off, int len, boolean copy)
  472. throws IOException
  473. {
  474. while (len > 0) {
  475. int n = read(b, off, len, copy);
  476. if (n < 0) {
  477. throw new EOFException();
  478. }
  479. off += n;
  480. len -= n;
  481. }
  482. }
  483.  
  484. public int skipBytes(int n) throws IOException {
  485. return din.skipBytes(n);
  486. }
  487.  
  488. public boolean readBoolean() throws IOException {
  489. int v = read();
  490. if (v < 0) {
  491. throw new EOFException();
  492. }
  493. return (v != 0);
  494. }
  495.  
  496. public byte readByte() throws IOException {
  497. int v = read();
  498. if (v < 0) {
  499. throw new EOFException();
  500. }
  501. return (byte) v;
  502. }
  503.  
  504. public int readUnsignedByte() throws IOException {
  505. int v = read();
  506. if (v < 0) {
  507. throw new EOFException();
  508. }
  509. return v;
  510. }
  511.  
  512. public char readChar() throws IOException {
  513. if (!blkmode) {
  514. pos = 0;
  515. in.readFully(buf, 0, 2);
  516. } else if (end - pos < 2) {
  517. return din.readChar();
  518. }
  519. char v = Bits.getChar(buf, pos);
  520. pos += 2;
  521. return v;
  522. }
  523.  
  524. public short readShort() throws IOException {
  525. if (!blkmode) {
  526. pos = 0;
  527. in.readFully(buf, 0, 2);
  528. } else if (end - pos < 2) {
  529. return din.readShort();
  530. }
  531. short v = Bits.getShort(buf, pos);
  532. pos += 2;
  533. return v;
  534. }
  535.  
  536. public int readUnsignedShort() throws IOException {
  537. if (!blkmode) {
  538. pos = 0;
  539. in.readFully(buf, 0, 2);
  540. } else if (end - pos < 2) {
  541. return din.readUnsignedShort();
  542. }
  543. int v = Bits.getShort(buf, pos) & 0xFFFF;
  544. pos += 2;
  545. return v;
  546. }
  547.  
  548. public int readInt() throws IOException {
  549. if (!blkmode) {
  550. pos = 0;
  551. in.readFully(buf, 0, 4);
  552. } else if (end - pos < 4) {
  553. return din.readInt();
  554. }
  555. int v = Bits.getInt(buf, pos);
  556. pos += 4;
  557. return v;
  558. }
  559.  
  560. public float readFloat() throws IOException {
  561. if (!blkmode) {
  562. pos = 0;
  563. in.readFully(buf, 0, 4);
  564. } else if (end - pos < 4) {
  565. return din.readFloat();
  566. }
  567. float v = Bits.getFloat(buf, pos);
  568. pos += 4;
  569. return v;
  570. }
  571.  
  572. public long readLong() throws IOException {
  573. if (!blkmode) {
  574. pos = 0;
  575. in.readFully(buf, 0, 8);
  576. } else if (end - pos < 8) {
  577. return din.readLong();
  578. }
  579. long v = Bits.getLong(buf, pos);
  580. pos += 8;
  581. return v;
  582. }
  583.  
  584. public double readDouble() throws IOException {
  585. if (!blkmode) {
  586. pos = 0;
  587. in.readFully(buf, 0, 8);
  588. } else if (end - pos < 8) {
  589. return din.readDouble();
  590. }
  591. double v = Bits.getDouble(buf, pos);
  592. pos += 8;
  593. return v;
  594. }
  595.  
  596. public String readUTF() throws IOException {
  597. return readUTFBody(readUnsignedShort());
  598. }
  599.  
  600. public String readLine() throws IOException {
  601. return din.readLine(); // deprecated, not worth optimizing
  602. }
  603.  
  604. /* -------------- primitive data array input methods --------------- */
  605. /*
  606.   * The following methods read in spans of primitive data values.
  607.   * Though equivalent to calling the corresponding primitive read
  608.   * methods repeatedly, these methods are optimized for reading groups
  609.   * of primitive data values more efficiently.
  610.   */
  611.  
  612. void readBooleans(boolean[] v, int off, int len) throws IOException {
  613. int stop, endoff = off + len;
  614. while (off < endoff) {
  615. if (!blkmode) {
  616. int span = Math.min(endoff - off, MAX_BLOCK_SIZE);
  617. in.readFully(buf, 0, span);
  618. stop = off + span;
  619. pos = 0;
  620. } else if (end - pos < 1) {
  621. v[off++] = din.readBoolean();
  622. continue;
  623. } else {
  624. stop = Math.min(endoff, off + end - pos);
  625. }
  626.  
  627. while (off < stop) {
  628. v[off++] = Bits.getBoolean(buf, pos++);
  629. }
  630. }
  631. }
  632.  
  633. void readChars(char[] v, int off, int len) throws IOException {
  634. int stop, endoff = off + len;
  635. while (off < endoff) {
  636. if (!blkmode) {
  637. int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1);
  638. in.readFully(buf, 0, span << 1);
  639. stop = off + span;
  640. pos = 0;
  641. } else if (end - pos < 2) {
  642. v[off++] = din.readChar();
  643. continue;
  644. } else {
  645. stop = Math.min(endoff, off + ((end - pos) >> 1));
  646. }
  647.  
  648. while (off < stop) {
  649. v[off++] = Bits.getChar(buf, pos);
  650. pos += 2;
  651. }
  652. }
  653. }
  654.  
  655. void readShorts(short[] v, int off, int len) throws IOException {
  656. int stop, endoff = off + len;
  657. while (off < endoff) {
  658. if (!blkmode) {
  659. int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1);
  660. in.readFully(buf, 0, span << 1);
  661. stop = off + span;
  662. pos = 0;
  663. } else if (end - pos < 2) {
  664. v[off++] = din.readShort();
  665. continue;
  666. } else {
  667. stop = Math.min(endoff, off + ((end - pos) >> 1));
  668. }
  669.  
  670. while (off < stop) {
  671. v[off++] = Bits.getShort(buf, pos);
  672. pos += 2;
  673. }
  674. }
  675. }
  676.  
  677. void readInts(int[] v, int off, int len) throws IOException {
  678. int stop, endoff = off + len;
  679. while (off < endoff) {
  680. if (!blkmode) {
  681. int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2);
  682. in.readFully(buf, 0, span << 2);
  683. stop = off + span;
  684. pos = 0;
  685. } else if (end - pos < 4) {
  686. v[off++] = din.readInt();
  687. continue;
  688. } else {
  689. stop = Math.min(endoff, off + ((end - pos) >> 2));
  690. }
  691.  
  692. while (off < stop) {
  693. v[off++] = Bits.getInt(buf, pos);
  694. pos += 4;
  695. }
  696. }
  697. }
  698. /**
  699.  * SERIOUSLY... this works? what the hell
  700.  */
  701.  
  702. private static native void bytesToFloats(byte[] src, int srcpos,
  703. float[] dst, int dstpos,
  704. int nfloats);
  705. private static native void bytesToDoubles(byte[] src, int srcpos,
  706. double[] dst, int dstpos,
  707. int ndoubles);
  708. void readFloats(float[] v, int off, int len) throws IOException {
  709. int span, endoff = off + len;
  710. while (off < endoff) {
  711. if (!blkmode) {
  712. span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2);
  713. in.readFully(buf, 0, span << 2);
  714. pos = 0;
  715. } else if (end - pos < 4) {
  716. v[off++] = din.readFloat();
  717. continue;
  718. } else {
  719. span = Math.min(endoff - off, ((end - pos) >> 2));
  720. }
  721.  
  722. bytesToFloats(buf, pos, v, off, span);
  723. off += span;
  724. pos += span << 2;
  725. }
  726. }
  727.  
  728. void readLongs(long[] v, int off, int len) throws IOException {
  729. int stop, endoff = off + len;
  730. while (off < endoff) {
  731. if (!blkmode) {
  732. int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3);
  733. in.readFully(buf, 0, span << 3);
  734. stop = off + span;
  735. pos = 0;
  736. } else if (end - pos < 8) {
  737. v[off++] = din.readLong();
  738. continue;
  739. } else {
  740. stop = Math.min(endoff, off + ((end - pos) >> 3));
  741. }
  742.  
  743. while (off < stop) {
  744. v[off++] = Bits.getLong(buf, pos);
  745. pos += 8;
  746. }
  747. }
  748. }
  749.  
  750. void readDoubles(double[] v, int off, int len) throws IOException {
  751. int span, endoff = off + len;
  752. while (off < endoff) {
  753. if (!blkmode) {
  754. span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3);
  755. in.readFully(buf, 0, span << 3);
  756. pos = 0;
  757. } else if (end - pos < 8) {
  758. v[off++] = din.readDouble();
  759. continue;
  760. } else {
  761. span = Math.min(endoff - off, ((end - pos) >> 3));
  762. }
  763.  
  764. bytesToDoubles(buf, pos, v, off, span);
  765. off += span;
  766. pos += span << 3;
  767. }
  768. }
  769.  
  770. /**
  771.   * Reads in string written in "long" UTF format. "Long" UTF format is
  772.   * identical to standard UTF, except that it uses an 8 byte header
  773.   * (instead of the standard 2 bytes) to convey the UTF encoding length.
  774.   */
  775. String readLongUTF() throws IOException {
  776. return readUTFBody(readLong());
  777. }
  778.  
  779. /**
  780.   * Reads in the "body" (i.e., the UTF representation minus the 2-byte
  781.   * or 8-byte length header) of a UTF encoding, which occupies the next
  782.   * utflen bytes.
  783.   */
  784. private String readUTFBody(long utflen) throws IOException {
  785. StringBuilder sbuf = new StringBuilder();
  786. if (!blkmode) {
  787. end = pos = 0;
  788. }
  789.  
  790. while (utflen > 0) {
  791. int avail = end - pos;
  792. if (avail >= 3 || (long) avail == utflen) {
  793. utflen -= readUTFSpan(sbuf, utflen);
  794. } else {
  795. if (blkmode) {
  796. // near block boundary, read one byte at a time
  797. utflen -= readUTFChar(sbuf, utflen);
  798. } else {
  799. // shift and refill buffer manually
  800. if (avail > 0) {
  801. System.arraycopy(buf, pos, buf, 0, avail);
  802. }
  803. pos = 0;
  804. end = (int) Math.min(MAX_BLOCK_SIZE, utflen);
  805. in.readFully(buf, avail, end - avail);
  806. }
  807. }
  808. }
  809.  
  810. return sbuf.toString();
  811. }
  812.  
  813. /**
  814.   * Reads span of UTF-encoded characters out of internal buffer
  815.   * (starting at offset pos and ending at or before offset end),
  816.   * consuming no more than utflen bytes. Appends read characters to
  817.   * sbuf. Returns the number of bytes consumed.
  818.   */
  819. private long readUTFSpan(StringBuilder sbuf, long utflen)
  820. throws IOException
  821. {
  822. int cpos = 0;
  823. int start = pos;
  824. int avail = Math.min(end - pos, CHAR_BUF_SIZE);
  825. // stop short of last char unless all of utf bytes in buffer
  826. int stop = pos + ((utflen > avail) ? avail - 2 : (int) utflen);
  827. boolean outOfBounds = false;
  828.  
  829. try {
  830. while (pos < stop) {
  831. int b1, b2, b3;
  832. b1 = buf[pos++] & 0xFF;
  833. switch (b1 >> 4) {
  834. case 0:
  835. case 1:
  836. case 2:
  837. case 3:
  838. case 4:
  839. case 5:
  840. case 6:
  841. case 7: // 1 byte format: 0xxxxxxx
  842. cbuf[cpos++] = (char) b1;
  843. break;
  844.  
  845. case 12:
  846. case 13: // 2 byte format: 110xxxxx 10xxxxxx
  847. b2 = buf[pos++];
  848. if ((b2 & 0xC0) != 0x80) {
  849. }
  850. cbuf[cpos++] = (char) (((b1 & 0x1F) << 6) |
  851. ((b2 & 0x3F) << 0));
  852. break;
  853.  
  854. case 14: // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx
  855. b3 = buf[pos + 1];
  856. b2 = buf[pos + 0];
  857. pos += 2;
  858. if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) {
  859. }
  860. cbuf[cpos++] = (char) (((b1 & 0x0F) << 12) |
  861. ((b2 & 0x3F) << 6) |
  862. ((b3 & 0x3F) << 0));
  863. break;
  864.  
  865. default: // 10xx xxxx, 1111 xxxx
  866. }
  867. }
  868. outOfBounds = true;
  869. } finally {
  870. if (outOfBounds || (pos - start) > utflen) {
  871. /*
  872.   * Fix for 4450867: if a malformed utf char causes the
  873.   * conversion loop to scan past the expected end of the utf
  874.   * string, only consume the expected number of utf bytes.
  875.   */
  876. pos = start + (int) utflen;
  877. }
  878. }
  879.  
  880. sbuf.append(cbuf, 0, cpos);
  881. return pos - start;
  882. }
  883.  
  884. /**
  885.   * Reads in single UTF-encoded character one byte at a time, appends
  886.   * the character to sbuf, and returns the number of bytes consumed.
  887.   * This method is used when reading in UTF strings written in block
  888.   * data mode to handle UTF-encoded characters which (potentially)
  889.   * straddle block-data boundaries.
  890.   */
  891. private int readUTFChar(StringBuilder sbuf, long utflen)
  892. throws IOException
  893. {
  894. int b1, b2, b3;
  895. b1 = readByte() & 0xFF;
  896. switch (b1 >> 4) {
  897. case 0:
  898. case 1:
  899. case 2:
  900. case 3:
  901. case 4:
  902. case 5:
  903. case 6:
  904. case 7: // 1 byte format: 0xxxxxxx
  905. sbuf.append((char) b1);
  906. return 1;
  907.  
  908. case 12:
  909. case 13: // 2 byte format: 110xxxxx 10xxxxxx
  910. if (utflen < 2) {
  911. }
  912. b2 = readByte();
  913. if ((b2 & 0xC0) != 0x80) {
  914. }
  915. sbuf.append((char) (((b1 & 0x1F) << 6) |
  916. ((b2 & 0x3F) << 0)));
  917. return 2;
  918.  
  919. case 14: // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx
  920. if (utflen < 3) {
  921. if (utflen == 2) {
  922. readByte(); // consume remaining byte
  923. }
  924. }
  925. b2 = readByte();
  926. b3 = readByte();
  927. if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) {
  928. }
  929. sbuf.append((char) (((b1 & 0x0F) << 12) |
  930. ((b2 & 0x3F) << 6) |
  931. ((b3 & 0x3F) << 0)));
  932. return 3;
  933.  
  934. default: // 10xx xxxx, 1111 xxxx
  935. }
  936. }
  937. }
  938. class PeekInputStream extends InputStream {
  939.  
  940. /** underlying stream */
  941. private final InputStream in;
  942. /** peeked byte */
  943. private int peekb = -1;
  944.  
  945. /**
  946.   * Creates new PeekInputStream on top of given underlying stream.
  947.   */
  948. PeekInputStream(InputStream in) {
  949. this.in = in;
  950. }
  951.  
  952. /**
  953.   * Peeks at next byte value in stream. Similar to read(), except
  954.   * that it does not consume the read value.
  955.   */
  956. int peek() throws IOException {
  957. return (peekb >= 0) ? peekb : (peekb = in.read());
  958. }
  959.  
  960. public int read() throws IOException {
  961. if (peekb >= 0) {
  962. int v = peekb;
  963. peekb = -1;
  964. return v;
  965. } else {
  966. return in.read();
  967. }
  968. }
  969.  
  970. public int read(byte[] b, int off, int len) throws IOException {
  971. if (len == 0) {
  972. return 0;
  973. } else if (peekb < 0) {
  974. return in.read(b, off, len);
  975. } else {
  976. b[off++] = (byte) peekb;
  977. len--;
  978. peekb = -1;
  979. int n = in.read(b, off, len);
  980. return (n >= 0) ? (n + 1) : 1;
  981. }
  982. }
  983.  
  984. void readFully(byte[] b, int off, int len) throws IOException {
  985. int n = 0;
  986. while (n < len) {
  987. int count = read(b, off + n, len - n);
  988. if (count < 0) {
  989. throw new EOFException();
  990. }
  991. n += count;
  992. }
  993. }
  994.  
  995. public long skip(long n) throws IOException {
  996. if (n <= 0) {
  997. return 0;
  998. }
  999. int skipped = 0;
  1000. if (peekb >= 0) {
  1001. peekb = -1;
  1002. skipped++;
  1003. n--;
  1004. }
  1005. return skipped + skip(n);
  1006. }
  1007.  
  1008. public int available() throws IOException {
  1009. return in.available() + ((peekb >= 0) ? 1 : 0);
  1010. }
  1011.  
  1012. public void close() throws IOException {
  1013. in.close();
  1014. }
  1015. }
  1016. class Bits {
  1017.  
  1018. /*
  1019.   * Methods for unpacking primitive values from byte arrays starting at
  1020.   * given offsets.
  1021.   */
  1022.  
  1023. static boolean getBoolean(byte[] b, int off) {
  1024. return b[off] != 0;
  1025. }
  1026.  
  1027. static char getChar(byte[] b, int off) {
  1028. return (char) ((b[off + 1] & 0xFF) +
  1029. (b[off] << 8));
  1030. }
  1031.  
  1032. static short getShort(byte[] b, int off) {
  1033. return (short) ((b[off + 1] & 0xFF) +
  1034. (b[off] << 8));
  1035. }
  1036.  
  1037. static int getInt(byte[] b, int off) {
  1038. return ((b[off + 3] & 0xFF) ) +
  1039. ((b[off + 2] & 0xFF) << 8) +
  1040. ((b[off + 1] & 0xFF) << 16) +
  1041. ((b[off ] ) << 24);
  1042. }
  1043.  
  1044. static float getFloat(byte[] b, int off) {
  1045. return Float.intBitsToFloat(getInt(b, off));
  1046. }
  1047.  
  1048. static long getLong(byte[] b, int off) {
  1049. return ((b[off + 7] & 0xFFL) ) +
  1050. ((b[off + 6] & 0xFFL) << 8) +
  1051. ((b[off + 5] & 0xFFL) << 16) +
  1052. ((b[off + 4] & 0xFFL) << 24) +
  1053. ((b[off + 3] & 0xFFL) << 32) +
  1054. ((b[off + 2] & 0xFFL) << 40) +
  1055. ((b[off + 1] & 0xFFL) << 48) +
  1056. (((long) b[off]) << 56);
  1057. }
  1058.  
  1059. static double getDouble(byte[] b, int off) {
  1060. return Double.longBitsToDouble(getLong(b, off));
  1061. }
  1062.  
  1063. /*
  1064.   * Methods for packing primitive values into byte arrays starting at given
  1065.   * offsets.
  1066.   */
  1067.  
  1068. static void putBoolean(byte[] b, int off, boolean val) {
  1069. b[off] = (byte) (val ? 1 : 0);
  1070. }
  1071.  
  1072. static void putChar(byte[] b, int off, char val) {
  1073. b[off + 1] = (byte) (val );
  1074. b[off ] = (byte) (val >>> 8);
  1075. }
  1076.  
  1077. static void putShort(byte[] b, int off, short val) {
  1078. b[off + 1] = (byte) (val );
  1079. b[off ] = (byte) (val >>> 8);
  1080. }
  1081.  
  1082. static void putInt(byte[] b, int off, int val) {
  1083. b[off + 3] = (byte) (val );
  1084. b[off + 2] = (byte) (val >>> 8);
  1085. b[off + 1] = (byte) (val >>> 16);
  1086. b[off ] = (byte) (val >>> 24);
  1087. }
  1088.  
  1089. static void putFloat(byte[] b, int off, float val) {
  1090. putInt(b, off, Float.floatToIntBits(val));
  1091. }
  1092.  
  1093. static void putLong(byte[] b, int off, long val) {
  1094. b[off + 7] = (byte) (val );
  1095. b[off + 6] = (byte) (val >>> 8);
  1096. b[off + 5] = (byte) (val >>> 16);
  1097. b[off + 4] = (byte) (val >>> 24);
  1098. b[off + 3] = (byte) (val >>> 32);
  1099. b[off + 2] = (byte) (val >>> 40);
  1100. b[off + 1] = (byte) (val >>> 48);
  1101. b[off ] = (byte) (val >>> 56);
  1102. }
  1103.  
  1104. static void putDouble(byte[] b, int off, double val) {
  1105. putLong(b, off, Double.doubleToLongBits(val));
  1106. }
  1107. }
Success #stdin #stdout 0.13s 38008KB
stdin
Standard input is empty
stdout
Found field comparator
1
java.util.TreeMap
Is string (java.util.TreeMap)it a java.util.TreeMap? yes
Read field name comparator