1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2014 The Chromium Authors. All rights reserved.
2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be
3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file.
4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezpackage org.chromium.mojo.bindings;
6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezimport org.chromium.mojo.system.Core;
8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
9cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelliimport java.nio.ByteBuffer;
10cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli
11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez/**
12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez * Base class for all mojo structs.
13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez */
14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezpublic abstract class Struct {
15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    /**
16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     * The base size of the encoded struct.
17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     */
18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    private final int mEncodedBaseSize;
19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    /**
21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     * The version of the struct.
22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     */
23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    private final int mVersion;
24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    /**
26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     * Constructor.
27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     */
28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    protected Struct(int encodedBaseSize, int version) {
29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        mEncodedBaseSize = encodedBaseSize;
30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        mVersion = version;
31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    }
32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    /**
34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     * Returns the version of the struct. It is the max version of the struct in the mojom if it has
35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     * been created locally, and the version of the received struct if it has been deserialized.
36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     */
37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    public int getVersion() {
38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        return mVersion;
39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    }
40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    /**
42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     * Returns the serialization of the struct. This method can close Handles.
43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     *
44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     * @param core the |Core| implementation used to generate handles. Only used if the data
45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     *            structure being encoded contains interfaces, can be |null| otherwise.
46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     */
47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    public Message serialize(Core core) {
48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        Encoder encoder = new Encoder(core, mEncodedBaseSize);
49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        encode(encoder);
50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        return encoder.getMessage();
51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    }
52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    /**
54cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli     * Similar to the method above, but returns the serialization result as |ByteBuffer|.
55cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli     *
56cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli     * @throws UnsupportedOperationException if the struct contains interfaces or handles.
57cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli     * @throws SerializationException on serialization failure.
58cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli     */
59cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli    public ByteBuffer serialize() {
60cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli        // If the struct contains interfaces which require a non-null |Core| instance, it will throw
61cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli        // UnsupportedOperationException.
62cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli        Message message = serialize(null);
63cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli
64cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli        if (!message.getHandles().isEmpty())
65cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli            throw new UnsupportedOperationException("Handles are discarded.");
66cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli
67cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli        return message.getData();
68cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli    }
69cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli
70cfc1eaa913db3974e56c87b5489bda0a2bf36d93Jay Civelli    /**
71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     * Returns the serialization of the struct prepended with the given header.
72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     *
73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     * @param header the header to prepend to the returned message.
74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     * @param core the |Core| implementation used to generate handles. Only used if the |Struct|
75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     *            being encoded contains interfaces, can be |null| otherwise.
76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     */
77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    public ServiceMessage serializeWithHeader(Core core, MessageHeader header) {
78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        Encoder encoder = new Encoder(core, mEncodedBaseSize + header.getSize());
79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        header.encode(encoder);
80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        encode(encoder);
81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        return new ServiceMessage(encoder.getMessage(), header);
82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    }
83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    /**
85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     * Use the given encoder to serialize this data structure.
86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez     */
87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    protected abstract void encode(Encoder encoder);
88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
89