1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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. 30 31 package com.google.protobuf; 32 33 import java.io.IOException; 34 import java.nio.ByteBuffer; 35 import java.util.Queue; 36 37 /** Utilities for serialization. */ 38 public class ExperimentalSerializationUtil { 39 40 /** 41 * Serializes the given message to a byte array using {@link com.google.protobuf.BinaryWriter}. 42 */ toByteArray(T msg)43 public static <T> byte[] toByteArray(T msg) throws IOException { 44 return toByteArray(msg, Protobuf.getInstance().schemaFor(msg)); 45 } 46 47 /** 48 * Serializes the given message to a byte array using {@link com.google.protobuf.BinaryWriter} 49 * with a customized Schema. 50 */ toByteArray(T msg, Schema<T> schema)51 public static <T> byte[] toByteArray(T msg, Schema<T> schema) throws IOException { 52 BinaryWriter writer = BinaryWriter.newHeapInstance(BufferAllocator.unpooled()); 53 schema.writeTo(msg, writer); 54 55 byte[] out = new byte[writer.getTotalBytesWritten()]; 56 int outPos = 0; 57 Queue<AllocatedBuffer> buffers = writer.complete(); 58 while (true) { 59 AllocatedBuffer buffer = buffers.poll(); 60 if (buffer == null) { 61 break; 62 } 63 int length = buffer.limit() - buffer.position(); 64 System.arraycopy( 65 buffer.array(), buffer.arrayOffset() + buffer.position(), out, outPos, length); 66 outPos += length; 67 } 68 if (out.length != outPos) { 69 throw new IllegalArgumentException("Failed to serialize test message"); 70 } 71 return out; 72 } 73 74 /** Deserializes a message from the given byte array. */ fromByteArray(byte[] data, Class<T> messageType)75 public static <T> T fromByteArray(byte[] data, Class<T> messageType) { 76 if (Android.isOnAndroidDevice()) { 77 return fromByteArrayFastPath(data, messageType); 78 } else { 79 return fromByteArray(data, messageType, ExtensionRegistryLite.getEmptyRegistry()); 80 } 81 } 82 83 /** 84 * Deserializes a message from the given byte array using {@link com.google.protobuf.BinaryReader} 85 * with an extension registry and a customized Schema. 86 */ fromByteArray( byte[] data, Class<T> messageType, ExtensionRegistryLite extensionRegistry)87 public static <T> T fromByteArray( 88 byte[] data, Class<T> messageType, ExtensionRegistryLite extensionRegistry) { 89 try { 90 Schema<T> schema = Protobuf.getInstance().schemaFor(messageType); 91 T msg = schema.newInstance(); 92 schema.mergeFrom( 93 msg, BinaryReader.newInstance(ByteBuffer.wrap(data), true), extensionRegistry); 94 schema.makeImmutable(msg); 95 return msg; 96 } catch (IOException e) { 97 throw new RuntimeException(e); 98 } 99 } 100 101 /** Deserializes a lite message from the given byte array using fast path. */ fromByteArrayFastPath(byte[] data, Class<T> messageType)102 private static <T> T fromByteArrayFastPath(byte[] data, Class<T> messageType) { 103 try { 104 Schema<T> schema = Protobuf.getInstance().schemaFor(messageType); 105 T msg = schema.newInstance(); 106 schema.mergeFrom(msg, data, 0, data.length, new ArrayDecoders.Registers()); 107 schema.makeImmutable(msg); 108 return msg; 109 } catch (IOException e) { 110 throw new RuntimeException(e); 111 } 112 } 113 } 114