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 
17 package org.apache.harmony.dalvik.ddmc;
18 
19 import java.nio.ByteBuffer;
20 import 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  */
28 public 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 
ChunkHandler()35     public ChunkHandler() {}
36 
37     /**
38      * Called when the DDM server connects.  The handler is allowed to
39      * send messages to the server.
40      */
connected()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      */
disconnected()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      */
handleChunk(Chunk request)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      */
createFailChunk(int errorCode, String msg)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      */
wrapChunk(Chunk request)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      */
getString(ByteBuffer buf, int len)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      */
putString(ByteBuffer buf, String str)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      */
type(String typeName)111     public static int type(String typeName) {
112         if (typeName.length() != 4) {
113             throw new IllegalArgumentException("Bad type name: " + typeName);
114         }
115         int result = 0;
116         for (int i = 0; i < 4; ++i) {
117             result = ((result << 8) | (typeName.charAt(i) & 0xff));
118         }
119         return result;
120     }
121 
122     /**
123      * Convert an integer type to a 4-character string.
124      */
name(int type)125     public static String name(int type)
126     {
127         char[] ascii = new char[4];
128 
129         ascii[0] = (char) ((type >> 24) & 0xff);
130         ascii[1] = (char) ((type >> 16) & 0xff);
131         ascii[2] = (char) ((type >> 8) & 0xff);
132         ascii[3] = (char) (type & 0xff);
133 
134         return new String(ascii);
135     }
136 
137 }
138