diff options
author | liujisi@google.com <liujisi@google.com@630680e5-0e50-0410-840e-4b1c322b438d> | 2010-11-02 13:14:58 +0000 |
---|---|---|
committer | liujisi@google.com <liujisi@google.com@630680e5-0e50-0410-840e-4b1c322b438d> | 2010-11-02 13:14:58 +0000 |
commit | 33165fe0d5c265c92f2a67fc2b437b567c24e294 (patch) | |
tree | 52def0850ddd2e976da238d1a437fbda79c96e44 /java/src/main/java/com/google/protobuf/CodedOutputStream.java | |
parent | 80aa23df6c63750e8cdfdcf3996fbc37d63cac61 (diff) | |
download | protobuf-33165fe0d5c265c92f2a67fc2b437b567c24e294.tar.gz protobuf-33165fe0d5c265c92f2a67fc2b437b567c24e294.tar.bz2 protobuf-33165fe0d5c265c92f2a67fc2b437b567c24e294.zip |
Submit recent changes from internal branch. See CHANGES.txt for more details.
Diffstat (limited to 'java/src/main/java/com/google/protobuf/CodedOutputStream.java')
-rw-r--r-- | java/src/main/java/com/google/protobuf/CodedOutputStream.java | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/java/src/main/java/com/google/protobuf/CodedOutputStream.java b/java/src/main/java/com/google/protobuf/CodedOutputStream.java index 58dd1506..51a932a3 100644 --- a/java/src/main/java/com/google/protobuf/CodedOutputStream.java +++ b/java/src/main/java/com/google/protobuf/CodedOutputStream.java @@ -33,6 +33,7 @@ package com.google.protobuf; import java.io.OutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.io.InputStream; /** * Encodes and writes protocol message fields. @@ -381,9 +382,8 @@ public final class CodedOutputStream { /** Write a {@code bytes} field to the stream. */ public void writeBytesNoTag(final ByteString value) throws IOException { - final byte[] bytes = value.toByteArray(); - writeRawVarint32(bytes.length); - writeRawBytes(bytes); + writeRawVarint32(value.size()); + writeRawBytes(value); } /** Write a {@code uint32} field to the stream. */ @@ -870,6 +870,11 @@ public final class CodedOutputStream { writeRawByte((byte) value); } + /** Write a byte string. */ + public void writeRawBytes(final ByteString value) throws IOException { + writeRawBytes(value, 0, value.size()); + } + /** Write an array of bytes. */ public void writeRawBytes(final byte[] value) throws IOException { writeRawBytes(value, 0, value.length); @@ -906,6 +911,53 @@ public final class CodedOutputStream { } } + /** Write part of a byte string. */ + public void writeRawBytes(final ByteString value, int offset, int length) + throws IOException { + if (limit - position >= length) { + // We have room in the current buffer. + value.copyTo(buffer, offset, position, length); + position += length; + } else { + // Write extends past current buffer. Fill the rest of this buffer and + // flush. + final int bytesWritten = limit - position; + value.copyTo(buffer, offset, position, bytesWritten); + offset += bytesWritten; + length -= bytesWritten; + position = limit; + refreshBuffer(); + + // Now deal with the rest. + // Since we have an output stream, this is our buffer + // and buffer offset == 0 + if (length <= limit) { + // Fits in new buffer. + value.copyTo(buffer, offset, 0, length); + position = length; + } else { + // Write is very big, but we can't do it all at once without allocating + // an a copy of the byte array since ByteString does not give us access + // to the underlying bytes. Use the InputStream interface on the + // ByteString and our buffer to copy between the two. + InputStream inputStreamFrom = value.newInput(); + if (offset != inputStreamFrom.skip(offset)) { + throw new IllegalStateException("Skip failed? Should never happen."); + } + // Use the buffer as the temporary buffer to avoid allocating memory. + while (length > 0) { + int bytesToRead = Math.min(length, limit); + int bytesRead = inputStreamFrom.read(buffer, 0, bytesToRead); + if (bytesRead != bytesToRead) { + throw new IllegalStateException("Read failed? Should never happen"); + } + output.write(buffer, 0, bytesRead); + length -= bytesRead; + } + } + } + } + /** Encode and write a tag. */ public void writeTag(final int fieldNumber, final int wireType) throws IOException { |