diff --git a/OsmAnd-java/src/com/google/protobuf/CodedInputStream.java b/OsmAnd-java/src/com/google/protobuf/CodedInputStream.java index 33417a7..5a9cb17 100644 --- a/OsmAnd-java/src/com/google/protobuf/CodedInputStream.java +++ b/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; @@ -61,6 +62,11 @@ public final class CodedInputStream { public static CodedInputStream newInstance(final byte[] buf) { return newInstance(buf, 0, buf.length); } + + // begin osmand change + public static CodedInputStream newInstance(RandomAccessFile raf) { + return new CodedInputStream(raf); + } /** * Create a new CodedInputStream wrapping the given byte array slice. @@ -532,6 +538,7 @@ public final class CodedInputStream { // ----------------------------------------------------------------- private final byte[] buffer; + private RandomAccessFile raf; private int bufferSize; private int bufferSizeAfterLimit; private int bufferPos; @@ -559,7 +566,7 @@ 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; @@ -569,6 +576,16 @@ public final class CodedInputStream { input = null; } + // osmand change + private CodedInputStream(final RandomAccessFile raf) { + buffer = new byte[BUFFER_SIZE]; + this.bufferSize = 0; + bufferPos = 0; + totalBytesRetired = 0; + this.raf = raf; + input = null; + } + private CodedInputStream(final InputStream input) { buffer = new byte[BUFFER_SIZE]; bufferSize = 0; @@ -734,7 +751,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 + @@ -848,8 +876,15 @@ 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(); } @@ -904,6 +939,16 @@ public final class CodedInputStream { int pos = bufferSize - bufferPos; bufferPos = bufferSize; + // osmand change + if(raf != null) { + bufferPos = 0; + bufferSize = 0; + final int n = raf.skipBytes(size - pos); + totalBytesRetired += bufferSize + n; // ? pos incorrect + if (n <= 0) { + throw InvalidProtocolBufferException.truncatedMessage(); + } + } else { // Keep refilling the buffer until we get to the point we wanted to skip // to. This has the side effect of ensuring the limits are updated // correctly. @@ -915,6 +960,23 @@ public final class CodedInputStream { } bufferPos = size - pos; + } } } + + 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 a/OsmAnd-java/src/com/google/protobuf/CodedOutputStream.java b/OsmAnd-java/src/com/google/protobuf/CodedOutputStream.java index ca24638..c1001bc 100644 --- a/OsmAnd-java/src/com/google/protobuf/CodedOutputStream.java +++ b/OsmAnd-java/src/com/google/protobuf/CodedOutputStream.java @@ -53,6 +53,7 @@ public final class CodedOutputStream { private final byte[] buffer; private final int limit; private int position; + private long writtenBytes = 0; private final OutputStream output; @@ -831,6 +832,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; } @@ -857,6 +859,13 @@ public final class CodedOutputStream { "writing to a flat array."); } } + + /** + * @return current offset in the output file + */ + public long getWrittenBytes() { + return writtenBytes + position; + } /** * Verifies that {@link #spaceLeft()} returns zero. It's common to create @@ -937,6 +946,7 @@ public final class CodedOutputStream { } else { // Write is very big. Let's do it all at once. output.write(value, offset, length); + writtenBytes += length; } } } @@ -982,6 +992,7 @@ public final class CodedOutputStream { throw new IllegalStateException("Read failed? Should never happen"); } output.write(buffer, 0, bytesRead); + writtenBytes += bytesRead; length -= bytesRead; } } diff --git a/OsmAnd-java/src/com/google/protobuf/WireFormat.java b/OsmAnd-java/src/com/google/protobuf/WireFormat.java index dd2d631..d6e07cf 100644 --- a/OsmAnd-java/src/com/google/protobuf/WireFormat.java +++ b/OsmAnd-java/src/com/google/protobuf/WireFormat.java @@ -51,12 +51,14 @@ public final class WireFormat { public static final int WIRETYPE_START_GROUP = 3; public static final int WIRETYPE_END_GROUP = 4; public 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; }