diff --git b/OsmAnd-java/src/com/google/protobuf/CodedInputStream.java a/OsmAnd-java/src/com/google/protobuf/CodedInputStream.java index ad43f96..45004e2 100644 --- b/OsmAnd-java/src/com/google/protobuf/CodedInputStream.java +++ a/OsmAnd-java/src/com/google/protobuf/CodedInputStream.java @@ -32,6 +32,7 @@ package com.google.protobuf; import java.io.IOException; import java.io.InputStream; +import java.io.RandomAccessFile; import java.util.ArrayList; import java.util.List; @@ -71,6 +72,12 @@ public final class CodedInputStream { } // ----------------------------------------------------------------- + // begin osmand change + public static CodedInputStream newInstance(RandomAccessFile raf) { + return new CodedInputStream(raf); + } + // end osmand change + /** * Attempt to read a field tag, returning zero if we have reached EOF. @@ -477,6 +484,7 @@ public final class CodedInputStream { // ----------------------------------------------------------------- private final byte[] buffer; + private RandomAccessFile raf; private int bufferSize; private int bufferSizeAfterLimit; private int bufferPos; @@ -504,7 +512,8 @@ public final class CodedInputStream { private static final int DEFAULT_RECURSION_LIMIT = 64; private static final int DEFAULT_SIZE_LIMIT = 64 << 20; // 64MB - private static final int BUFFER_SIZE = 4096; + private static final int BUFFER_SIZE = 5 * 1024; + private CodedInputStream(final byte[] buffer, final int off, final int len) { this.buffer = buffer; @@ -521,6 +530,15 @@ public final class CodedInputStream { totalBytesRetired = 0; this.input = input; } + + private CodedInputStream(final RandomAccessFile raf) { + buffer = new byte[BUFFER_SIZE]; + this.bufferSize = 0; + bufferPos = 0; + totalBytesRetired = 0; + this.raf = raf; + input = null; + } /** * Set the maximum message recursion depth. In order to prevent malicious @@ -679,7 +697,18 @@ public final class CodedInputStream { totalBytesRetired += bufferSize; bufferPos = 0; - bufferSize = (input == null) ? -1 : input.read(buffer); + if (raf != null) { + // osmand change + long remain = raf.length() - raf.getFilePointer(); + bufferSize = (int) Math.min(remain, buffer.length); + if(bufferSize > 0) { + raf.readFully(buffer, 0, bufferSize); + } else { + bufferSize = -1; + } + } else { + bufferSize = (input == null) ? -1 : input.read(buffer); + } if (bufferSize == 0 || bufferSize < -1) { throw new IllegalStateException( "InputStream#read(byte[]) returned invalid result: " + bufferSize + @@ -793,8 +822,16 @@ public final class CodedInputStream { final byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)]; int pos = 0; while (pos < chunk.length) { - final int n = (input == null) ? -1 : - input.read(chunk, pos, chunk.length - pos); + + final int n; + // osmand change + if(raf != null) { + raf.readFully(chunk, pos, chunk.length - pos); + n = chunk.length - pos; + } else { + n = (input == null) ? -1 : + input.read(chunk, pos, chunk.length - pos); + } if (n == -1) { throw InvalidProtocolBufferException.truncatedMessage(); } @@ -817,7 +854,6 @@ public final class CodedInputStream { System.arraycopy(chunk, 0, bytes, pos, chunk.length); pos += chunk.length; } - // Done. return bytes; } @@ -847,13 +883,19 @@ public final class CodedInputStream { } else { // Skipping more bytes than are in the buffer. First skip what we have. int pos = bufferSize - bufferPos; - totalBytesRetired += pos; + totalBytesRetired += bufferSize; // ? pos incorrect bufferPos = 0; bufferSize = 0; // Then skip directly from the InputStream for the rest. while (pos < size) { - final int n = (input == null) ? -1 : (int) input.skip(size - pos); + // osmand change + final int n ; + if(raf != null) { + n = raf.skipBytes(size - pos); + } else { + n = (input == null) ? -1 : (int) input.skip(size - pos); + } if (n <= 0) { throw InvalidProtocolBufferException.truncatedMessage(); } @@ -862,4 +904,21 @@ public final class CodedInputStream { } } } + + // osmand change + public void seek(long pointer) throws IOException { + if (pointer - totalBytesRetired >= 0 && pointer - totalBytesRetired < bufferSize) { + if (pointer > currentLimit) { + // Then fail. + throw InvalidProtocolBufferException.truncatedMessage(); + } + bufferPos = (int) (pointer - totalBytesRetired); + } else { + totalBytesRetired = (int) pointer; + bufferSizeAfterLimit = 0; + raf.seek(pointer); + bufferPos = 0; + bufferSize = 0; + } + } } diff --git b/OsmAnd-java/src/com/google/protobuf/CodedOutputStream.java a/OsmAnd-java/src/com/google/protobuf/CodedOutputStream.java index 58dd150..6e81b98 100644 --- b/OsmAnd-java/src/com/google/protobuf/CodedOutputStream.java +++ a/OsmAnd-java/src/com/google/protobuf/CodedOutputStream.java @@ -30,8 +30,8 @@ package com.google.protobuf; -import java.io.OutputStream; import java.io.IOException; +import java.io.OutputStream; import java.io.UnsupportedEncodingException; /** @@ -52,6 +52,8 @@ public final class CodedOutputStream { private final byte[] buffer; private final int limit; private int position; + // + Change + private long writtenBytes = 0; private final OutputStream output; @@ -801,6 +803,7 @@ public final class CodedOutputStream { // Since we have an output stream, this is our buffer // and buffer offset == 0 output.write(buffer, 0, position); + writtenBytes += position; position = 0; } @@ -813,6 +816,13 @@ public final class CodedOutputStream { refreshBuffer(); } } + + /** + * @return current offset in the output file + */ + public long getWrittenBytes() { + return writtenBytes + position; + } /** * If writing to a flat array, return the space left in the array. @@ -902,6 +912,7 @@ public final class CodedOutputStream { } else { // Write is very big. Let's do it all at once. output.write(value, offset, length); + writtenBytes += length; } } } diff --git b/OsmAnd-java/src/com/google/protobuf/WireFormat.java a/OsmAnd-java/src/com/google/protobuf/WireFormat.java index c46f7b0..cca0b8e 100644 --- b/OsmAnd-java/src/com/google/protobuf/WireFormat.java +++ a/OsmAnd-java/src/com/google/protobuf/WireFormat.java @@ -51,11 +51,13 @@ public final class WireFormat { static final int WIRETYPE_START_GROUP = 3; static final int WIRETYPE_END_GROUP = 4; static final int WIRETYPE_FIXED32 = 5; + // Osmand Delta change + public static final int WIRETYPE_FIXED32_LENGTH_DELIMITED = 6; static final int TAG_TYPE_BITS = 3; static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1; /** Given a tag value, determines the wire type (the lower 3 bits). */ - static int getTagWireType(final int tag) { + public static int getTagWireType(final int tag) { return tag & TAG_TYPE_MASK; }