• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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