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

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

Issue 2600753002: Reverts third_party/protobuf: Update to HEAD (f52e188fe4) (Closed)
Patch Set: Created 3 years, 12 months 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;
36 import java.io.IOException; 37 import java.io.IOException;
37 import java.io.OutputStream; 38 import java.io.OutputStream;
38 import java.lang.ref.SoftReference; 39 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;
42 41
43 /** 42 /**
44 * Utility class to provide efficient writing of {@link ByteBuffer}s to {@link O utputStream}s. 43 * Utility class to provide efficient writing of {@link ByteBuffer}s to {@link O utputStream}s.
45 */ 44 */
46 final class ByteBufferWriter { 45 final class ByteBufferWriter {
47 private ByteBufferWriter() {} 46 private ByteBufferWriter() {}
48 47
49 /** 48 /**
50 * Minimum size for a cached buffer. This prevents us from allocating buffers that are too 49 * Minimum size for a cached buffer. This prevents us from allocating buffers that are too
51 * small to be easily reused. 50 * small to be easily reused.
(...skipping 17 matching lines...) Expand all
69 /** 68 /**
70 * Keeping a soft reference to a thread-local buffer. This buffer is used for writing a 69 * Keeping a soft reference to a thread-local buffer. This buffer is used for writing a
71 * {@link ByteBuffer} to an {@link OutputStream} when no zero-copy alternative was available. 70 * {@link ByteBuffer} to an {@link OutputStream} when no zero-copy alternative was available.
72 * Using a "soft" reference since VMs may keep this reference around longer th an "weak" 71 * Using a "soft" reference since VMs may keep this reference around longer th an "weak"
73 * (e.g. HotSpot will maintain soft references until memory pressure warrants collection). 72 * (e.g. HotSpot will maintain soft references until memory pressure warrants collection).
74 */ 73 */
75 private static final ThreadLocal<SoftReference<byte[]>> BUFFER = 74 private static final ThreadLocal<SoftReference<byte[]>> BUFFER =
76 new ThreadLocal<SoftReference<byte[]>>(); 75 new ThreadLocal<SoftReference<byte[]>>();
77 76
78 /** 77 /**
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 /**
85 * For testing purposes only. Clears the cached buffer to force a new allocati on on the next 78 * For testing purposes only. Clears the cached buffer to force a new allocati on on the next
86 * invocation. 79 * invocation.
87 */ 80 */
88 static void clearCachedBuffer() { 81 static void clearCachedBuffer() {
89 BUFFER.set(null); 82 BUFFER.set(null);
90 } 83 }
91 84
92 /** 85 /**
93 * Writes the remaining content of the buffer to the given stream. The buffer {@code position} 86 * Writes the remaining content of the buffer to the given stream. The buffer {@code position}
94 * will remain unchanged by this method. 87 * will remain unchanged by this method.
95 */ 88 */
96 static void write(ByteBuffer buffer, OutputStream output) throws IOException { 89 static void write(ByteBuffer buffer, OutputStream output) throws IOException {
97 final int initialPos = buffer.position(); 90 final int initialPos = buffer.position();
98 try { 91 try {
99 if (buffer.hasArray()) { 92 if (buffer.hasArray()) {
100 // Optimized write for array-backed buffers. 93 // Optimized write for array-backed buffers.
101 // Note that we're taking the risk that a malicious OutputStream could m odify the array. 94 // Note that we're taking the risk that a malicious OutputStream could m odify the array.
102 output.write(buffer.array(), buffer.arrayOffset() + buffer.position(), b uffer.remaining()); 95 output.write(buffer.array(), buffer.arrayOffset() + buffer.position(), b uffer.remaining());
103 } else if (!writeToChannel(buffer, output)){ 96 } else if (output instanceof FileOutputStream) {
97 // Use a channel to write out the ByteBuffer. This will automatically em pty the buffer.
98 ((FileOutputStream) output).getChannel().write(buffer);
99 } else {
104 // Read all of the data from the buffer to an array. 100 // Read all of the data from the buffer to an array.
105 // TODO(nathanmittler): Consider performance improvements for other "kno wn" stream types. 101 // TODO(nathanmittler): Consider performance improvements for other "kno wn" stream types.
106 final byte[] array = getOrCreateBuffer(buffer.remaining()); 102 final byte[] array = getOrCreateBuffer(buffer.remaining());
107 while (buffer.hasRemaining()) { 103 while (buffer.hasRemaining()) {
108 int length = min(buffer.remaining(), array.length); 104 int length = min(buffer.remaining(), array.length);
109 buffer.get(array, 0, length); 105 buffer.get(array, 0, length);
110 output.write(array, 0, length); 106 output.write(array, 0, length);
111 } 107 }
112 } 108 }
113 } finally { 109 } finally {
(...skipping 25 matching lines...) Expand all
139 } 135 }
140 136
141 private static byte[] getBuffer() { 137 private static byte[] getBuffer() {
142 SoftReference<byte[]> sr = BUFFER.get(); 138 SoftReference<byte[]> sr = BUFFER.get();
143 return sr == null ? null : sr.get(); 139 return sr == null ? null : sr.get();
144 } 140 }
145 141
146 private static void setBuffer(byte[] value) { 142 private static void setBuffer(byte[] value) {
147 BUFFER.set(new SoftReference<byte[]>(value)); 143 BUFFER.set(new SoftReference<byte[]>(value));
148 } 144 }
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 }
185 } 145 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698