Home | History | Annotate | Download | only in ddmc
      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 
     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         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      */
    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