Android彩信解码函数,需要从输入流中解析字段。

今天又看了一下pduparse中几个解析函数,在这里做个总结。

大概可以分为3类

一、解析字节

1.extractByteValue

protected static int extractByteValue(ByteArrayInputStream pduDataStream) { assert(null != pduDataStream); int temp = pduDataStream.read(); assert(-1 != temp); return temp & 0xFF; }

这个啥也没的说,就是把一个byte转换成一个整型返回。

二、解析整型

1.parseShortInteger

基本同时,只是返回的有效位不一样,取这个byte的前7位,因此范围0-127

就 return temp & 0x7F ; 这句不一样。

2.parseUnsignedInt

解析一个无符号整型。

assert(null != pduDataStream); int result = 0; int temp = pduDataStream.read(); if (temp == -1) { return temp; } while((temp & 0x80) != 0) { result = result << 7; result |= temp & 0x7F; temp = pduDataStream.read(); if (temp == -1) { return temp; } } result = result << 7; result |= temp & 0x7F; return result;

首先判断第一个数字最高位,如果是0,取这个字节的低7位返回。

如果是1,就继续读下一位,直到读到高位为0的byte为止,最后把各个byte的低7位串成一个整型返回。

相当于每一个byte只有7为有效。

由于一个int最多32为,所以用这种方式表示的字节流不会超过5(32/7)个octec(8位字节).

3、 parseLongInteger

int temp = pduDataStream.read(); assert(-1 != temp); int count = temp & 0xFF; if (count > LONG_INTEGER_LENGTH_MAX) { throw new RuntimeException("Octet count greater than 8 and I can't represent that!"); } long result = 0; for (int i = 0 ; i < count ; i++) { temp = pduDataStream.read(); assert(-1 != temp); result <<= 8; result += (temp & 0xFF); } return result;

这个解析一个长整型

先读取一个count,表示该整型由多少octet组成,然后读响应字节,组成一个长整型。

由于长整型最多8个字节,所以这个count不会大于8.

再者,由于有了长度,它不需要用高位来标示结束符,因此每一个字节8位都有效。

4.parseIntegerValue

assert(null != pduDataStream); pduDataStream.mark(1); int temp = pduDataStream.read(); assert(-1 != temp); pduDataStream.reset(); if (temp > SHORT_INTEGER_MAX) { return parseShortInteger(pduDataStream); } else { return parseLongInteger(pduDataStream); }

解析整型。

先读取第一个字节,如果大于SHORT_INTEGER_MAX(127),即高位为1,则认为是一个short int,直接返回低7位。

否则就解析长int,先读取长度,再解析该长度的自己组成一个整型。

5.parseValueLength

assert(null != pduDataStream); int temp = pduDataStream.read(); assert(-1 != temp); int first = temp & 0xFF; if (first <= SHORT_LENGTH_MAX) { return first; } else if (first == LENGTH_QUOTE) { return parseUnsignedInt(pduDataStream); }

读取第一个的8位字节,如果小于SHORT_LENGTH_MAX(30),返回。

如果等于LENGTH_QUOTE(31),按照parseUnsignedInt方法解析。

三、解析字符串

1.parseWapString

pduDataStream.mark(1); // Check first char int temp = pduDataStream.read(); assert(-1 != temp); if ((TYPE_QUOTED_STRING == stringType) && (QUOTED_STRING_FLAG == temp)) { // Mark again if QUOTED_STRING_FLAG and ignore it pduDataStream.mark(1); } else if ((TYPE_TEXT_STRING == stringType) && (QUOTE == temp)) { // Mark again if QUOTE and ignore it pduDataStream.mark(1); } else { // Otherwise go back to origin pduDataStream.reset(); } return getWapString(pduDataStream, stringType);

首先解析第一个字节,如果字符串类型是TYPE_QUOTED_STRING,并且解析出来的第一个字节标识也是QUOTED_STRING_FLAG(34),就跳过这个标示,准备读下面数据。

如果出入类型是TYPE_TEXT_STRING,并且解析出来的第一个字节也是QUOTE(127),同样也是跳过这个标识,准备读下面数据。

否则,就是没有类型标示的字符串,那么就回退数据流。按照一个字符串来解析getWapString。

2.getWapString

ByteArrayOutputStream out = new ByteArrayOutputStream(); int temp = pduDataStream.read(); assert(-1 != temp); while((-1 != temp) && ('/0' != temp)) { // check each of the character if (stringType == TYPE_TOKEN_STRING) { if (isTokenCharacter(temp)) { out.write(temp); } } else { if (isText(temp)) { out.write(temp); } } temp = pduDataStream.read(); assert(-1 != temp); } if (out.size() > 0) { return out.toByteArray(); } return null;

这个没什么好说的,就是读取字节到结束,或者 /0结束为止。

3.parseEncodedStringValue

pduDataStream.mark(1); EncodedStringValue returnValue = null; int charset = 0; int temp = pduDataStream.read(); assert(-1 != temp); int first = temp & 0xFF; pduDataStream.reset(); if (first < TEXT_MIN) { parseValueLength(pduDataStream); charset = parseShortInteger(pduDataStream); //get the "Charset" } byte[] textString = parseWapString(pduDataStream, TYPE_TEXT_STRING); try { if (0 != charset) { returnValue = new EncodedStringValue(charset, textString); } else { returnValue = new EncodedStringValue(textString); } } catch(Exception e) { return null; } return returnValue;

首先读取第一个字节。

如果小于TEXT_MIN,就是说明这个字节是一个标示符,下面有编码方式。跳过这个字节,读取编码方式,然后调用parseWapString再解析下面的字符串数据。

否则,就是说明这个字符串没有编码方式,单纯一个字符串。就从头将其作为一个字符串解析。

补充,至于这些关键字符SHORT_LENGTH_MAX、LENGTH_QUOTE之类的,是wsp协议规定的,见wap-230-wsp-20010705-a.pdf,在我上传至资源中。

更多相关文章

  1. Android 加密解密字符串
  2. android 字符串转json
  3. Android中的strings文件中字符串的拼接
  4. Android定义字符串数组资源并在程序中使用
  5. android字符串资源字符format
  6. 〖Android〗Android App项目资源字符串检查(检查是否缺少对应的翻
  7. 2019AndroidBAT.字节跳动74道高级面试第二篇
  8. android 字节数据的转换与处理
  9. android string.xml中格式资源字符串

随机推荐

  1. JQuery 1.4.4和Datatable 1.7不工作
  2. CSS3转换导致非常奇怪的window.scrollY行
  3. 奇怪的字符显示在XML> ASP.NET> Javascri
  4. S1-Javascript基础知识一[Javascript]
  5. 如何在url中将特殊字符作为查询字符串传
  6. 删除Google Analytics Cookie和欧盟电子
  7. js中匿名函数的写法
  8. JavaScript中的类型转换(一)
  9. mongojs的异步调用找到函数
  10. JavaScript基础知识梳理,你能回答几道题?