| OLD | NEW |
| 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 24 matching lines...) Expand all Loading... |
| 35 | 35 |
| 36 /** | 36 /** |
| 37 * Provides a number of unsafe byte operations to be used by advanced applicatio
ns with high | 37 * Provides a number of unsafe byte operations to be used by advanced applicatio
ns with high |
| 38 * performance requirements. These methods are referred to as "unsafe" due to th
e fact that they | 38 * performance requirements. These methods are referred to as "unsafe" due to th
e fact that they |
| 39 * potentially expose the backing buffer of a {@link ByteString} to the applicat
ion. | 39 * potentially expose the backing buffer of a {@link ByteString} to the applicat
ion. |
| 40 * | 40 * |
| 41 * <p><strong>DISCLAIMER:</strong> The methods in this class should only be call
ed if it is | 41 * <p><strong>DISCLAIMER:</strong> The methods in this class should only be call
ed if it is |
| 42 * guaranteed that the buffer backing the {@link ByteString} will never change!
Mutation of a | 42 * guaranteed that the buffer backing the {@link ByteString} will never change!
Mutation of a |
| 43 * {@link ByteString} can lead to unexpected and undesirable consequences in you
r application, | 43 * {@link ByteString} can lead to unexpected and undesirable consequences in you
r application, |
| 44 * and will likely be difficult to debug. Proceed with caution! | 44 * and will likely be difficult to debug. Proceed with caution! |
| 45 * |
| 46 * <p>This can have a number of significant side affects that have |
| 47 * spooky-action-at-a-distance-like behavior. In particular, if the bytes value
changes out from |
| 48 * under a Protocol Buffer: |
| 49 * <ul> |
| 50 * <li>serialization may throw |
| 51 * <li>serialization may succeed but the wrong bytes may be written out |
| 52 * <li>messages are no longer threadsafe |
| 53 * <li>hashCode may be incorrect |
| 54 * <ul> |
| 55 * <li>can result in a permanent memory leak when used as a key in a long-live
d HashMap |
| 56 * <li> the semantics of many programs may be violated if this is the case |
| 57 * </ul> |
| 58 * </ul> |
| 59 * Each of these issues will occur in parts of the code base that are entirely d
istinct from the |
| 60 * parts of the code base modifying the buffer. In fact, both parts of the code
base may be correct |
| 61 * - it is the bridging with the unsafe operations that was in error! |
| 45 */ | 62 */ |
| 46 @ExperimentalApi | 63 @ExperimentalApi |
| 47 public final class UnsafeByteOperations { | 64 public final class UnsafeByteOperations { |
| 48 private UnsafeByteOperations() {} | 65 private UnsafeByteOperations() {} |
| 49 | 66 |
| 50 /** | 67 /** |
| 51 * An unsafe operation that returns a {@link ByteString} that is backed by the
provided buffer. | 68 * An unsafe operation that returns a {@link ByteString} that is backed by the
provided buffer. |
| 52 * | 69 * |
| 70 * @param buffer the buffer to be wrapped |
| 71 * @return a {@link ByteString} backed by the provided buffer |
| 72 */ |
| 73 public static ByteString unsafeWrap(byte[] buffer) { |
| 74 return ByteString.wrap(buffer); |
| 75 } |
| 76 |
| 77 /** |
| 78 * An unsafe operation that returns a {@link ByteString} that is backed by a s
ubregion of the |
| 79 * provided buffer. |
| 80 * |
| 81 * @param buffer the buffer to be wrapped |
| 82 * @param offset the offset of the wrapped region |
| 83 * @param length the number of bytes of the wrapped region |
| 84 * @return a {@link ByteString} backed by the provided buffer |
| 85 */ |
| 86 public static ByteString unsafeWrap(byte[] buffer, int offset, int length) { |
| 87 return ByteString.wrap(buffer, offset, length); |
| 88 } |
| 89 |
| 90 /** |
| 91 * An unsafe operation that returns a {@link ByteString} that is backed by the
provided buffer. |
| 92 * |
| 53 * @param buffer the Java NIO buffer to be wrapped | 93 * @param buffer the Java NIO buffer to be wrapped |
| 54 * @return a {@link ByteString} backed by the provided buffer | 94 * @return a {@link ByteString} backed by the provided buffer |
| 55 */ | 95 */ |
| 56 public static ByteString unsafeWrap(ByteBuffer buffer) { | 96 public static ByteString unsafeWrap(ByteBuffer buffer) { |
| 57 if (buffer.hasArray()) { | 97 return ByteString.wrap(buffer); |
| 58 final int offset = buffer.arrayOffset(); | |
| 59 return ByteString.wrap(buffer.array(), offset + buffer.position(), buffer.
remaining()); | |
| 60 } else { | |
| 61 return new NioByteString(buffer); | |
| 62 } | |
| 63 } | 98 } |
| 64 | 99 |
| 65 /** | 100 /** |
| 66 * Writes the given {@link ByteString} to the provided {@link ByteOutput}. Cal
ling this method may | 101 * Writes the given {@link ByteString} to the provided {@link ByteOutput}. Cal
ling this method may |
| 67 * result in multiple operations on the target {@link ByteOutput} | 102 * result in multiple operations on the target {@link ByteOutput} |
| 68 * (i.e. for roped {@link ByteString}s). | 103 * (i.e. for roped {@link ByteString}s). |
| 69 * | 104 * |
| 70 * <p>This method exposes the internal backing buffer(s) of the {@link ByteStr
ing} to the {@link | 105 * <p>This method exposes the internal backing buffer(s) of the {@link ByteStr
ing} to the {@link |
| 71 * ByteOutput} in order to avoid additional copying overhead. It would be poss
ible for a malicious | 106 * ByteOutput} in order to avoid additional copying overhead. It would be poss
ible for a malicious |
| 72 * {@link ByteOutput} to corrupt the {@link ByteString}. Use with caution! | 107 * {@link ByteOutput} to corrupt the {@link ByteString}. Use with caution! |
| 73 * | 108 * |
| 74 * <p> NOTE: The {@link ByteOutput} <strong>MUST NOT</strong> modify the provi
ded buffers. Doing | 109 * <p> NOTE: The {@link ByteOutput} <strong>MUST NOT</strong> modify the provi
ded buffers. Doing |
| 75 * so may result in corrupted data, which would be difficult to debug. | 110 * so may result in corrupted data, which would be difficult to debug. |
| 76 * | 111 * |
| 77 * @param bytes the {@link ByteString} to be written | 112 * @param bytes the {@link ByteString} to be written |
| 78 * @param output the output to receive the bytes | 113 * @param output the output to receive the bytes |
| 79 * @throws IOException if an I/O error occurs | 114 * @throws IOException if an I/O error occurs |
| 80 */ | 115 */ |
| 81 public static void unsafeWriteTo(ByteString bytes, ByteOutput output) throws I
OException { | 116 public static void unsafeWriteTo(ByteString bytes, ByteOutput output) throws I
OException { |
| 82 bytes.writeTo(output); | 117 bytes.writeTo(output); |
| 83 } | 118 } |
| 119 |
| 84 } | 120 } |
| OLD | NEW |