• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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