1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 package com.google.protobuf; 9 10 import java.io.IOException; 11 import java.nio.ByteBuffer; 12 13 /** 14 * Provides a number of unsafe byte operations to be used by advanced applications with high 15 * performance requirements. These methods are referred to as "unsafe" because they potentially 16 * expose the backing buffer of a {@link ByteString} to the application. 17 * 18 * <p><strong>DISCLAIMER:</strong> The methods in this class should only be called if it is 19 * guaranteed that the buffer backing the {@link ByteString} will never change! Mutation of a {@link 20 * ByteString} can lead to unexpected and undesirable consequences in your application, and will 21 * likely be difficult to debug. Proceed with caution! 22 * 23 * <p>This can have a number of significant side effects that have spooky-action-at-a-distance-like 24 * behavior. In particular, if the bytes value changes out from under a Protocol Buffer: 25 * 26 * <ul> 27 * <li>serialization may throw 28 * <li>serialization may succeed but the wrong bytes may be written out 29 * <li>messages are no longer threadsafe 30 * <li>hashCode may be incorrect 31 * <ul> 32 * <li>can result in a permanent memory leak when used as a key in a long-lived HashMap 33 * <li>the semantics of many programs may be violated if this is the case 34 * </ul> 35 * </ul> 36 * 37 * Each of these issues will occur in parts of the code base that are entirely distinct from the 38 * parts of the code base modifying the buffer. In fact, both parts of the code base may be correct 39 * - it is the bridging with the unsafe operations that was in error! 40 */ 41 public final class UnsafeByteOperations { UnsafeByteOperations()42 private UnsafeByteOperations() {} 43 44 /** 45 * An unsafe operation that returns a {@link ByteString} that is backed by the provided buffer. 46 * 47 * @param buffer the buffer to be wrapped 48 * @return a {@link ByteString} backed by the provided buffer 49 */ unsafeWrap(byte[] buffer)50 public static ByteString unsafeWrap(byte[] buffer) { 51 return ByteString.wrap(buffer); 52 } 53 54 /** 55 * An unsafe operation that returns a {@link ByteString} that is backed by a subregion of the 56 * provided buffer. 57 * 58 * @param buffer the buffer to be wrapped 59 * @param offset the offset of the wrapped region 60 * @param length the number of bytes of the wrapped region 61 * @return a {@link ByteString} backed by the provided buffer 62 */ unsafeWrap(byte[] buffer, int offset, int length)63 public static ByteString unsafeWrap(byte[] buffer, int offset, int length) { 64 return ByteString.wrap(buffer, offset, length); 65 } 66 67 /** 68 * An unsafe operation that returns a {@link ByteString} that is backed by the provided buffer. 69 * 70 * @param buffer the Java NIO buffer to be wrapped 71 * @return a {@link ByteString} backed by the provided buffer 72 */ unsafeWrap(ByteBuffer buffer)73 public static ByteString unsafeWrap(ByteBuffer buffer) { 74 return ByteString.wrap(buffer); 75 } 76 77 /** 78 * Writes the given {@link ByteString} to the provided {@link ByteOutput}. Calling this method may 79 * result in multiple operations on the target {@link ByteOutput} (i.e. for roped {@link 80 * ByteString}s). 81 * 82 * <p>This method exposes the internal backing buffer(s) of the {@link ByteString} to the {@link 83 * ByteOutput} in order to avoid additional copying overhead. It would be possible for a malicious 84 * {@link ByteOutput} to corrupt the {@link ByteString}. Use with caution! 85 * 86 * <p>NOTE: The {@link ByteOutput} <strong>MUST NOT</strong> modify the provided buffers. Doing so 87 * may result in corrupted data, which would be difficult to debug. 88 * 89 * @param bytes the {@link ByteString} to be written 90 * @param output the output to receive the bytes 91 * @throws IOException if an I/O error occurs 92 */ unsafeWriteTo(ByteString bytes, ByteOutput output)93 public static void unsafeWriteTo(ByteString bytes, ByteOutput output) throws IOException { 94 bytes.writeTo(output); 95 } 96 } 97