Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: third_party/protobuf/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java

Issue 2590803003: Revert "third_party/protobuf: Update to HEAD (83d681ee2c)" (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 12 matching lines...) Expand all
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 30
31 package com.google.protobuf; 31 package com.google.protobuf;
32 32
33 import static com.google.protobuf.WireFormat.FIXED_32_SIZE;
34 import static com.google.protobuf.WireFormat.FIXED_64_SIZE;
35 import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE;
36 import static java.lang.Math.max; 33 import static java.lang.Math.max;
37 34
38 import com.google.protobuf.Utf8.UnpairedSurrogateException; 35 import com.google.protobuf.Utf8.UnpairedSurrogateException;
36
39 import java.io.IOException; 37 import java.io.IOException;
40 import java.io.OutputStream; 38 import java.io.OutputStream;
39 import java.lang.reflect.Field;
41 import java.nio.BufferOverflowException; 40 import java.nio.BufferOverflowException;
42 import java.nio.ByteBuffer; 41 import java.nio.ByteBuffer;
43 import java.nio.ByteOrder; 42 import java.nio.ByteOrder;
43 import java.security.AccessController;
44 import java.security.PrivilegedExceptionAction;
44 import java.util.logging.Level; 45 import java.util.logging.Level;
45 import java.util.logging.Logger; 46 import java.util.logging.Logger;
46 47
47 /** 48 /**
48 * Encodes and writes protocol message fields. 49 * Encodes and writes protocol message fields.
49 * 50 *
50 * <p>This class contains two kinds of methods: methods that write specific 51 * <p>This class contains two kinds of methods: methods that write specific
51 * protocol message constructs and field types (e.g. {@link #writeTag} and 52 * protocol message constructs and field types (e.g. {@link #writeTag} and
52 * {@link #writeInt32}) and methods that write low-level values (e.g. 53 * {@link #writeInt32}) and methods that write low-level values (e.g.
53 * {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are 54 * {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are
54 * writing encoded protocol messages, you should use the former methods, but if 55 * writing encoded protocol messages, you should use the former methods, but if
55 * you are writing some other format of your own design, use the latter. 56 * you are writing some other format of your own design, use the latter.
56 * 57 *
57 * <p>This class is totally unsynchronized. 58 * <p>This class is totally unsynchronized.
58 */ 59 */
59 public abstract class CodedOutputStream extends ByteOutput { 60 public abstract class CodedOutputStream extends ByteOutput {
60 private static final Logger logger = Logger.getLogger(CodedOutputStream.class. getName()); 61 private static final Logger logger = Logger.getLogger(CodedOutputStream.class. getName());
61 private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = UnsafeUtil.hasUnsaf eArrayOperations(); 62 private static final sun.misc.Unsafe UNSAFE = getUnsafe();
62 private static final long ARRAY_BASE_OFFSET = UnsafeUtil.getArrayBaseOffset(); 63 private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = supportsUnsafeArray Operations();
64 private static final long ARRAY_BASE_OFFSET = byteArrayBaseOffset();
65
66 private static final int FIXED_32_SIZE = 4;
67 private static final int FIXED_64_SIZE = 8;
68 private static final int MAX_VARINT_SIZE = 10;
63 69
64 /** 70 /**
65 * @deprecated Use {@link #computeFixed32SizeNoTag(int)} instead. 71 * @deprecated Use {@link #computeFixed32SizeNoTag(int)} instead.
66 */ 72 */
67 @Deprecated 73 @Deprecated
68 public static final int LITTLE_ENDIAN_32_SIZE = FIXED_32_SIZE; 74 public static final int LITTLE_ENDIAN_32_SIZE = FIXED_32_SIZE;
69 75
70 /** 76 /**
71 * The buffer size used in {@link #newInstance(OutputStream)}. 77 * The buffer size used in {@link #newInstance(OutputStream)}.
72 */ 78 */
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 * byte array slice. If more bytes are written than fit in the slice, 131 * byte array slice. If more bytes are written than fit in the slice,
126 * {@link OutOfSpaceException} will be thrown. Writing directly to a flat 132 * {@link OutOfSpaceException} will be thrown. Writing directly to a flat
127 * array is faster than writing to an {@code OutputStream}. See also 133 * array is faster than writing to an {@code OutputStream}. See also
128 * {@link ByteString#newCodedBuilder}. 134 * {@link ByteString#newCodedBuilder}.
129 */ 135 */
130 public static CodedOutputStream newInstance( 136 public static CodedOutputStream newInstance(
131 final byte[] flatArray, final int offset, final int length) { 137 final byte[] flatArray, final int offset, final int length) {
132 return new ArrayEncoder(flatArray, offset, length); 138 return new ArrayEncoder(flatArray, offset, length);
133 } 139 }
134 140
135 /** Create a new {@code CodedOutputStream} that writes to the given {@link Byt eBuffer}. */ 141 /**
136 public static CodedOutputStream newInstance(ByteBuffer buffer) { 142 * Create a new {@code CodedOutputStream} that writes to the given {@link Byte Buffer}.
137 if (buffer.hasArray()) { 143 */
138 return new HeapNioEncoder(buffer); 144 public static CodedOutputStream newInstance(ByteBuffer byteBuffer) {
145 if (byteBuffer.hasArray()) {
146 return new NioHeapEncoder(byteBuffer);
139 } 147 }
140 if (buffer.isDirect() && !buffer.isReadOnly()) { 148 return new NioEncoder(byteBuffer);
141 return UnsafeDirectNioEncoder.isSupported()
142 ? newUnsafeInstance(buffer)
143 : newSafeInstance(buffer);
144 }
145 throw new IllegalArgumentException("ByteBuffer is read-only");
146 }
147
148 /** For testing purposes only. */
149 static CodedOutputStream newUnsafeInstance(ByteBuffer buffer) {
150 return new UnsafeDirectNioEncoder(buffer);
151 }
152
153 /** For testing purposes only. */
154 static CodedOutputStream newSafeInstance(ByteBuffer buffer) {
155 return new SafeDirectNioEncoder(buffer);
156 } 149 }
157 150
158 /** 151 /**
159 * Configures serialization to be deterministic.
160 *
161 * <p>The deterministic serialization guarantees that for a given binary, equa l (defined by the
162 * {@code equals()} methods in protos) messages will always be serialized to t he same bytes. This
163 * implies:
164 *
165 * <ul>
166 * <li>repeated serialization of a message will return the same bytes
167 * <li>different processes of the same binary (which may be executing on diffe rent machines) will
168 * serialize equal messages to the same bytes.
169 * </ul>
170 *
171 * <p>Note the deterministic serialization is NOT canonical across languages; it is also unstable
172 * across different builds with schema changes due to unknown fields. Users wh o need canonical
173 * serialization, e.g. persistent storage in a canonical form, fingerprinting, etc, should define
174 * their own canonicalization specification and implement the serializer using reflection APIs
175 * rather than relying on this API.
176 *
177 * <p> Once set, the serializer will: (Note this is an implementation detail and may subject to
178 * change in the future)
179 *
180 * <ul>
181 * <li> sort map entries by keys in lexicographical order or numerical order. Note: For string
182 * keys, the order is based on comparing the Unicode value of each charact er in the strings.
183 * The order may be different from the deterministic serialization in othe r languages where
184 * maps are sorted on the lexicographical order of the UTF8 encoded keys.
185 * </ul>
186 */
187 void useDeterministicSerialization() {
188 serializationDeterministic = true;
189 }
190
191 boolean isSerializationDeterministic() {
192 return serializationDeterministic;
193 }
194 private boolean serializationDeterministic;
195
196 /**
197 * Create a new {@code CodedOutputStream} that writes to the given {@link Byte Buffer}. 152 * Create a new {@code CodedOutputStream} that writes to the given {@link Byte Buffer}.
198 * 153 *
199 * @deprecated the size parameter is no longer used since use of an internal b uffer is useless 154 * @deprecated the size parameter is no longer used since use of an internal b uffer is useless
200 * (and wasteful) when writing to a {@link ByteBuffer}. Use {@link #newInstanc e(ByteBuffer)} 155 * (and wasteful) when writing to a {@link ByteBuffer}. Use {@link #newInstanc e(ByteBuffer)}
201 * instead. 156 * instead.
202 */ 157 */
203 @Deprecated 158 @Deprecated
204 public static CodedOutputStream newInstance(ByteBuffer byteBuffer, 159 public static CodedOutputStream newInstance(ByteBuffer byteBuffer,
205 @SuppressWarnings("unused") int unused) { 160 @SuppressWarnings("unused") int unused) {
206 return newInstance(byteBuffer); 161 return newInstance(byteBuffer);
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 } 862 }
908 863
909 /** 864 /**
910 * Compute the number of bytes that would be needed to encode an embedded 865 * Compute the number of bytes that would be needed to encode an embedded
911 * message field. 866 * message field.
912 */ 867 */
913 public static int computeMessageSizeNoTag(final MessageLite value) { 868 public static int computeMessageSizeNoTag(final MessageLite value) {
914 return computeLengthDelimitedFieldSize(value.getSerializedSize()); 869 return computeLengthDelimitedFieldSize(value.getSerializedSize());
915 } 870 }
916 871
917 static int computeLengthDelimitedFieldSize(int fieldLength) { 872 private static int computeLengthDelimitedFieldSize(int fieldLength) {
918 return computeUInt32SizeNoTag(fieldLength) + fieldLength; 873 return computeUInt32SizeNoTag(fieldLength) + fieldLength;
919 } 874 }
920 875
921 /** 876 /**
922 * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers 877 * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
923 * into values that can be efficiently encoded with varint. (Otherwise, 878 * into values that can be efficiently encoded with varint. (Otherwise,
924 * negative values must be sign-extended to 64 bits to be varint encoded, 879 * negative values must be sign-extended to 64 bits to be varint encoded,
925 * thus always taking 10 bytes on the wire.) 880 * thus always taking 10 bytes on the wire.)
926 * 881 *
927 * @param n A signed 32-bit integer. 882 * @param n A signed 32-bit integer.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
983 public static class OutOfSpaceException extends IOException { 938 public static class OutOfSpaceException extends IOException {
984 private static final long serialVersionUID = -6947486886997889499L; 939 private static final long serialVersionUID = -6947486886997889499L;
985 940
986 private static final String MESSAGE = 941 private static final String MESSAGE =
987 "CodedOutputStream was writing to a flat byte array and ran out of space ."; 942 "CodedOutputStream was writing to a flat byte array and ran out of space .";
988 943
989 OutOfSpaceException() { 944 OutOfSpaceException() {
990 super(MESSAGE); 945 super(MESSAGE);
991 } 946 }
992 947
993 OutOfSpaceException(String explanationMessage) {
994 super(MESSAGE + ": " + explanationMessage);
995 }
996
997 OutOfSpaceException(Throwable cause) { 948 OutOfSpaceException(Throwable cause) {
998 super(MESSAGE, cause); 949 super(MESSAGE, cause);
999 } 950 }
1000
1001 OutOfSpaceException(String explanationMessage, Throwable cause) {
1002 super(MESSAGE + ": " + explanationMessage, cause);
1003 }
1004 } 951 }
1005 952
1006 /** 953 /**
1007 * Get the total number of bytes successfully written to this stream. The 954 * Get the total number of bytes successfully written to this stream. The
1008 * returned value is not guaranteed to be accurate if exceptions have been 955 * returned value is not guaranteed to be accurate if exceptions have been
1009 * found in the middle of writing. 956 * found in the middle of writing.
1010 */ 957 */
1011 public abstract int getTotalBytesWritten(); 958 public abstract int getTotalBytesWritten();
1012 959
1013 // ================================================================= 960 // =================================================================
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 public final void writeMessageNoTag(final MessageLite value) throws IOExcept ion { 1243 public final void writeMessageNoTag(final MessageLite value) throws IOExcept ion {
1297 writeUInt32NoTag(value.getSerializedSize()); 1244 writeUInt32NoTag(value.getSerializedSize());
1298 value.writeTo(this); 1245 value.writeTo(this);
1299 } 1246 }
1300 1247
1301 @Override 1248 @Override
1302 public final void write(byte value) throws IOException { 1249 public final void write(byte value) throws IOException {
1303 try { 1250 try {
1304 buffer[position++] = value; 1251 buffer[position++] = value;
1305 } catch (IndexOutOfBoundsException e) { 1252 } catch (IndexOutOfBoundsException e) {
1306 throw new OutOfSpaceException( 1253 throw new OutOfSpaceException(new IndexOutOfBoundsException(
1307 String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e) ; 1254 String.format("Pos: %d, limit: %d, len: %d", position, limit, 1)));
1308 } 1255 }
1309 } 1256 }
1310 1257
1311 @Override 1258 @Override
1312 public final void writeInt32NoTag(int value) throws IOException { 1259 public final void writeInt32NoTag(int value) throws IOException {
1313 if (value >= 0) { 1260 if (value >= 0) {
1314 writeUInt32NoTag(value); 1261 writeUInt32NoTag(value);
1315 } else { 1262 } else {
1316 // Must sign-extend. 1263 // Must sign-extend.
1317 writeUInt64NoTag(value); 1264 writeUInt64NoTag(value);
1318 } 1265 }
1319 } 1266 }
1320 1267
1321 @Override 1268 @Override
1322 public final void writeUInt32NoTag(int value) throws IOException { 1269 public final void writeUInt32NoTag(int value) throws IOException {
1323 if (HAS_UNSAFE_ARRAY_OPERATIONS && spaceLeft() >= MAX_VARINT_SIZE) { 1270 if (HAS_UNSAFE_ARRAY_OPERATIONS && spaceLeft() >= MAX_VARINT_SIZE) {
1324 long pos = ARRAY_BASE_OFFSET + position; 1271 long pos = ARRAY_BASE_OFFSET + position;
1325 while (true) { 1272 while (true) {
1326 if ((value & ~0x7F) == 0) { 1273 if ((value & ~0x7F) == 0) {
1327 UnsafeUtil.putByte(buffer, pos++, (byte) value); 1274 UNSAFE.putByte(buffer, pos++, (byte) value);
1328 position++; 1275 position++;
1329 return; 1276 return;
1330 } else { 1277 } else {
1331 UnsafeUtil.putByte(buffer, pos++, (byte) ((value & 0x7F) | 0x80)); 1278 UNSAFE.putByte(buffer, pos++, (byte) ((value & 0x7F) | 0x80));
1332 position++; 1279 position++;
1333 value >>>= 7; 1280 value >>>= 7;
1334 } 1281 }
1335 } 1282 }
1336 } else { 1283 } else {
1337 try { 1284 try {
1338 while (true) { 1285 while (true) {
1339 if ((value & ~0x7F) == 0) { 1286 if ((value & ~0x7F) == 0) {
1340 buffer[position++] = (byte) value; 1287 buffer[position++] = (byte) value;
1341 return; 1288 return;
1342 } else { 1289 } else {
1343 buffer[position++] = (byte) ((value & 0x7F) | 0x80); 1290 buffer[position++] = (byte) ((value & 0x7F) | 0x80);
1344 value >>>= 7; 1291 value >>>= 7;
1345 } 1292 }
1346 } 1293 }
1347 } catch (IndexOutOfBoundsException e) { 1294 } catch (IndexOutOfBoundsException e) {
1348 throw new OutOfSpaceException( 1295 throw new OutOfSpaceException(
1349 String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e); 1296 new IndexOutOfBoundsException(
1297 String.format("Pos: %d, limit: %d, len: %d", position, limit, 1)));
1350 } 1298 }
1351 } 1299 }
1352 } 1300 }
1353 1301
1354 @Override 1302 @Override
1355 public final void writeFixed32NoTag(int value) throws IOException { 1303 public final void writeFixed32NoTag(int value) throws IOException {
1356 try { 1304 try {
1357 buffer[position++] = (byte) (value & 0xFF); 1305 buffer[position++] = (byte) (value & 0xFF);
1358 buffer[position++] = (byte) ((value >> 8) & 0xFF); 1306 buffer[position++] = (byte) ((value >> 8) & 0xFF);
1359 buffer[position++] = (byte) ((value >> 16) & 0xFF); 1307 buffer[position++] = (byte) ((value >> 16) & 0xFF);
1360 buffer[position++] = (byte) ((value >> 24) & 0xFF); 1308 buffer[position++] = (byte) ((value >> 24) & 0xFF);
1361 } catch (IndexOutOfBoundsException e) { 1309 } catch (IndexOutOfBoundsException e) {
1362 throw new OutOfSpaceException( 1310 throw new OutOfSpaceException(
1363 String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e) ; 1311 new IndexOutOfBoundsException(
1312 String.format("Pos: %d, limit: %d, len: %d", position, limit, 1) ));
1364 } 1313 }
1365 } 1314 }
1366 1315
1367 @Override 1316 @Override
1368 public final void writeUInt64NoTag(long value) throws IOException { 1317 public final void writeUInt64NoTag(long value) throws IOException {
1369 if (HAS_UNSAFE_ARRAY_OPERATIONS && spaceLeft() >= MAX_VARINT_SIZE) { 1318 if (HAS_UNSAFE_ARRAY_OPERATIONS && spaceLeft() >= MAX_VARINT_SIZE) {
1370 long pos = ARRAY_BASE_OFFSET + position; 1319 long pos = ARRAY_BASE_OFFSET + position;
1371 while (true) { 1320 while (true) {
1372 if ((value & ~0x7FL) == 0) { 1321 if ((value & ~0x7FL) == 0) {
1373 UnsafeUtil.putByte(buffer, pos++, (byte) value); 1322 UNSAFE.putByte(buffer, pos++, (byte) value);
1374 position++; 1323 position++;
1375 return; 1324 return;
1376 } else { 1325 } else {
1377 UnsafeUtil.putByte(buffer, pos++, (byte) (((int) value & 0x7F) | 0x8 0)); 1326 UNSAFE.putByte(buffer, pos++, (byte) (((int) value & 0x7F) | 0x80));
1378 position++; 1327 position++;
1379 value >>>= 7; 1328 value >>>= 7;
1380 } 1329 }
1381 } 1330 }
1382 } else { 1331 } else {
1383 try { 1332 try {
1384 while (true) { 1333 while (true) {
1385 if ((value & ~0x7FL) == 0) { 1334 if ((value & ~0x7FL) == 0) {
1386 buffer[position++] = (byte) value; 1335 buffer[position++] = (byte) value;
1387 return; 1336 return;
1388 } else { 1337 } else {
1389 buffer[position++] = (byte) (((int) value & 0x7F) | 0x80); 1338 buffer[position++] = (byte) (((int) value & 0x7F) | 0x80);
1390 value >>>= 7; 1339 value >>>= 7;
1391 } 1340 }
1392 } 1341 }
1393 } catch (IndexOutOfBoundsException e) { 1342 } catch (IndexOutOfBoundsException e) {
1394 throw new OutOfSpaceException( 1343 throw new OutOfSpaceException(
1395 String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e); 1344 new IndexOutOfBoundsException(
1345 String.format("Pos: %d, limit: %d, len: %d", position, limit, 1)));
1396 } 1346 }
1397 } 1347 }
1398 } 1348 }
1399 1349
1400 @Override 1350 @Override
1401 public final void writeFixed64NoTag(long value) throws IOException { 1351 public final void writeFixed64NoTag(long value) throws IOException {
1402 try { 1352 try {
1403 buffer[position++] = (byte) ((int) (value) & 0xFF); 1353 buffer[position++] = (byte) ((int) (value) & 0xFF);
1404 buffer[position++] = (byte) ((int) (value >> 8) & 0xFF); 1354 buffer[position++] = (byte) ((int) (value >> 8) & 0xFF);
1405 buffer[position++] = (byte) ((int) (value >> 16) & 0xFF); 1355 buffer[position++] = (byte) ((int) (value >> 16) & 0xFF);
1406 buffer[position++] = (byte) ((int) (value >> 24) & 0xFF); 1356 buffer[position++] = (byte) ((int) (value >> 24) & 0xFF);
1407 buffer[position++] = (byte) ((int) (value >> 32) & 0xFF); 1357 buffer[position++] = (byte) ((int) (value >> 32) & 0xFF);
1408 buffer[position++] = (byte) ((int) (value >> 40) & 0xFF); 1358 buffer[position++] = (byte) ((int) (value >> 40) & 0xFF);
1409 buffer[position++] = (byte) ((int) (value >> 48) & 0xFF); 1359 buffer[position++] = (byte) ((int) (value >> 48) & 0xFF);
1410 buffer[position++] = (byte) ((int) (value >> 56) & 0xFF); 1360 buffer[position++] = (byte) ((int) (value >> 56) & 0xFF);
1411 } catch (IndexOutOfBoundsException e) { 1361 } catch (IndexOutOfBoundsException e) {
1412 throw new OutOfSpaceException( 1362 throw new OutOfSpaceException(
1413 String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e) ; 1363 new IndexOutOfBoundsException(
1364 String.format("Pos: %d, limit: %d, len: %d", position, limit, 1) ));
1414 } 1365 }
1415 } 1366 }
1416 1367
1417 @Override 1368 @Override
1418 public final void write(byte[] value, int offset, int length) throws IOExcep tion { 1369 public final void write(byte[] value, int offset, int length) throws IOExcep tion {
1419 try { 1370 try {
1420 System.arraycopy(value, offset, buffer, position, length); 1371 System.arraycopy(value, offset, buffer, position, length);
1421 position += length; 1372 position += length;
1422 } catch (IndexOutOfBoundsException e) { 1373 } catch (IndexOutOfBoundsException e) {
1423 throw new OutOfSpaceException( 1374 throw new OutOfSpaceException(
1424 String.format("Pos: %d, limit: %d, len: %d", position, limit, length ), e); 1375 new IndexOutOfBoundsException(
1376 String.format("Pos: %d, limit: %d, len: %d", position, limit, le ngth)));
1425 } 1377 }
1426 } 1378 }
1427 1379
1428 @Override 1380 @Override
1429 public final void writeLazy(byte[] value, int offset, int length) throws IOE xception { 1381 public final void writeLazy(byte[] value, int offset, int length) throws IOE xception {
1430 write(value, offset, length); 1382 write(value, offset, length);
1431 } 1383 }
1432 1384
1433 @Override 1385 @Override
1434 public final void write(ByteBuffer value) throws IOException { 1386 public final void write(ByteBuffer value) throws IOException {
1435 final int length = value.remaining(); 1387 final int length = value.remaining();
1436 try { 1388 try {
1437 value.get(buffer, position, length); 1389 value.get(buffer, position, length);
1438 position += length; 1390 position += length;
1439 } catch (IndexOutOfBoundsException e) { 1391 } catch (IndexOutOfBoundsException e) {
1440 throw new OutOfSpaceException( 1392 throw new OutOfSpaceException(
1441 String.format("Pos: %d, limit: %d, len: %d", position, limit, length ), e); 1393 new IndexOutOfBoundsException(
1394 String.format("Pos: %d, limit: %d, len: %d", position, limit, le ngth)));
1442 } 1395 }
1443 } 1396 }
1444 1397
1445 @Override 1398 @Override
1446 public final void writeLazy(ByteBuffer value) throws IOException { 1399 public final void writeLazy(ByteBuffer value) throws IOException {
1447 write(value); 1400 write(value);
1448 } 1401 }
1449 1402
1450 @Override 1403 @Override
1451 public final void writeStringNoTag(String value) throws IOException { 1404 public final void writeStringNoTag(String value) throws IOException {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 @Override 1447 @Override
1495 public final int getTotalBytesWritten() { 1448 public final int getTotalBytesWritten() {
1496 return position - offset; 1449 return position - offset;
1497 } 1450 }
1498 } 1451 }
1499 1452
1500 /** 1453 /**
1501 * A {@link CodedOutputStream} that writes directly to a heap {@link ByteBuffe r}. Writes are 1454 * A {@link CodedOutputStream} that writes directly to a heap {@link ByteBuffe r}. Writes are
1502 * done directly to the underlying array. The buffer position is only updated after a flush. 1455 * done directly to the underlying array. The buffer position is only updated after a flush.
1503 */ 1456 */
1504 private static final class HeapNioEncoder extends ArrayEncoder { 1457 private static final class NioHeapEncoder extends ArrayEncoder {
1505 private final ByteBuffer byteBuffer; 1458 private final ByteBuffer byteBuffer;
1506 private int initialPosition; 1459 private int initialPosition;
1507 1460
1508 HeapNioEncoder(ByteBuffer byteBuffer) { 1461 NioHeapEncoder(ByteBuffer byteBuffer) {
1509 super(byteBuffer.array(), byteBuffer.arrayOffset() + byteBuffer.position() , 1462 super(byteBuffer.array(), byteBuffer.arrayOffset() + byteBuffer.position() ,
1510 byteBuffer.remaining()); 1463 byteBuffer.remaining());
1511 this.byteBuffer = byteBuffer; 1464 this.byteBuffer = byteBuffer;
1512 this.initialPosition = byteBuffer.position(); 1465 this.initialPosition = byteBuffer.position();
1513 } 1466 }
1514 1467
1515 @Override 1468 @Override
1516 public void flush() { 1469 public void flush() {
1517 // Update the position on the buffer. 1470 // Update the position on the buffer.
1518 byteBuffer.position(initialPosition + getTotalBytesWritten()); 1471 byteBuffer.position(initialPosition + getTotalBytesWritten());
1519 } 1472 }
1520 } 1473 }
1521 1474
1522 /** 1475 /**
1523 * A {@link CodedOutputStream} that writes directly to a direct {@link ByteBuf fer}, using only 1476 * A {@link CodedOutputStream} that writes directly to a {@link ByteBuffer}.
1524 * safe operations..
1525 */ 1477 */
1526 private static final class SafeDirectNioEncoder extends CodedOutputStream { 1478 private static final class NioEncoder extends CodedOutputStream {
1527 private final ByteBuffer originalBuffer; 1479 private final ByteBuffer originalBuffer;
1528 private final ByteBuffer buffer; 1480 private final ByteBuffer buffer;
1529 private final int initialPosition; 1481 private final int initialPosition;
1530 1482
1531 SafeDirectNioEncoder(ByteBuffer buffer) { 1483 NioEncoder(ByteBuffer buffer) {
1532 this.originalBuffer = buffer; 1484 this.originalBuffer = buffer;
1533 this.buffer = buffer.duplicate().order(ByteOrder.LITTLE_ENDIAN); 1485 this.buffer = buffer.duplicate().order(ByteOrder.LITTLE_ENDIAN);
1534 initialPosition = buffer.position(); 1486 initialPosition = buffer.position();
1535 } 1487 }
1536 1488
1537 @Override 1489 @Override
1538 public void writeTag(final int fieldNumber, final int wireType) throws IOExc eption { 1490 public void writeTag(final int fieldNumber, final int wireType) throws IOExc eption {
1539 writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType)); 1491 writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
1540 } 1492 }
1541 1493
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1824 private void encode(String value) throws IOException { 1776 private void encode(String value) throws IOException {
1825 try { 1777 try {
1826 Utf8.encodeUtf8(value, buffer); 1778 Utf8.encodeUtf8(value, buffer);
1827 } catch (IndexOutOfBoundsException e) { 1779 } catch (IndexOutOfBoundsException e) {
1828 throw new OutOfSpaceException(e); 1780 throw new OutOfSpaceException(e);
1829 } 1781 }
1830 } 1782 }
1831 } 1783 }
1832 1784
1833 /** 1785 /**
1834 * A {@link CodedOutputStream} that writes directly to a direct {@link ByteBuf fer} using {@code
1835 * sun.misc.Unsafe}.
1836 */
1837 private static final class UnsafeDirectNioEncoder extends CodedOutputStream {
1838 private final ByteBuffer originalBuffer;
1839 private final ByteBuffer buffer;
1840 private final long address;
1841 private final long initialPosition;
1842 private final long limit;
1843 private final long oneVarintLimit;
1844 private long position;
1845
1846 UnsafeDirectNioEncoder(ByteBuffer buffer) {
1847 this.originalBuffer = buffer;
1848 this.buffer = buffer.duplicate().order(ByteOrder.LITTLE_ENDIAN);
1849 address = UnsafeUtil.addressOffset(buffer);
1850 initialPosition = address + buffer.position();
1851 limit = address + buffer.limit();
1852 oneVarintLimit = limit - MAX_VARINT_SIZE;
1853 position = initialPosition;
1854 }
1855
1856 static boolean isSupported() {
1857 return UnsafeUtil.hasUnsafeByteBufferOperations();
1858 }
1859
1860 @Override
1861 public void writeTag(int fieldNumber, int wireType) throws IOException {
1862 writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
1863 }
1864
1865 @Override
1866 public void writeInt32(int fieldNumber, int value) throws IOException {
1867 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
1868 writeInt32NoTag(value);
1869 }
1870
1871 @Override
1872 public void writeUInt32(int fieldNumber, int value) throws IOException {
1873 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
1874 writeUInt32NoTag(value);
1875 }
1876
1877 @Override
1878 public void writeFixed32(int fieldNumber, int value) throws IOException {
1879 writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
1880 writeFixed32NoTag(value);
1881 }
1882
1883 @Override
1884 public void writeUInt64(int fieldNumber, long value) throws IOException {
1885 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
1886 writeUInt64NoTag(value);
1887 }
1888
1889 @Override
1890 public void writeFixed64(int fieldNumber, long value) throws IOException {
1891 writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
1892 writeFixed64NoTag(value);
1893 }
1894
1895 @Override
1896 public void writeBool(int fieldNumber, boolean value) throws IOException {
1897 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
1898 write((byte) (value ? 1 : 0));
1899 }
1900
1901 @Override
1902 public void writeString(int fieldNumber, String value) throws IOException {
1903 writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
1904 writeStringNoTag(value);
1905 }
1906
1907 @Override
1908 public void writeBytes(int fieldNumber, ByteString value) throws IOException {
1909 writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
1910 writeBytesNoTag(value);
1911 }
1912
1913 @Override
1914 public void writeByteArray(int fieldNumber, byte[] value) throws IOException {
1915 writeByteArray(fieldNumber, value, 0, value.length);
1916 }
1917
1918 @Override
1919 public void writeByteArray(int fieldNumber, byte[] value, int offset, int le ngth)
1920 throws IOException {
1921 writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
1922 writeByteArrayNoTag(value, offset, length);
1923 }
1924
1925 @Override
1926 public void writeByteBuffer(int fieldNumber, ByteBuffer value) throws IOExce ption {
1927 writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
1928 writeUInt32NoTag(value.capacity());
1929 writeRawBytes(value);
1930 }
1931
1932 @Override
1933 public void writeMessage(int fieldNumber, MessageLite value) throws IOExcept ion {
1934 writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
1935 writeMessageNoTag(value);
1936 }
1937
1938 @Override
1939 public void writeMessageSetExtension(int fieldNumber, MessageLite value) thr ows IOException {
1940 writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
1941 writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
1942 writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
1943 writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
1944 }
1945
1946 @Override
1947 public void writeRawMessageSetExtension(int fieldNumber, ByteString value) t hrows IOException {
1948 writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
1949 writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
1950 writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
1951 writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
1952 }
1953
1954 @Override
1955 public void writeMessageNoTag(MessageLite value) throws IOException {
1956 writeUInt32NoTag(value.getSerializedSize());
1957 value.writeTo(this);
1958 }
1959
1960 @Override
1961 public void write(byte value) throws IOException {
1962 if (position >= limit) {
1963 throw new OutOfSpaceException(
1964 String.format("Pos: %d, limit: %d, len: %d", position, limit, 1));
1965 }
1966 UnsafeUtil.putByte(position++, value);
1967 }
1968
1969 @Override
1970 public void writeBytesNoTag(ByteString value) throws IOException {
1971 writeUInt32NoTag(value.size());
1972 value.writeTo(this);
1973 }
1974
1975 @Override
1976 public void writeByteArrayNoTag(byte[] value, int offset, int length) throws IOException {
1977 writeUInt32NoTag(length);
1978 write(value, offset, length);
1979 }
1980
1981 @Override
1982 public void writeRawBytes(ByteBuffer value) throws IOException {
1983 if (value.hasArray()) {
1984 write(value.array(), value.arrayOffset(), value.capacity());
1985 } else {
1986 ByteBuffer duplicated = value.duplicate();
1987 duplicated.clear();
1988 write(duplicated);
1989 }
1990 }
1991
1992 @Override
1993 public void writeInt32NoTag(int value) throws IOException {
1994 if (value >= 0) {
1995 writeUInt32NoTag(value);
1996 } else {
1997 // Must sign-extend.
1998 writeUInt64NoTag(value);
1999 }
2000 }
2001
2002 @Override
2003 public void writeUInt32NoTag(int value) throws IOException {
2004 if (position <= oneVarintLimit) {
2005 // Optimization to avoid bounds checks on each iteration.
2006 while (true) {
2007 if ((value & ~0x7F) == 0) {
2008 UnsafeUtil.putByte(position++, (byte) value);
2009 return;
2010 } else {
2011 UnsafeUtil.putByte(position++, (byte) ((value & 0x7F) | 0x80));
2012 value >>>= 7;
2013 }
2014 }
2015 } else {
2016 while (position < limit) {
2017 if ((value & ~0x7F) == 0) {
2018 UnsafeUtil.putByte(position++, (byte) value);
2019 return;
2020 } else {
2021 UnsafeUtil.putByte(position++, (byte) ((value & 0x7F) | 0x80));
2022 value >>>= 7;
2023 }
2024 }
2025 throw new OutOfSpaceException(
2026 String.format("Pos: %d, limit: %d, len: %d", position, limit, 1));
2027 }
2028 }
2029
2030 @Override
2031 public void writeFixed32NoTag(int value) throws IOException {
2032 buffer.putInt(bufferPos(position), value);
2033 position += FIXED_32_SIZE;
2034 }
2035
2036 @Override
2037 public void writeUInt64NoTag(long value) throws IOException {
2038 if (position <= oneVarintLimit) {
2039 // Optimization to avoid bounds checks on each iteration.
2040 while (true) {
2041 if ((value & ~0x7FL) == 0) {
2042 UnsafeUtil.putByte(position++, (byte) value);
2043 return;
2044 } else {
2045 UnsafeUtil.putByte(position++, (byte) (((int) value & 0x7F) | 0x80)) ;
2046 value >>>= 7;
2047 }
2048 }
2049 } else {
2050 while (position < limit) {
2051 if ((value & ~0x7FL) == 0) {
2052 UnsafeUtil.putByte(position++, (byte) value);
2053 return;
2054 } else {
2055 UnsafeUtil.putByte(position++, (byte) (((int) value & 0x7F) | 0x80)) ;
2056 value >>>= 7;
2057 }
2058 }
2059 throw new OutOfSpaceException(
2060 String.format("Pos: %d, limit: %d, len: %d", position, limit, 1));
2061 }
2062 }
2063
2064 @Override
2065 public void writeFixed64NoTag(long value) throws IOException {
2066 buffer.putLong(bufferPos(position), value);
2067 position += FIXED_64_SIZE;
2068 }
2069
2070 @Override
2071 public void write(byte[] value, int offset, int length) throws IOException {
2072 if (value == null
2073 || offset < 0
2074 || length < 0
2075 || (value.length - length) < offset
2076 || (limit - length) < position) {
2077 if (value == null) {
2078 throw new NullPointerException("value");
2079 }
2080 throw new OutOfSpaceException(
2081 String.format("Pos: %d, limit: %d, len: %d", position, limit, length ));
2082 }
2083
2084 UnsafeUtil.copyMemory(
2085 value, UnsafeUtil.getArrayBaseOffset() + offset, null, position, lengt h);
2086 position += length;
2087 }
2088
2089 @Override
2090 public void writeLazy(byte[] value, int offset, int length) throws IOExcepti on {
2091 write(value, offset, length);
2092 }
2093
2094 @Override
2095 public void write(ByteBuffer value) throws IOException {
2096 try {
2097 int length = value.remaining();
2098 repositionBuffer(position);
2099 buffer.put(value);
2100 position += length;
2101 } catch (BufferOverflowException e) {
2102 throw new OutOfSpaceException(e);
2103 }
2104 }
2105
2106 @Override
2107 public void writeLazy(ByteBuffer value) throws IOException {
2108 write(value);
2109 }
2110
2111 @Override
2112 public void writeStringNoTag(String value) throws IOException {
2113 long prevPos = position;
2114 try {
2115 // UTF-8 byte length of the string is at least its UTF-16 code unit leng th (value.length()),
2116 // and at most 3 times of it. We take advantage of this in both branches below.
2117 int maxEncodedSize = value.length() * Utf8.MAX_BYTES_PER_CHAR;
2118 int maxLengthVarIntSize = computeUInt32SizeNoTag(maxEncodedSize);
2119 int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
2120 if (minLengthVarIntSize == maxLengthVarIntSize) {
2121 // Save the current position and increment past the length field. We'l l come back
2122 // and write the length field after the encoding is complete.
2123 int stringStart = bufferPos(position) + minLengthVarIntSize;
2124 buffer.position(stringStart);
2125
2126 // Encode the string.
2127 Utf8.encodeUtf8(value, buffer);
2128
2129 // Write the length and advance the position.
2130 int length = buffer.position() - stringStart;
2131 writeUInt32NoTag(length);
2132 position += length;
2133 } else {
2134 // Calculate and write the encoded length.
2135 int length = Utf8.encodedLength(value);
2136 writeUInt32NoTag(length);
2137
2138 // Write the string and advance the position.
2139 repositionBuffer(position);
2140 Utf8.encodeUtf8(value, buffer);
2141 position += length;
2142 }
2143 } catch (UnpairedSurrogateException e) {
2144 // Roll back the change and convert to an IOException.
2145 position = prevPos;
2146 repositionBuffer(position);
2147
2148 // TODO(nathanmittler): We should throw an IOException here instead.
2149 inefficientWriteStringNoTag(value, e);
2150 } catch (IllegalArgumentException e) {
2151 // Thrown by buffer.position() if out of range.
2152 throw new OutOfSpaceException(e);
2153 } catch (IndexOutOfBoundsException e) {
2154 throw new OutOfSpaceException(e);
2155 }
2156 }
2157
2158 @Override
2159 public void flush() {
2160 // Update the position of the original buffer.
2161 originalBuffer.position(bufferPos(position));
2162 }
2163
2164 @Override
2165 public int spaceLeft() {
2166 return (int) (limit - position);
2167 }
2168
2169 @Override
2170 public int getTotalBytesWritten() {
2171 return (int) (position - initialPosition);
2172 }
2173
2174 private void repositionBuffer(long pos) {
2175 buffer.position(bufferPos(pos));
2176 }
2177
2178 private int bufferPos(long pos) {
2179 return (int) (pos - address);
2180 }
2181 }
2182
2183 /**
2184 * Abstract base class for buffered encoders. 1786 * Abstract base class for buffered encoders.
2185 */ 1787 */
2186 private abstract static class AbstractBufferedEncoder extends CodedOutputStrea m { 1788 private abstract static class AbstractBufferedEncoder extends CodedOutputStrea m {
2187 final byte[] buffer; 1789 final byte[] buffer;
2188 final int limit; 1790 final int limit;
2189 int position; 1791 int position;
2190 int totalBytesWritten; 1792 int totalBytesWritten;
2191 1793
2192 AbstractBufferedEncoder(int bufferSize) { 1794 AbstractBufferedEncoder(int bufferSize) {
2193 if (bufferSize < 0) { 1795 if (bufferSize < 0) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2246 /** 1848 /**
2247 * This method does not perform bounds checking on the array. Checking array bounds is the 1849 * This method does not perform bounds checking on the array. Checking array bounds is the
2248 * responsibility of the caller. 1850 * responsibility of the caller.
2249 */ 1851 */
2250 final void bufferUInt32NoTag(int value) { 1852 final void bufferUInt32NoTag(int value) {
2251 if (HAS_UNSAFE_ARRAY_OPERATIONS) { 1853 if (HAS_UNSAFE_ARRAY_OPERATIONS) {
2252 final long originalPos = ARRAY_BASE_OFFSET + position; 1854 final long originalPos = ARRAY_BASE_OFFSET + position;
2253 long pos = originalPos; 1855 long pos = originalPos;
2254 while (true) { 1856 while (true) {
2255 if ((value & ~0x7F) == 0) { 1857 if ((value & ~0x7F) == 0) {
2256 UnsafeUtil.putByte(buffer, pos++, (byte) value); 1858 UNSAFE.putByte(buffer, pos++, (byte) value);
2257 break; 1859 break;
2258 } else { 1860 } else {
2259 UnsafeUtil.putByte(buffer, pos++, (byte) ((value & 0x7F) | 0x80)); 1861 UNSAFE.putByte(buffer, pos++, (byte) ((value & 0x7F) | 0x80));
2260 value >>>= 7; 1862 value >>>= 7;
2261 } 1863 }
2262 } 1864 }
2263 int delta = (int) (pos - originalPos); 1865 int delta = (int) (pos - originalPos);
2264 position += delta; 1866 position += delta;
2265 totalBytesWritten += delta; 1867 totalBytesWritten += delta;
2266 } else { 1868 } else {
2267 while (true) { 1869 while (true) {
2268 if ((value & ~0x7F) == 0) { 1870 if ((value & ~0x7F) == 0) {
2269 buffer[position++] = (byte) value; 1871 buffer[position++] = (byte) value;
(...skipping 11 matching lines...) Expand all
2281 /** 1883 /**
2282 * This method does not perform bounds checking on the array. Checking array bounds is the 1884 * This method does not perform bounds checking on the array. Checking array bounds is the
2283 * responsibility of the caller. 1885 * responsibility of the caller.
2284 */ 1886 */
2285 final void bufferUInt64NoTag(long value) { 1887 final void bufferUInt64NoTag(long value) {
2286 if (HAS_UNSAFE_ARRAY_OPERATIONS) { 1888 if (HAS_UNSAFE_ARRAY_OPERATIONS) {
2287 final long originalPos = ARRAY_BASE_OFFSET + position; 1889 final long originalPos = ARRAY_BASE_OFFSET + position;
2288 long pos = originalPos; 1890 long pos = originalPos;
2289 while (true) { 1891 while (true) {
2290 if ((value & ~0x7FL) == 0) { 1892 if ((value & ~0x7FL) == 0) {
2291 UnsafeUtil.putByte(buffer, pos++, (byte) value); 1893 UNSAFE.putByte(buffer, pos++, (byte) value);
2292 break; 1894 break;
2293 } else { 1895 } else {
2294 UnsafeUtil.putByte(buffer, pos++, (byte) (((int) value & 0x7F) | 0x8 0)); 1896 UNSAFE.putByte(buffer, pos++, (byte) (((int) value & 0x7F) | 0x80));
2295 value >>>= 7; 1897 value >>>= 7;
2296 } 1898 }
2297 } 1899 }
2298 int delta = (int) (pos - originalPos); 1900 int delta = (int) (pos - originalPos);
2299 position += delta; 1901 position += delta;
2300 totalBytesWritten += delta; 1902 totalBytesWritten += delta;
2301 } else { 1903 } else {
2302 while (true) { 1904 while (true) {
2303 if ((value & ~0x7FL) == 0) { 1905 if ((value & ~0x7FL) == 0) {
2304 buffer[position++] = (byte) value; 1906 buffer[position++] = (byte) value;
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after
2991 if (limit - position < requiredSize) { 2593 if (limit - position < requiredSize) {
2992 doFlush(); 2594 doFlush();
2993 } 2595 }
2994 } 2596 }
2995 2597
2996 private void doFlush() throws IOException { 2598 private void doFlush() throws IOException {
2997 out.write(buffer, 0, position); 2599 out.write(buffer, 0, position);
2998 position = 0; 2600 position = 0;
2999 } 2601 }
3000 } 2602 }
2603
2604 /**
2605 * Gets the {@code sun.misc.Unsafe} instance, or {@code null} if not available on this
2606 * platform.
2607 */
2608 private static sun.misc.Unsafe getUnsafe() {
2609 sun.misc.Unsafe unsafe = null;
2610 try {
2611 unsafe = AccessController.doPrivileged(new PrivilegedExceptionAction<sun.m isc.Unsafe>() {
2612 @Override
2613 public sun.misc.Unsafe run() throws Exception {
2614 Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
2615
2616 for (Field f : k.getDeclaredFields()) {
2617 f.setAccessible(true);
2618 Object x = f.get(null);
2619 if (k.isInstance(x)) {
2620 return k.cast(x);
2621 }
2622 }
2623 // The sun.misc.Unsafe field does not exist.
2624 return null;
2625 }
2626 });
2627 } catch (Throwable e) {
2628 // Catching Throwable here due to the fact that Google AppEngine raises No ClassDefFoundError
2629 // for Unsafe.
2630 }
2631
2632 logger.log(Level.FINEST, "sun.misc.Unsafe: {}",
2633 unsafe != null ? "available" : "unavailable");
2634 return unsafe;
2635 }
2636
2637 /**
2638 * Indicates whether or not unsafe array operations are supported on this plat form.
2639 */
2640 // TODO(nathanmittler): Add support for Android's MemoryBlock.
2641 private static boolean supportsUnsafeArrayOperations() {
2642 boolean supported = false;
2643 if (UNSAFE != null) {
2644 try {
2645 UNSAFE.getClass().getMethod("arrayBaseOffset", Class.class);
2646 UNSAFE.getClass().getMethod("putByte", Object.class, long.class, byte.cl ass);
2647 supported = true;
2648 } catch (Throwable e) {
2649 // Do nothing.
2650 }
2651 }
2652 logger.log(Level.FINEST, "Unsafe array operations: {}",
2653 supported ? "available" : "unavailable");
2654 return supported;
2655 }
2656
2657 /**
2658 * Get the base offset for byte arrays, or {@code -1} if {@code sun.misc.Unsaf e} is not
2659 * available.
2660 */
2661 private static <T> int byteArrayBaseOffset() {
2662 return HAS_UNSAFE_ARRAY_OPERATIONS ? UNSAFE.arrayBaseOffset(byte[].class) : -1;
2663 }
3001 } 2664 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698