    001    /**
    002     * Copyright (C) 2010, Skype Limited
    003     *
    004     * All intellectual property rights, including but not limited to copyrights,
    005     * trademarks and patents, as well as know how and trade secrets contained in,
    006     * relating to, or arising from the internet telephony software of
    007     * Skype Limited (including its affiliates, "Skype"), including without
    008     * limitation this source code, Skype API and related material of such
    009     * software proprietary to Skype and/or its licensors ("IP Rights") are and
    010     * shall remain the exclusive property of Skype and/or its licensors.
    011     * The recipient hereby acknowledges and agrees that any unauthorized use of
    012     * the IP Rights is a violation of intellectual property laws.
    013     *
    014     * Skype reserves all rights and may take legal action against infringers of
    015     * IP Rights.
    016     *
    017     * The recipient agrees not to remove, obscure, make illegible or alter any
    018     * notices or indications of the IP Rights and/or Skype's rights and
    019     * ownership thereof.
    020     */
    021
    022    package com.skype.ipc;
    023
    024    import java.io.IOException;
    025
    026    import com.skype.util.Log;
    027
    028    public abstract class AbstractDecoder
    029    {
    030        private static final String TAG        = "AbstractDecoder";
    031        public static final int     NULL_VALUE = -1;
    032        protected Transport         ioTransport;
    033
    034        AbstractDecoder(Transport in) // ,EventCallback.eType type)
    035        {
    036            ioTransport = in;
    037        }
    038
    039        protected Object decodeOneOfKind(int kind) throws IOException
    040        {
    041            switch (kind) {
    042            case 'z':
    043                // no more parms
    044                //Log.d(TAG, "No more params");
    045                return null;
    046            case 'S':
    047            case 'X':
    048            case 'f':
    049                // decode string
    050                return decodeString();
    051            case 'B':
    052                // decode binary
    053                return decodeBinary();
    054            case '[':
    055                // decode list
    056                return decodeList();
    057            case ']':
    058                // end decoding list
    059                return null;
    060            case 'O':
    061                // decode object
    062                return decodeObjectid();
    063            case 'u':
    064            case 'e':
    065            case 'o':
    066                // decode varuint
    067                return decodeVaruint();
    068            case 'i':
    069                // decode varint
    070                return decodeVarint();
    071            case 'T':
    072                // decode boolean true
    073                return 1;
    074            case 'F':
    075                // decode boolean false
    076                return 0;
    077            default:
    078                Log.e(TAG, "Unknown response parm " + kind + " '" + (char) kind + "'");
    079                throw new IOException();
    080            }
    081            // return null;
    082
    083        }
    084
    085        protected String decodeString() throws IOException
    086        {
    087            int length = decodeVaruint();
    088            if (length > 0) {
    089                byte[] bytes = new byte[length];
    090                ioTransport.read(length, bytes, true);
    091                String s = new String(bytes);
    092                return s;
    093            }
    094            return "";
    095        }
    096
    097        protected byte[] decodeBinary() throws IOException
    098        {
    099            int length = decodeVaruint();
    100            if (length > 0) {
    101                byte[] bytes = new byte[length];
    102                ioTransport.read(length, bytes, true);
    103                return bytes;
    104            }
    105            return new byte[0];
    106        }
    107
    108        protected int decodeVarint() throws IOException
    109        {
    110
    111            int number = decodeVaruint();
    112            if ((1 & number) != 0) {
    113                // negative
    114                number = (number ^ (~0)) >> 1;
    115            }
    116            else {
    117                // positive
    118                number = (number >> 1);
    119            }
    120
    121            return number;
    122        }
    123
    124        protected int decodeVaruint() throws IOException
    125        {
    126            return (decodeOneVaruint(ioTransport));
    127        }
    128
    129        protected static int decodeOneVaruint(Transport i) throws IOException
    130        {
    131            int shift = 0;
    132            int result = 0;
    133            while (true) {
    134                int value = i.read() & 0xFF;
    135                result = result | ((value & 0x7f) << shift);
    136                shift = shift + 7;
    137                if ((value & 0x80) == 0)
    138                    break;
    139            }
    140            return result;
    141        }
    142
    143        protected int decodeObjectid() throws IOException
    144        {
    145            return (decodeVaruint());
    146        }
    147
    148        protected boolean decodeBoolean() throws IOException
    149        {
    150            int v = ioTransport.read();
    151            if (v == 'T') {
    152                return true;
    153            }
    154            else if (v == 'F') {
    155                return false;
    156            }
    157            else {
    158                Log.e(TAG, "Invalid boolean value " + v + "'" + (char) v + "'");
    159                throw new IOException();
    160            }
    161        }
    162
    163        protected ResponseListElement decodeList() throws IOException
    164        {
    165            ResponseListElement rlist = new ResponseListElement(ioTransport);
    166            return rlist;
    167        }
    168    }