ChunkHandler.java revision adc854b798c1cfe3bfd4c27d68d5cee38ca617da
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.apache.harmony.dalvik.ddmc;
18
19import java.nio.ByteBuffer;
20import java.nio.ByteOrder;
21
22/**
23 * Handle a chunk of data sent from a DDM server.
24 *
25 * To handle a chunk type, sub-class ChunkHandler and register your class
26 * with DdmServer.
27 */
28public abstract class ChunkHandler {
29
30    public static final ByteOrder CHUNK_ORDER = ByteOrder.BIG_ENDIAN;
31
32    public static final int CHUNK_FAIL = type("FAIL");
33
34
35    public ChunkHandler() {}
36
37    /**
38     * Called when the DDM server connects.  The handler is allowed to
39     * send messages to the server.
40     */
41    public abstract void connected();
42
43    /**
44     * Called when the DDM server disconnects.  Can be used to disable
45     * periodic transmissions or clean up saved state.
46     */
47    public abstract void disconnected();
48
49    /**
50     * Handle a single chunk of data.  "request" includes the type and
51     * the chunk payload.
52     *
53     * Returns a response in a Chunk.
54     */
55    public abstract Chunk handleChunk(Chunk request);
56
57    /**
58     * Create a FAIL chunk.  The "handleChunk" methods can use this to
59     * return an error message when they are not able to process a chunk.
60     */
61    public static Chunk createFailChunk(int errorCode, String msg) {
62        if (msg == null)
63            msg = "";
64
65        ByteBuffer out = ByteBuffer.allocate(8 + msg.length() * 2);
66        out.order(ChunkHandler.CHUNK_ORDER);
67        out.putInt(errorCode);
68        out.putInt(msg.length());
69        putString(out, msg);
70
71        return new Chunk(CHUNK_FAIL, out);
72    }
73
74    /**
75     * Utility function to wrap a ByteBuffer around a Chunk.
76     */
77    public static ByteBuffer wrapChunk(Chunk request) {
78        ByteBuffer in;
79
80        in = ByteBuffer.wrap(request.data, request.offset, request.length);
81        in.order(CHUNK_ORDER);
82        return in;
83    }
84
85
86    /**
87     * Utility function to copy a String out of a ByteBuffer.
88     *
89     * This is here because multiple chunk handlers can make use of it,
90     * and there's nowhere better to put it.
91     */
92    public static String getString(ByteBuffer buf, int len) {
93        char[] data = new char[len];
94        for (int i = 0; i < len; i++)
95            data[i] = buf.getChar();
96        return new String(data);
97    }
98
99    /**
100     * Utility function to copy a String into a ByteBuffer.
101     */
102    public static void putString(ByteBuffer buf, String str) {
103        int len = str.length();
104        for (int i = 0; i < len; i++)
105            buf.putChar(str.charAt(i));
106    }
107
108    /**
109     * Convert a 4-character string to a 32-bit type.
110     */
111    public static int type(String typeName)
112    {
113        int val = 0;
114
115        if (typeName.length() != 4)
116            throw new RuntimeException();
117
118        for (int i = 0; i < 4; i++) {
119            val <<= 8;
120            val |= (byte) typeName.charAt(i);
121        }
122
123        return val;
124    }
125
126    /**
127     * Convert an integer type to a 4-character string.
128     */
129    public static String name(int type)
130    {
131        char[] ascii = new char[4];
132
133        ascii[0] = (char) ((type >> 24) & 0xff);
134        ascii[1] = (char) ((type >> 16) & 0xff);
135        ascii[2] = (char) ((type >> 8) & 0xff);
136        ascii[3] = (char) (type & 0xff);
137
138        return new String(ascii);
139    }
140
141}
142
143