| 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! | |
| 62 */ | 45 */ |
| 63 @ExperimentalApi | 46 @ExperimentalApi |
| 64 public final class UnsafeByteOperations { | 47 public final class UnsafeByteOperations { |
| 65 private UnsafeByteOperations() {} | 48 private UnsafeByteOperations() {} |
| 66 | 49 |
| 67 /** | 50 /** |
| 68 * An unsafe operation that returns a {@link ByteString} that is backed by the
provided buffer. | 51 * An unsafe operation that returns a {@link ByteString} that is backed by the
provided buffer. |
| 69 * | 52 * |
| 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 * | |
| 93 * @param buffer the Java NIO buffer to be wrapped | 53 * @param buffer the Java NIO buffer to be wrapped |
| 94 * @return a {@link ByteString} backed by the provided buffer | 54 * @return a {@link ByteString} backed by the provided buffer |
| 95 */ | 55 */ |
| 96 public static ByteString unsafeWrap(ByteBuffer buffer) { | 56 public static ByteString unsafeWrap(ByteBuffer buffer) { |
| 97 return ByteString.wrap(buffer); | 57 if (buffer.hasArray()) { |
| 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 } |
| 98 } | 63 } |
| 99 | 64 |
| 100 /** | 65 /** |
| 101 * Writes the given {@link ByteString} to the provided {@link ByteOutput}. Cal
ling this method may | 66 * Writes the given {@link ByteString} to the provided {@link ByteOutput}. Cal
ling this method may |
| 102 * result in multiple operations on the target {@link ByteOutput} | 67 * result in multiple operations on the target {@link ByteOutput} |
| 103 * (i.e. for roped {@link ByteString}s). | 68 * (i.e. for roped {@link ByteString}s). |
| 104 * | 69 * |
| 105 * <p>This method exposes the internal backing buffer(s) of the {@link ByteStr
ing} to the {@link | 70 * <p>This method exposes the internal backing buffer(s) of the {@link ByteStr
ing} to the {@link |
| 106 * ByteOutput} in order to avoid additional copying overhead. It would be poss
ible for a malicious | 71 * ByteOutput} in order to avoid additional copying overhead. It would be poss
ible for a malicious |
| 107 * {@link ByteOutput} to corrupt the {@link ByteString}. Use with caution! | 72 * {@link ByteOutput} to corrupt the {@link ByteString}. Use with caution! |
| 108 * | 73 * |
| 109 * <p> NOTE: The {@link ByteOutput} <strong>MUST NOT</strong> modify the provi
ded buffers. Doing | 74 * <p> NOTE: The {@link ByteOutput} <strong>MUST NOT</strong> modify the provi
ded buffers. Doing |
| 110 * so may result in corrupted data, which would be difficult to debug. | 75 * so may result in corrupted data, which would be difficult to debug. |
| 111 * | 76 * |
| 112 * @param bytes the {@link ByteString} to be written | 77 * @param bytes the {@link ByteString} to be written |
| 113 * @param output the output to receive the bytes | 78 * @param output the output to receive the bytes |
| 114 * @throws IOException if an I/O error occurs | 79 * @throws IOException if an I/O error occurs |
| 115 */ | 80 */ |
| 116 public static void unsafeWriteTo(ByteString bytes, ByteOutput output) throws I
OException { | 81 public static void unsafeWriteTo(ByteString bytes, ByteOutput output) throws I
OException { |
| 117 bytes.writeTo(output); | 82 bytes.writeTo(output); |
| 118 } | 83 } |
| 119 | |
| 120 } | 84 } |
| OLD | NEW |