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