Changeset 13061 in josm for trunk/src/com/drew/lang


Ignore:
Timestamp:
2017-10-30T22:46:09+01:00 (8 years ago)
Author:
Don-vip
Message:

fix #15505 - update to metadata-extractor 2.10.1

Location:
trunk/src/com/drew/lang
Files:
4 added
2 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/com/drew/lang/BufferBoundsException.java

    r10862 r13061  
    11/*
    2  * Copyright 2002-2016 Drew Noakes
     2 * Copyright 2002-2017 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/lang/ByteArrayReader.java

    r10862 r13061  
    11/*
    2  * Copyright 2002-2016 Drew Noakes
     2 * Copyright 2002-2017 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    2222package com.drew.lang;
    2323
     24import com.drew.lang.annotations.NotNull;
     25
    2426import java.io.IOException;
    25 
    26 import com.drew.lang.annotations.NotNull;
    2727
    2828/**
     
    3939    @NotNull
    4040    private final byte[] _buffer;
     41    private final int _baseOffset;
    4142
     43    @SuppressWarnings({ "ConstantConditions" })
     44    @com.drew.lang.annotations.SuppressWarnings(value = "EI_EXPOSE_REP2", justification = "Design intent")
    4245    public ByteArrayReader(@NotNull byte[] buffer)
     46    {
     47        this(buffer, 0);
     48    }
     49
     50    @SuppressWarnings({ "ConstantConditions" })
     51    @com.drew.lang.annotations.SuppressWarnings(value = "EI_EXPOSE_REP2", justification = "Design intent")
     52    public ByteArrayReader(@NotNull byte[] buffer, int baseOffset)
    4353    {
    4454        if (buffer == null)
    4555            throw new NullPointerException();
     56        if (baseOffset < 0)
     57            throw new IllegalArgumentException("Must be zero or greater");
    4658
    4759        _buffer = buffer;
     60        _baseOffset = baseOffset;
     61    }
     62
     63    @Override
     64    public int toUnshiftedOffset(int localOffset)
     65    {
     66        return localOffset + _baseOffset;
    4867    }
    4968
     
    5170    public long getLength()
    5271    {
    53         return _buffer.length;
     72        return _buffer.length - _baseOffset;
    5473    }
    5574
    5675    @Override
    57     protected byte getByte(int index) throws IOException
     76    public byte getByte(int index) throws IOException
    5877    {
    59         return _buffer[index];
     78        validateIndex(index, 1);
     79        return _buffer[index + _baseOffset];
    6080    }
    6181
     
    6484    {
    6585        if (!isValidIndex(index, bytesRequested))
    66             throw new BufferBoundsException(index, bytesRequested, _buffer.length);
     86            throw new BufferBoundsException(toUnshiftedOffset(index), bytesRequested, _buffer.length);
    6787    }
    6888
     
    7292        return bytesRequested >= 0
    7393            && index >= 0
    74             && (long)index + (long)bytesRequested - 1L < _buffer.length;
     94            && (long)index + (long)bytesRequested - 1L < getLength();
    7595    }
    7696
     
    82102
    83103        byte[] bytes = new byte[count];
    84         System.arraycopy(_buffer, index, bytes, 0, count);
     104        System.arraycopy(_buffer, index + _baseOffset, bytes, 0, count);
    85105        return bytes;
    86106    }
  • trunk/src/com/drew/lang/CompoundException.java

    r10862 r13061  
    11/*
    2  * Copyright 2002-2016 Drew Noakes
     2 * Copyright 2002-2017 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/lang/GeoLocation.java

    r10862 r13061  
    11/*
    2  * Copyright 2002-2016 Drew Noakes
     2 * Copyright 2002-2017 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/lang/RandomAccessReader.java

    r10862 r13061  
    11/*
    2  * Copyright 2002-2016 Drew Noakes
     2 * Copyright 2002-2017 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    2222package com.drew.lang;
    2323
    24 import com.drew.lang.annotations.NotNull;
    25 
    2624import java.io.IOException;
    2725import java.io.UnsupportedEncodingException;
     26import java.nio.charset.Charset;
     27
     28import com.drew.lang.annotations.NotNull;
     29import com.drew.lang.annotations.Nullable;
     30import com.drew.metadata.StringValue;
    2831
    2932/**
     
    3639 * <ul>
    3740 *     <li>{@link ByteArrayReader}</li>
    38  *     <li>{@link RandomAccessStreamReader}</li>
    3941 * </ul>
    4042 *
     
    4547    private boolean _isMotorolaByteOrder = true;
    4648
     49    public abstract int toUnshiftedOffset(int localOffset);
     50
    4751    /**
    4852     * Gets the byte value at the specified byte <code>index</code>.
     
    5761     * @throws IOException if the byte is unable to be read
    5862     */
    59     protected abstract byte getByte(int index) throws IOException;
     63    public abstract byte getByte(int index) throws IOException;
    6064
    6165    /**
     
    8993     * Returns the length of the data source in bytes.
    9094     * <p>
    91      * This is a simple operation for implementations (such as {@link RandomAccessFileReader} and
     95     * This is a simple operation for implementations (such as
    9296     * {@link ByteArrayReader}) that have the entire data source available.
    9397     * <p>
    94      * Users of this method must be aware that sequentially accessed implementations such as
    95      * {@link RandomAccessStreamReader} will have to read and buffer the entire data source in
     98     * Users of this method must be aware that sequentially accessed implementations
     99     * will have to read and buffer the entire data source in
    96100     * order to determine the length.
    97101     *
     
    207211        if (_isMotorolaByteOrder) {
    208212            // Motorola - MSB first
    209             return (short) (((short)getByte(index    ) << 8 & (short)0xFF00) |
    210                             ((short)getByte(index + 1)      & (short)0xFF));
     213            return (short) ((getByte(index    ) << 8 & (short)0xFF00) |
     214                            (getByte(index + 1)      & (short)0xFF));
    211215        } else {
    212216            // Intel ordering - LSB first
    213             return (short) (((short)getByte(index + 1) << 8 & (short)0xFF00) |
    214                             ((short)getByte(index    )      & (short)0xFF));
     217            return (short) ((getByte(index + 1) << 8 & (short)0xFF00) |
     218                            (getByte(index    )      & (short)0xFF));
    215219        }
    216220    }
     
    229233        if (_isMotorolaByteOrder) {
    230234            // Motorola - MSB first (big endian)
    231             return (((int)getByte(index    )) << 16 & 0xFF0000) |
    232                    (((int)getByte(index + 1)) << 8  & 0xFF00) |
    233                    (((int)getByte(index + 2))       & 0xFF);
     235            return ((getByte(index    )) << 16 & 0xFF0000) |
     236                   ((getByte(index + 1)) << 8  & 0xFF00) |
     237                   ((getByte(index + 2))       & 0xFF);
    234238        } else {
    235239            // Intel ordering - LSB first (little endian)
    236             return (((int)getByte(index + 2)) << 16 & 0xFF0000) |
    237                    (((int)getByte(index + 1)) << 8  & 0xFF00) |
    238                    (((int)getByte(index    ))       & 0xFF);
     240            return ((getByte(index + 2)) << 16 & 0xFF0000) |
     241                   ((getByte(index + 1)) << 8  & 0xFF00) |
     242                   ((getByte(index    ))       & 0xFF);
    239243        }
    240244    }
     
    256260                   (((long)getByte(index + 1)) << 16 & 0xFF0000L) |
    257261                   (((long)getByte(index + 2)) << 8  & 0xFF00L) |
    258                    (((long)getByte(index + 3))       & 0xFFL);
     262                   ((getByte(index + 3))       & 0xFFL);
    259263        } else {
    260264            // Intel ordering - LSB first (little endian)
     
    262266                   (((long)getByte(index + 2)) << 16 & 0xFF0000L) |
    263267                   (((long)getByte(index + 1)) << 8  & 0xFF00L) |
    264                    (((long)getByte(index    ))       & 0xFFL);
     268                   ((getByte(index    ))       & 0xFFL);
    265269        }
    266270    }
     
    312316                   ((long)getByte(index + 5) << 16 & 0xFF0000L) |
    313317                   ((long)getByte(index + 6) << 8  & 0xFF00L) |
    314                    ((long)getByte(index + 7)       & 0xFFL);
     318                   (getByte(index + 7)       & 0xFFL);
    315319        } else {
    316320            // Intel ordering - LSB first
     
    322326                   ((long)getByte(index + 2) << 16 & 0xFF0000L) |
    323327                   ((long)getByte(index + 1) << 8  & 0xFF00L) |
    324                    ((long)getByte(index    )       & 0xFFL);
     328                   (getByte(index    )       & 0xFFL);
    325329        }
    326330    }
     
    365369
    366370    @NotNull
    367     public String getString(int index, int bytesRequested) throws IOException
    368     {
    369         return new String(getBytes(index, bytesRequested));
    370     }
    371 
    372     @NotNull
    373     public String getString(int index, int bytesRequested, String charset) throws IOException
     371    public StringValue getStringValue(int index, int bytesRequested, @Nullable Charset charset) throws IOException
     372    {
     373        return new StringValue(getBytes(index, bytesRequested), charset);
     374    }
     375
     376    @NotNull
     377    public String getString(int index, int bytesRequested, @NotNull Charset charset) throws IOException
     378    {
     379        return new String(getBytes(index, bytesRequested), charset.name());
     380    }
     381
     382    @NotNull
     383    public String getString(int index, int bytesRequested, @NotNull String charset) throws IOException
    374384    {
    375385        byte[] bytes = getBytes(index, bytesRequested);
     
    392402     */
    393403    @NotNull
    394     public String getNullTerminatedString(int index, int maxLengthBytes) throws IOException
    395     {
    396         // NOTE currently only really suited to single-byte character strings
    397 
    398         byte[] bytes = getBytes(index, maxLengthBytes);
     404    public String getNullTerminatedString(int index, int maxLengthBytes, @NotNull Charset charset) throws IOException
     405    {
     406        return new String(getNullTerminatedBytes(index, maxLengthBytes), charset.name());
     407    }
     408
     409    @NotNull
     410    public StringValue getNullTerminatedStringValue(int index, int maxLengthBytes, @Nullable Charset charset) throws IOException
     411    {
     412        byte[] bytes = getNullTerminatedBytes(index, maxLengthBytes);
     413
     414        return new StringValue(bytes, charset);
     415    }
     416
     417    /**
     418     * Returns the sequence of bytes punctuated by a <code>\0</code> value.
     419     *
     420     * @param index The index within the buffer at which to start reading the string.
     421     * @param maxLengthBytes The maximum number of bytes to read. If a <code>\0</code> byte is not reached within this limit,
     422     * the returned array will be <code>maxLengthBytes</code> long.
     423     * @return The read byte array, excluding the null terminator.
     424     * @throws IOException The buffer does not contain enough bytes to satisfy this request.
     425     */
     426    @NotNull
     427    public byte[] getNullTerminatedBytes(int index, int maxLengthBytes) throws IOException
     428    {
     429        byte[] buffer = getBytes(index, maxLengthBytes);
    399430
    400431        // Count the number of non-null bytes
    401432        int length = 0;
    402         while (length < bytes.length && bytes[length] != '\0')
     433        while (length < buffer.length && buffer[length] != 0)
    403434            length++;
    404435
    405         return new String(bytes, 0, length);
     436        if (length == maxLengthBytes)
     437            return buffer;
     438
     439        byte[] bytes = new byte[length];
     440        if (length > 0)
     441            System.arraycopy(buffer, 0, bytes, 0, length);
     442        return bytes;
    406443    }
    407444}
  • trunk/src/com/drew/lang/Rational.java

    r10862 r13061  
    11/*
    2  * Copyright 2002-2016 Drew Noakes
     2 * Copyright 2002-2017 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    3636 * @author Drew Noakes https://drewnoakes.com
    3737 */
    38 public class Rational extends java.lang.Number implements Serializable
     38@SuppressWarnings("WeakerAccess")
     39public class Rational extends java.lang.Number implements Comparable<Rational>, Serializable
    3940{
    4041    private static final long serialVersionUID = 510688928138848770L;
     
    173174                (_denominator != 0 && (_numerator % _denominator == 0)) ||
    174175                (_denominator == 0 && _numerator == 0);
     176    }
     177
     178    /** Checks if either the numerator or denominator are zero. */
     179    public boolean isZero()
     180    {
     181        return _numerator == 0 || _denominator == 0;
    175182    }
    176183
     
    212219
    213220    /**
    214      * Decides whether a brute-force simplification calculation should be avoided
    215      * by comparing the maximum number of possible calculations with some threshold.
    216      *
    217      * @return true if the simplification should be performed, otherwise false
    218      */
    219     private boolean tooComplexForSimplification()
    220     {
    221         double maxPossibleCalculations = (((double) (Math.min(_denominator, _numerator) - 1) / 5d) + 2);
    222         final int maxSimplificationCalculations = 1000;
    223         return maxPossibleCalculations > maxSimplificationCalculations;
     221     * Compares two {@link Rational} instances, returning true if they are mathematically
     222     * equivalent (in consistence with {@link Rational#equals(Object)} method).
     223     *
     224     * @param that the {@link Rational} to compare this instance to.
     225     * @return the value {@code 0} if this {@link Rational} is
     226     *         equal to the argument {@link Rational} mathematically; a value less
     227     *         than {@code 0} if this {@link Rational} is less
     228     *         than the argument {@link Rational}; and a value greater
     229     *         than {@code 0} if this {@link Rational} is greater than the argument
     230     *         {@link Rational}.
     231     */
     232    public int compareTo(@NotNull Rational that) {
     233        return Double.compare(this.doubleValue(), that.doubleValue());
     234    }
     235
     236    /**
     237     * Indicates whether this instance and <code>other</code> are numerically equal,
     238     * even if their representations differ.
     239     *
     240     * For example, 1/2 is equal to 10/20 by this method.
     241     * Similarly, 1/0 is equal to 100/0 by this method.
     242     * To test equal representations, use EqualsExact.
     243     *
     244     * @param other The rational value to compare with
     245     */
     246    public boolean equals(Rational other) {
     247        return other.doubleValue() == doubleValue();
     248    }
     249
     250    /**
     251     * Indicates whether this instance and <code>other</code> have identical
     252     * Numerator and Denominator.
     253     * <p>
     254     * For example, 1/2 is not equal to 10/20 by this method.
     255     * Similarly, 1/0 is not equal to 100/0 by this method.
     256     * To test numerically equivalence, use Equals(Rational).</p>
     257     *
     258     * @param other The rational value to compare with
     259     */
     260    public boolean equalsExact(Rational other) {
     261        return getDenominator() == other.getDenominator() && getNumerator() == other.getNumerator();
    224262    }
    225263
     
    249287    /**
    250288     * <p>
    251      * Simplifies the {@link Rational} number.</p>
     289     * Simplifies the representation of this {@link Rational} number.</p>
    252290     * <p>
    253      * Prime number series: 1, 2, 3, 5, 7, 9, 11, 13, 17</p>
     291     * For example, 5/10 simplifies to 1/2 because both Numerator
     292     * and Denominator share a common factor of 5.</p>
    254293     * <p>
    255      * To reduce a rational, need to see if both numerator and denominator are divisible
    256      * by a common factor.  Using the prime number series in ascending order guarantees
    257      * the minimum number of checks required.</p>
    258      * <p>
    259      * However, generating the prime number series seems to be a hefty task.  Perhaps
    260      * it's simpler to check if both d &amp; n are divisible by all numbers from 2 {@literal ->}
    261      * (Math.min(denominator, numerator) / 2).  In doing this, one can check for 2
    262      * and 5 once, then ignore all even numbers, and all numbers ending in 0 or 5.
    263      * This leaves four numbers from every ten to check.</p>
    264      * <p>
    265      * Therefore, the max number of pairs of modulus divisions required will be:</p>
    266      * <pre><code>
    267      *    4   Math.min(denominator, numerator) - 1
    268      *   -- * ------------------------------------ + 2
    269      *   10                    2
    270      *
    271      *   Math.min(denominator, numerator) - 1
    272      * = ------------------------------------ + 2
    273      *                  5
    274      * </code></pre>
    275      *
    276      * @return a simplified instance, or if the Rational could not be simplified,
    277      *         returns itself (unchanged)
     294     * Uses the Euclidean Algorithm to find the greatest common divisor.</p>
     295     *
     296     * @return A simplified instance if one exists, otherwise a copy of the original value.
    278297     */
    279298    @NotNull
    280299    public Rational getSimplifiedInstance()
    281300    {
    282         if (tooComplexForSimplification()) {
    283             return this;
     301        long gcd = GCD(_numerator, _denominator);
     302
     303        return new Rational(_numerator / gcd, _denominator / gcd);
     304    }
     305
     306    private static long GCD(long a, long b)
     307    {
     308        if (a < 0)
     309            a = -a;
     310        if (b < 0)
     311            b = -b;
     312
     313        while (a != 0 && b != 0)
     314        {
     315            if (a > b)
     316                a %= b;
     317            else
     318                b %= a;
    284319        }
    285         for (int factor = 2; factor <= Math.min(_denominator, _numerator); factor++) {
    286             if ((factor % 2 == 0 && factor > 2) || (factor % 5 == 0 && factor > 5)) {
    287                 continue;
    288             }
    289             if (_denominator % factor == 0 && _numerator % factor == 0) {
    290                 // found a common factor
    291                 return new Rational(_numerator / factor, _denominator / factor);
    292             }
    293         }
    294         return this;
     320
     321        return a == 0 ? b : a;
    295322    }
    296323}
  • trunk/src/com/drew/lang/SequentialByteArrayReader.java

    r10862 r13061  
    11/*
    2  * Copyright 2002-2016 Drew Noakes
     2 * Copyright 2002-2017 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    3737    private int _index;
    3838
     39    @Override
     40    public long getPosition()
     41    {
     42        return _index;
     43    }
     44
    3945    public SequentialByteArrayReader(@NotNull byte[] bytes)
    4046    {
     
    4248    }
    4349
     50    @SuppressWarnings("ConstantConditions")
    4451    public SequentialByteArrayReader(@NotNull byte[] bytes, int baseIndex)
    4552    {
     
    5259
    5360    @Override
    54     protected byte getByte() throws IOException
     61    public byte getByte() throws IOException
    5562    {
    5663        if (_index >= _bytes.length) {
     
    7380
    7481        return bytes;
     82    }
     83
     84    @Override
     85    public void getBytes(@NotNull byte[] buffer, int offset, int count) throws IOException
     86    {
     87        if (_index + count > _bytes.length) {
     88            throw new EOFException("End of data reached.");
     89        }
     90
     91        System.arraycopy(_bytes, _index, buffer, offset, count);
     92        _index += count;
    7593    }
    7694
     
    105123        return true;
    106124    }
     125
     126    @Override
     127    public int available() {
     128        return _bytes.length - _index;
     129    }
    107130}
  • trunk/src/com/drew/lang/SequentialReader.java

    r10862 r13061  
    11/*
    2  * Copyright 2002-2016 Drew Noakes
     2 * Copyright 2002-2017 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    2323
    2424import com.drew.lang.annotations.NotNull;
     25import com.drew.lang.annotations.Nullable;
     26import com.drew.metadata.StringValue;
    2527
    2628import java.io.EOFException;
    2729import java.io.IOException;
    2830import java.io.UnsupportedEncodingException;
     31import java.nio.charset.Charset;
    2932
    3033/**
    3134 * @author Drew Noakes https://drewnoakes.com
    3235 */
     36@SuppressWarnings("WeakerAccess")
    3337public abstract class SequentialReader
    3438{
     
    3741    private boolean _isMotorolaByteOrder = true;
    3842
     43    public abstract long getPosition() throws IOException;
     44
    3945    /**
    4046     * Gets the next byte in the sequence.
     
    4248     * @return The read byte value
    4349     */
    44     protected abstract byte getByte() throws IOException;
     50    public abstract byte getByte() throws IOException;
    4551
    4652    /**
     
    5258    @NotNull
    5359    public abstract byte[] getBytes(int count) throws IOException;
     60
     61    /**
     62     * Retrieves bytes, writing them into a caller-provided buffer.
     63     * @param buffer The array to write bytes to.
     64     * @param offset The starting position within buffer to write to.
     65     * @param count The number of bytes to be written.
     66     */
     67    public abstract void getBytes(@NotNull byte[] buffer, int offset, int count) throws IOException;
    5468
    5569    /**
     
    7084     */
    7185    public abstract boolean trySkip(long n) throws IOException;
     86
     87    /**
     88     * Returns an estimate of the number of bytes that can be read (or skipped
     89     * over) from this {@link SequentialReader} without blocking by the next
     90     * invocation of a method for this input stream. A single read or skip of
     91     * this many bytes will not block, but may read or skip fewer bytes.
     92     * <p>
     93     * Note that while some implementations of {@link SequentialReader} like
     94     * {@link SequentialByteArrayReader} will return the total remaining number
     95     * of bytes in the stream, others will not. It is never correct to use the
     96     * return value of this method to allocate a buffer intended to hold all
     97     * data in this stream.
     98     *
     99     * @return an estimate of the number of bytes that can be read (or skipped
     100     *         over) from this {@link SequentialReader} without blocking or
     101     *         {@code 0} when it reaches the end of the input stream.
     102     */
     103    public abstract int available();
    72104
    73105    /**
     
    284316    }
    285317
     318    @NotNull
     319    public String getString(int bytesRequested, @NotNull Charset charset) throws IOException
     320    {
     321        byte[] bytes = getBytes(bytesRequested);
     322        return new String(bytes, charset);
     323    }
     324
     325    @NotNull
     326    public StringValue getStringValue(int bytesRequested, @Nullable Charset charset) throws IOException
     327    {
     328        return new StringValue(getBytes(bytesRequested), charset);
     329    }
     330
    286331    /**
    287332     * Creates a String from the stream, ending where <code>byte=='\0'</code> or where <code>length==maxLength</code>.
     
    293338     */
    294339    @NotNull
    295     public String getNullTerminatedString(int maxLengthBytes) throws IOException
    296     {
    297         // NOTE currently only really suited to single-byte character strings
    298 
    299         byte[] bytes = new byte[maxLengthBytes];
     340    public String getNullTerminatedString(int maxLengthBytes, Charset charset) throws IOException
     341    {
     342       return getNullTerminatedStringValue(maxLengthBytes, charset).toString();
     343    }
     344
     345    /**
     346     * Creates a String from the stream, ending where <code>byte=='\0'</code> or where <code>length==maxLength</code>.
     347     *
     348     * @param maxLengthBytes The maximum number of bytes to read.  If a <code>\0</code> byte is not reached within this limit,
     349     *                       reading will stop and the string will be truncated to this length.
     350     * @param charset The <code>Charset</code> to register with the returned <code>StringValue</code>, or <code>null</code> if the encoding
     351     *                is unknown
     352     * @return The read string.
     353     * @throws IOException The buffer does not contain enough bytes to satisfy this request.
     354     */
     355    @NotNull
     356    public StringValue getNullTerminatedStringValue(int maxLengthBytes, Charset charset) throws IOException
     357    {
     358        byte[] bytes = getNullTerminatedBytes(maxLengthBytes);
     359
     360        return new StringValue(bytes, charset);
     361    }
     362
     363    /**
     364     * Returns the sequence of bytes punctuated by a <code>\0</code> value.
     365     *
     366     * @param maxLengthBytes The maximum number of bytes to read. If a <code>\0</code> byte is not reached within this limit,
     367     * the returned array will be <code>maxLengthBytes</code> long.
     368     * @return The read byte array, excluding the null terminator.
     369     * @throws IOException The buffer does not contain enough bytes to satisfy this request.
     370     */
     371    @NotNull
     372    public byte[] getNullTerminatedBytes(int maxLengthBytes) throws IOException
     373    {
     374        byte[] buffer = new byte[maxLengthBytes];
    300375
    301376        // Count the number of non-null bytes
    302377        int length = 0;
    303         while (length < bytes.length && (bytes[length] = getByte()) != '\0')
     378        while (length < buffer.length && (buffer[length] = getByte()) != 0)
    304379            length++;
    305380
    306         return new String(bytes, 0, length);
     381        if (length == maxLengthBytes)
     382            return buffer;
     383
     384        byte[] bytes = new byte[length];
     385        if (length > 0)
     386            System.arraycopy(buffer, 0, bytes, 0, length);
     387        return bytes;
    307388    }
    308389}
  • trunk/src/com/drew/lang/StreamReader.java

    r10862 r13061  
    11/*
    2  * Copyright 2002-2016 Drew Noakes
     2 * Copyright 2002-2017 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    3737    private final InputStream _stream;
    3838
     39    private long _pos;
     40
     41    @Override
     42    public long getPosition()
     43    {
     44        return _pos;
     45    }
     46
     47    @SuppressWarnings("ConstantConditions")
    3948    public StreamReader(@NotNull InputStream stream)
    4049    {
     
    4352
    4453        _stream = stream;
     54        _pos = 0;
    4555    }
    4656
    4757    @Override
    48     protected byte getByte() throws IOException
     58    public byte getByte() throws IOException
    4959    {
    5060        int value = _stream.read();
    5161        if (value == -1)
    5262            throw new EOFException("End of data reached.");
     63        _pos++;
    5364        return (byte)value;
    5465    }
     
    5970    {
    6071        byte[] bytes = new byte[count];
     72        getBytes(bytes, 0, count);
     73        return bytes;
     74    }
     75
     76    @Override
     77    public void getBytes(@NotNull byte[] buffer, int offset, int count) throws IOException
     78    {
    6179        int totalBytesRead = 0;
    62 
    63         while (totalBytesRead != count) {
    64             final int bytesRead = _stream.read(bytes, totalBytesRead, count - totalBytesRead);
     80        while (totalBytesRead != count)
     81        {
     82            final int bytesRead = _stream.read(buffer, offset + totalBytesRead, count - totalBytesRead);
    6583            if (bytesRead == -1)
    6684                throw new EOFException("End of data reached.");
     
    6886            assert(totalBytesRead <= count);
    6987        }
    70 
    71         return bytes;
     88        _pos += totalBytesRead;
    7289    }
    7390
     
    93110    }
    94111
     112    @Override
     113    public int available() {
     114        try {
     115            return _stream.available();
     116        } catch (IOException e) {
     117            return 0;
     118        }
     119    }
     120
    95121    private long skipInternal(long n) throws IOException
    96122    {
     
    109135                break;
    110136        }
     137        _pos += skippedTotal;
    111138        return skippedTotal;
    112139    }
  • trunk/src/com/drew/lang/StringUtil.java

    r10862 r13061  
    11/*
    2  * Copyright 2002-2016 Drew Noakes
     2 * Copyright 2002-2017 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    3434 * @author Drew Noakes https://drewnoakes.com
    3535 */
    36 public class StringUtil
     36public final class StringUtil
    3737{
    3838    @NotNull
  • trunk/src/com/drew/lang/annotations/NotNull.java

    r10862 r13061  
    11/*
    2  * Copyright 2002-2016 Drew Noakes
     2 * Copyright 2002-2017 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/lang/annotations/Nullable.java

    r10862 r13061  
    11/*
    2  * Copyright 2002-2016 Drew Noakes
     2 * Copyright 2002-2017 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
Note: See TracChangeset for help on using the changeset viewer.