Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: third_party/protobuf/java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 15 matching lines...) Expand all
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 30
31 package com.google.protobuf; 31 package com.google.protobuf;
32 32
33 import static java.lang.Math.max; 33 import static java.lang.Math.max;
34 import static java.lang.Math.min; 34 import static java.lang.Math.min;
35 35
36 import java.io.FileOutputStream;
37 import java.io.IOException; 36 import java.io.IOException;
38 import java.io.OutputStream; 37 import java.io.OutputStream;
39 import java.lang.ref.SoftReference; 38 import java.lang.ref.SoftReference;
39 import java.lang.reflect.Field;
40 import java.nio.ByteBuffer; 40 import java.nio.ByteBuffer;
41 import java.nio.channels.WritableByteChannel;
41 42
42 /** 43 /**
43 * Utility class to provide efficient writing of {@link ByteBuffer}s to {@link O utputStream}s. 44 * Utility class to provide efficient writing of {@link ByteBuffer}s to {@link O utputStream}s.
44 */ 45 */
45 final class ByteBufferWriter { 46 final class ByteBufferWriter {
46 private ByteBufferWriter() {} 47 private ByteBufferWriter() {}
47 48
48 /** 49 /**
49 * Minimum size for a cached buffer. This prevents us from allocating buffers that are too 50 * Minimum size for a cached buffer. This prevents us from allocating buffers that are too
50 * small to be easily reused. 51 * small to be easily reused.
(...skipping 17 matching lines...) Expand all
68 /** 69 /**
69 * Keeping a soft reference to a thread-local buffer. This buffer is used for writing a 70 * Keeping a soft reference to a thread-local buffer. This buffer is used for writing a
70 * {@link ByteBuffer} to an {@link OutputStream} when no zero-copy alternative was available. 71 * {@link ByteBuffer} to an {@link OutputStream} when no zero-copy alternative was available.
71 * Using a "soft" reference since VMs may keep this reference around longer th an "weak" 72 * Using a "soft" reference since VMs may keep this reference around longer th an "weak"
72 * (e.g. HotSpot will maintain soft references until memory pressure warrants collection). 73 * (e.g. HotSpot will maintain soft references until memory pressure warrants collection).
73 */ 74 */
74 private static final ThreadLocal<SoftReference<byte[]>> BUFFER = 75 private static final ThreadLocal<SoftReference<byte[]>> BUFFER =
75 new ThreadLocal<SoftReference<byte[]>>(); 76 new ThreadLocal<SoftReference<byte[]>>();
76 77
77 /** 78 /**
79 * This is a hack for GAE, where {@code FileOutputStream} is unavailable.
80 */
81 private static final Class<?> FILE_OUTPUT_STREAM_CLASS = safeGetClass("java.io .FileOutputStream");
82 private static final long CHANNEL_FIELD_OFFSET = getChannelFieldOffset(FILE_OU TPUT_STREAM_CLASS);
83
84 /**
78 * For testing purposes only. Clears the cached buffer to force a new allocati on on the next 85 * For testing purposes only. Clears the cached buffer to force a new allocati on on the next
79 * invocation. 86 * invocation.
80 */ 87 */
81 static void clearCachedBuffer() { 88 static void clearCachedBuffer() {
82 BUFFER.set(null); 89 BUFFER.set(null);
83 } 90 }
84 91
85 /** 92 /**
86 * Writes the remaining content of the buffer to the given stream. The buffer {@code position} 93 * Writes the remaining content of the buffer to the given stream. The buffer {@code position}
87 * will remain unchanged by this method. 94 * will remain unchanged by this method.
88 */ 95 */
89 static void write(ByteBuffer buffer, OutputStream output) throws IOException { 96 static void write(ByteBuffer buffer, OutputStream output) throws IOException {
90 final int initialPos = buffer.position(); 97 final int initialPos = buffer.position();
91 try { 98 try {
92 if (buffer.hasArray()) { 99 if (buffer.hasArray()) {
93 // Optimized write for array-backed buffers. 100 // Optimized write for array-backed buffers.
94 // Note that we're taking the risk that a malicious OutputStream could m odify the array. 101 // Note that we're taking the risk that a malicious OutputStream could m odify the array.
95 output.write(buffer.array(), buffer.arrayOffset() + buffer.position(), b uffer.remaining()); 102 output.write(buffer.array(), buffer.arrayOffset() + buffer.position(), b uffer.remaining());
96 } else if (output instanceof FileOutputStream) { 103 } else if (!writeToChannel(buffer, output)){
97 // Use a channel to write out the ByteBuffer. This will automatically em pty the buffer.
98 ((FileOutputStream) output).getChannel().write(buffer);
99 } else {
100 // Read all of the data from the buffer to an array. 104 // Read all of the data from the buffer to an array.
101 // TODO(nathanmittler): Consider performance improvements for other "kno wn" stream types. 105 // TODO(nathanmittler): Consider performance improvements for other "kno wn" stream types.
102 final byte[] array = getOrCreateBuffer(buffer.remaining()); 106 final byte[] array = getOrCreateBuffer(buffer.remaining());
103 while (buffer.hasRemaining()) { 107 while (buffer.hasRemaining()) {
104 int length = min(buffer.remaining(), array.length); 108 int length = min(buffer.remaining(), array.length);
105 buffer.get(array, 0, length); 109 buffer.get(array, 0, length);
106 output.write(array, 0, length); 110 output.write(array, 0, length);
107 } 111 }
108 } 112 }
109 } finally { 113 } finally {
(...skipping 25 matching lines...) Expand all
135 } 139 }
136 140
137 private static byte[] getBuffer() { 141 private static byte[] getBuffer() {
138 SoftReference<byte[]> sr = BUFFER.get(); 142 SoftReference<byte[]> sr = BUFFER.get();
139 return sr == null ? null : sr.get(); 143 return sr == null ? null : sr.get();
140 } 144 }
141 145
142 private static void setBuffer(byte[] value) { 146 private static void setBuffer(byte[] value) {
143 BUFFER.set(new SoftReference<byte[]>(value)); 147 BUFFER.set(new SoftReference<byte[]>(value));
144 } 148 }
149
150 private static boolean writeToChannel(ByteBuffer buffer, OutputStream output) throws IOException {
151 if (CHANNEL_FIELD_OFFSET >= 0 && FILE_OUTPUT_STREAM_CLASS.isInstance(output) ) {
152 // Use a channel to write out the ByteBuffer. This will automatically empt y the buffer.
153 WritableByteChannel channel = null;
154 try {
155 channel = (WritableByteChannel) UnsafeUtil.getObject(output, CHANNEL_FIE LD_OFFSET);
156 } catch (ClassCastException e) {
157 // Absorb.
158 }
159 if (channel != null) {
160 channel.write(buffer);
161 return true;
162 }
163 }
164 return false;
165 }
166
167 private static Class<?> safeGetClass(String className) {
168 try {
169 return Class.forName(className);
170 } catch (ClassNotFoundException e) {
171 return null;
172 }
173 }
174 private static long getChannelFieldOffset(Class<?> clazz) {
175 try {
176 if (clazz != null && UnsafeUtil.hasUnsafeArrayOperations()) {
177 Field field = clazz.getDeclaredField("channel");
178 return UnsafeUtil.objectFieldOffset(field);
179 }
180 } catch (Throwable e) {
181 // Absorb
182 }
183 return -1;
184 }
145 } 185 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698