diff options
Diffstat (limited to 'third_party/protobuf/3.2.0/java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java')
-rw-r--r-- | third_party/protobuf/3.2.0/java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java | 185 |
1 files changed, 0 insertions, 185 deletions
diff --git a/third_party/protobuf/3.2.0/java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java b/third_party/protobuf/3.2.0/java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java deleted file mode 100644 index 6157a52f50..0000000000 --- a/third_party/protobuf/3.2.0/java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java +++ /dev/null @@ -1,185 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf; - -import static java.lang.Math.max; -import static java.lang.Math.min; - -import java.io.IOException; -import java.io.OutputStream; -import java.lang.ref.SoftReference; -import java.lang.reflect.Field; -import java.nio.ByteBuffer; -import java.nio.channels.WritableByteChannel; - -/** - * Utility class to provide efficient writing of {@link ByteBuffer}s to {@link OutputStream}s. - */ -final class ByteBufferWriter { - private ByteBufferWriter() {} - - /** - * Minimum size for a cached buffer. This prevents us from allocating buffers that are too - * small to be easily reused. - */ - // TODO(nathanmittler): tune this property or allow configuration? - private static final int MIN_CACHED_BUFFER_SIZE = 1024; - - /** - * Maximum size for a cached buffer. If a larger buffer is required, it will be allocated - * but not cached. - */ - // TODO(nathanmittler): tune this property or allow configuration? - private static final int MAX_CACHED_BUFFER_SIZE = 16 * 1024; - - /** - * The fraction of the requested buffer size under which the buffer will be reallocated. - */ - // TODO(nathanmittler): tune this property or allow configuration? - private static final float BUFFER_REALLOCATION_THRESHOLD = 0.5f; - - /** - * Keeping a soft reference to a thread-local buffer. This buffer is used for writing a - * {@link ByteBuffer} to an {@link OutputStream} when no zero-copy alternative was available. - * Using a "soft" reference since VMs may keep this reference around longer than "weak" - * (e.g. HotSpot will maintain soft references until memory pressure warrants collection). - */ - private static final ThreadLocal<SoftReference<byte[]>> BUFFER = - new ThreadLocal<SoftReference<byte[]>>(); - - /** - * This is a hack for GAE, where {@code FileOutputStream} is unavailable. - */ - private static final Class<?> FILE_OUTPUT_STREAM_CLASS = safeGetClass("java.io.FileOutputStream"); - private static final long CHANNEL_FIELD_OFFSET = getChannelFieldOffset(FILE_OUTPUT_STREAM_CLASS); - - /** - * For testing purposes only. Clears the cached buffer to force a new allocation on the next - * invocation. - */ - static void clearCachedBuffer() { - BUFFER.set(null); - } - - /** - * Writes the remaining content of the buffer to the given stream. The buffer {@code position} - * will remain unchanged by this method. - */ - static void write(ByteBuffer buffer, OutputStream output) throws IOException { - final int initialPos = buffer.position(); - try { - if (buffer.hasArray()) { - // Optimized write for array-backed buffers. - // Note that we're taking the risk that a malicious OutputStream could modify the array. - output.write(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining()); - } else if (!writeToChannel(buffer, output)){ - // Read all of the data from the buffer to an array. - // TODO(nathanmittler): Consider performance improvements for other "known" stream types. - final byte[] array = getOrCreateBuffer(buffer.remaining()); - while (buffer.hasRemaining()) { - int length = min(buffer.remaining(), array.length); - buffer.get(array, 0, length); - output.write(array, 0, length); - } - } - } finally { - // Restore the initial position. - buffer.position(initialPos); - } - } - - private static byte[] getOrCreateBuffer(int requestedSize) { - requestedSize = max(requestedSize, MIN_CACHED_BUFFER_SIZE); - - byte[] buffer = getBuffer(); - // Only allocate if we need to. - if (buffer == null || needToReallocate(requestedSize, buffer.length)) { - buffer = new byte[requestedSize]; - - // Only cache the buffer if it's not too big. - if (requestedSize <= MAX_CACHED_BUFFER_SIZE) { - setBuffer(buffer); - } - } - return buffer; - } - - private static boolean needToReallocate(int requestedSize, int bufferLength) { - // First check against just the requested length to avoid the multiply. - return bufferLength < requestedSize - && bufferLength < requestedSize * BUFFER_REALLOCATION_THRESHOLD; - } - - private static byte[] getBuffer() { - SoftReference<byte[]> sr = BUFFER.get(); - return sr == null ? null : sr.get(); - } - - private static void setBuffer(byte[] value) { - BUFFER.set(new SoftReference<byte[]>(value)); - } - - private static boolean writeToChannel(ByteBuffer buffer, OutputStream output) throws IOException { - if (CHANNEL_FIELD_OFFSET >= 0 && FILE_OUTPUT_STREAM_CLASS.isInstance(output)) { - // Use a channel to write out the ByteBuffer. This will automatically empty the buffer. - WritableByteChannel channel = null; - try { - channel = (WritableByteChannel) UnsafeUtil.getObject(output, CHANNEL_FIELD_OFFSET); - } catch (ClassCastException e) { - // Absorb. - } - if (channel != null) { - channel.write(buffer); - return true; - } - } - return false; - } - - private static Class<?> safeGetClass(String className) { - try { - return Class.forName(className); - } catch (ClassNotFoundException e) { - return null; - } - } - private static long getChannelFieldOffset(Class<?> clazz) { - try { - if (clazz != null && UnsafeUtil.hasUnsafeArrayOperations()) { - Field field = clazz.getDeclaredField("channel"); - return UnsafeUtil.objectFieldOffset(field); - } - } catch (Throwable e) { - // Absorb - } - return -1; - } -} |