1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.mojo.bindings;
6
7import org.chromium.mojo.system.Core;
8
9import java.nio.ByteBuffer;
10
11/**
12 * Base class for all mojo structs.
13 */
14public abstract class Struct {
15    /**
16     * The base size of the encoded struct.
17     */
18    private final int mEncodedBaseSize;
19
20    /**
21     * The version of the struct.
22     */
23    private final int mVersion;
24
25    /**
26     * Constructor.
27     */
28    protected Struct(int encodedBaseSize, int version) {
29        mEncodedBaseSize = encodedBaseSize;
30        mVersion = version;
31    }
32
33    /**
34     * Returns the version of the struct. It is the max version of the struct in the mojom if it has
35     * been created locally, and the version of the received struct if it has been deserialized.
36     */
37    public int getVersion() {
38        return mVersion;
39    }
40
41    /**
42     * Returns the serialization of the struct. This method can close Handles.
43     *
44     * @param core the |Core| implementation used to generate handles. Only used if the data
45     *            structure being encoded contains interfaces, can be |null| otherwise.
46     */
47    public Message serialize(Core core) {
48        Encoder encoder = new Encoder(core, mEncodedBaseSize);
49        encode(encoder);
50        return encoder.getMessage();
51    }
52
53    /**
54     * Similar to the method above, but returns the serialization result as |ByteBuffer|.
55     *
56     * @throws UnsupportedOperationException if the struct contains interfaces or handles.
57     * @throws SerializationException on serialization failure.
58     */
59    public ByteBuffer serialize() {
60        // If the struct contains interfaces which require a non-null |Core| instance, it will throw
61        // UnsupportedOperationException.
62        Message message = serialize(null);
63
64        if (!message.getHandles().isEmpty())
65            throw new UnsupportedOperationException("Handles are discarded.");
66
67        return message.getData();
68    }
69
70    /**
71     * Returns the serialization of the struct prepended with the given header.
72     *
73     * @param header the header to prepend to the returned message.
74     * @param core the |Core| implementation used to generate handles. Only used if the |Struct|
75     *            being encoded contains interfaces, can be |null| otherwise.
76     */
77    public ServiceMessage serializeWithHeader(Core core, MessageHeader header) {
78        Encoder encoder = new Encoder(core, mEncodedBaseSize + header.getSize());
79        header.encode(encoder);
80        encode(encoder);
81        return new ServiceMessage(encoder.getMessage(), header);
82    }
83
84    /**
85     * Use the given encoder to serialize this data structure.
86     */
87    protected abstract void encode(Encoder encoder);
88}
89