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 import java.util.Queue; 13 14 /** Utilities for serialization. */ 15 public class ExperimentalSerializationUtil { 16 17 /** 18 * Serializes the given message to a byte array using {@link com.google.protobuf.BinaryWriter}. 19 */ toByteArray(T msg)20 public static <T> byte[] toByteArray(T msg) throws IOException { 21 return toByteArray(msg, Protobuf.getInstance().schemaFor(msg)); 22 } 23 24 /** 25 * Serializes the given message to a byte array using {@link com.google.protobuf.BinaryWriter} 26 * with a customized Schema. 27 */ toByteArray(T msg, Schema<T> schema)28 public static <T> byte[] toByteArray(T msg, Schema<T> schema) throws IOException { 29 BinaryWriter writer = BinaryWriter.newHeapInstance(BufferAllocator.unpooled()); 30 schema.writeTo(msg, writer); 31 32 byte[] out = new byte[writer.getTotalBytesWritten()]; 33 int outPos = 0; 34 Queue<AllocatedBuffer> buffers = writer.complete(); 35 while (true) { 36 AllocatedBuffer buffer = buffers.poll(); 37 if (buffer == null) { 38 break; 39 } 40 int length = buffer.limit() - buffer.position(); 41 System.arraycopy( 42 buffer.array(), buffer.arrayOffset() + buffer.position(), out, outPos, length); 43 outPos += length; 44 } 45 if (out.length != outPos) { 46 throw new IllegalArgumentException("Failed to serialize test message"); 47 } 48 return out; 49 } 50 51 /** Deserializes a message from the given byte array. */ fromByteArray(byte[] data, Class<T> messageType)52 public static <T> T fromByteArray(byte[] data, Class<T> messageType) { 53 if (Android.isOnAndroidDevice()) { 54 return fromByteArrayFastPath(data, messageType); 55 } else { 56 return fromByteArray(data, messageType, ExtensionRegistryLite.getEmptyRegistry()); 57 } 58 } 59 60 /** 61 * Deserializes a message from the given byte array using {@link com.google.protobuf.BinaryReader} 62 * with an extension registry and a customized Schema. 63 */ fromByteArray( byte[] data, Class<T> messageType, ExtensionRegistryLite extensionRegistry)64 public static <T> T fromByteArray( 65 byte[] data, Class<T> messageType, ExtensionRegistryLite extensionRegistry) { 66 try { 67 Schema<T> schema = Protobuf.getInstance().schemaFor(messageType); 68 T msg = schema.newInstance(); 69 schema.mergeFrom( 70 msg, BinaryReader.newInstance(ByteBuffer.wrap(data), true), extensionRegistry); 71 schema.makeImmutable(msg); 72 return msg; 73 } catch (IOException e) { 74 throw new RuntimeException(e); 75 } 76 } 77 78 /** Deserializes a lite message from the given byte array using fast path. */ fromByteArrayFastPath(byte[] data, Class<T> messageType)79 private static <T> T fromByteArrayFastPath(byte[] data, Class<T> messageType) { 80 try { 81 Schema<T> schema = Protobuf.getInstance().schemaFor(messageType); 82 T msg = schema.newInstance(); 83 schema.mergeFrom(msg, data, 0, data.length, new ArrayDecoders.Registers()); 84 schema.makeImmutable(msg); 85 return msg; 86 } catch (IOException e) { 87 throw new RuntimeException(e); 88 } 89 } 90 } 91