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 Log.d(TAG, "Parm is list. Starting list decoding...");
057 return decodeList();
058 case ']':
059 // end decoding list
060 Log.d(TAG, "Ending list decoding");
061 return null;
062 case 'O':
063 // decode object
064 return decodeObjectid();
065 case 'u':
066 case 'e':
067 case 'o':
068 // decode varuint
069 return decodeVaruint();
070 case 'i':
071 // decode varint
072 return decodeVarint();
073 case 'T':
074 // decode boolean true
075 return 1;
076 case 'F':
077 // decode boolean false
078 return 0;
079 default:
080 Log.e(TAG, "Unknown response parm " + kind + " '" + (char) kind + "'");
081 throw new IOException();
082 }
083 // return null;
084
085 }
086
087 protected String decodeString() throws IOException
088 {
089 int length = decodeVaruint();
090 if (length > 0) {
091 byte[] bytes = new byte[length];
092 ioTransport.read(length, bytes, true);
093 String s = new String(bytes);
094 return s;
095 }
096 return "";
097 }
098
099 protected byte[] decodeBinary() throws IOException
100 {
101 int length = decodeVaruint();
102 if (length > 0) {
103 byte[] bytes = new byte[length];
104 ioTransport.read(length, bytes, true);
105 return bytes;
106 }
107 return new byte[0];
108 }
109
110 protected int decodeVarint() throws IOException
111 {
112
113 int number = decodeVaruint();
114 if ((1 & number) != 0) {
115 // negative
116 number = (number ^ (~0)) >> 1;
117 }
118 else {
119 // positive
120 number = (number >> 1);
121 }
122
123 return number;
124 }
125
126 protected int decodeVaruint() throws IOException
127 {
128 return (decodeOneVaruint(ioTransport));
129 }
130
131 protected static int decodeOneVaruint(Transport i) throws IOException
132 {
133 Log.d(TAG,"Going to decode Varuint");
134 int shift = 0;
135 int result = 0;
136 while (true) {
137 int value = i.read() & 0xFF;
138 result = result | ((value & 0x7f) << shift);
139 shift = shift + 7;
140 Log.d(TAG, "processing byte " + value + ", result=" + result + ",shift=" + shift);
141 if ((value & 0x80) == 0)
142 break;
143 }
144 return result;
145 }
146
147 protected int decodeObjectid() throws IOException
148 {
149 return (decodeVaruint());
150 }
151
152 protected boolean decodeBoolean() throws IOException
153 {
154 int v = ioTransport.read();
155 if (v == 'T') {
156 return true;
157 }
158 else if (v == 'F') {
159 return false;
160 }
161 else {
162 Log.e(TAG, "Invalid boolean value " + v + "'" + (char) v + "'");
163 throw new IOException();
164 }
165 }
166
167 protected ResponseListElement decodeList() throws IOException
168 {
169 ResponseListElement rlist = new ResponseListElement(ioTransport);
170 return rlist;
171 }
172 }