package com.fcar.frameworks.utils; import com.fcar.frameworks.core.GlobalVar; import com.fcar.frameworks.utils.io.EncryptedInputStream; import com.fcar.frameworks.utils.xjson.XJsonToXmlNodeParser; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.Stack; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public class XmlFile { private XmlNode mRoot; //需要包装一层用于移植方便 // 因为需要记录文件名,因此这里屏蔽了这个方法,如果有问题,实在需要再开放 /** * 构造函数,输入为文件输入流 */ private XmlFile(InputStream is) { mRoot = new Handler().parse(is); } /** * 构造函数,输入为文件名称 * * @param fileName 文件名 */ public XmlFile(String fileName) { long time = System.currentTimeMillis(); int whichXmlParserToUse = GlobalVar.getWhichXmlParserToUse(); if (whichXmlParserToUse == 0) mRoot = new Handler().parse(fileName); else { File f = new File(fileName); XJsonToXmlNodeParser parser = null; InputStream inputStream = null; try { // 先尝试从外部数据库zip中读取文件 inputStream = ZipFileManager.instance().getFileInputStream(fileName); if (inputStream == null) { if (f.exists()) inputStream = new FileInputStream(f); else inputStream = GlobalVar.getContext().getAssets().open(fileName); } parser = new XJsonToXmlNodeParser(new EncryptedInputStream(new BufferedInputStream(inputStream))); // 使用BufferedInputStream提升IO速度 mRoot = parser.parse(); } catch (IOException e) { mRoot = null; return; } finally { if (parser != null) parser.close(); if (inputStream != null) try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } // inputStream在parser.close中没有关闭 } } time = System.currentTimeMillis() - time; L.i("XmlFile", "It takes " + time + " milliseconds to parse " + fileName); } /** * 获取根节点 * * @return 该Xml文件的根节点 */ public XmlNode getRoot() { return mRoot; } } class Handler extends DefaultHandler { private final Boolean DBG = true; private XmlNode root; private Stack<XmlNode> tmp; private String tmpStr; /** * 解析Xml文件,输入为文件名称 * * @param fileName 文件名,如果未找到,则尝试从Assets中寻找 * @return Xml根节点 */ public XmlNode parse(String fileName) { if (fileName == null) return null; root = null; try { L.i("XmlFile", "open file --> " + fileName); File f = new File(fileName); if (f.exists()) { return parse(new FileInputStream(f)); } return parse(GlobalVar.getContext().getAssets().open(fileName)); } catch (FileNotFoundException e) { L.e("Error", "File not found --> " + fileName); //e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 处理文件,输入为文件流 * * @param is 输入数据流 * @return Xml数据流的根节点 */ public XmlNode parse(InputStream is) { try { SAXParser p = SAXParserFactory.newInstance().newSAXParser(); p.parse(is, this); if (tmp.size() != 0) { L.e("com.fcar", "error tmp != 0"); return null; } tmp = null; tmpStr = null; return root; } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); } finally { if (is != null) try { is.close(); } catch (IOException e) { e.printStackTrace(); } } return null; } @Override public void startDocument() throws SAXException { tmp = new Stack<XmlNode>(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { XmlNode n; //L.i("com.fcar.start", uri + " " + localName + " " + qName); if (tmp.size() > 0) { n = new XmlNode(qName, tmp.peek(), attributes); n.getParent().addChild(n); tmp.push(n); } else { n = new XmlNode(qName, null, attributes); root = n; tmp.push(n); } tmpStr = ""; } @Override public void characters(char[] ch, int start, int length) throws SAXException { //有特殊字符,所以更改成这样 tmpStr += new String(ch, start, length).trim(); //tmp.peek().setText(new String(ch, start,length).trim()); //L.i("com.fcar.char", tmp.peek().getText()); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { //L.i("com.fcar.end", uri + " " + localName + " " + qName); tmp.peek().setText(tmpStr); tmpStr = ""; //检查语法 可以优化掉 if (DBG) { XmlNode p = tmp.peek(); if (!p.getName().equals(qName)) L.e("com.fcar.end", p.getName() + " != " + qName); } // tmp.pop(); }}
--------------------------------------
package com.fcar.frameworks.utils; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import org.xml.sax.Attributes; public class XmlNode implements Serializable { // private static final long serialVersionUID = 352135146221453293L; private XmlNode mParent; private XmlNodeList mChildren; String mName; String mText; HashMap<String, String> mAttrs; public XmlNode(String name, XmlNode parent, Attributes attrs) { mParent = parent; mChildren = new XmlNodeList(); mAttrs = new HashMap<String, String>(); for (int i = 0; i < attrs.getLength(); i++) { mAttrs.put(attrs.getQName(i), attrs.getValue(i)); } mName = name; } public XmlNode(String name, XmlNode parent) { mParent = parent; mChildren = new XmlNodeList(); mAttrs = new HashMap<String, String>(); mName = name; } public XmlNode() { mParent = null; mChildren = new XmlNodeList(); mAttrs = new HashMap<String, String>(); mName = "NoName"; } public void addChild(XmlNode child) { mChildren.add(child); } //设置文本 public void setText(String text) { mText = text; } //获取文本 public String getText() { return mText; } //获取节点名称 public String getName() { return mName; } //获取父节点 public XmlNode getParent() { return mParent; } //获取指定名称的第一个子结点 public XmlNode getChild(String name) { return mChildren.find(name); } //获取所有的子节点 public XmlNodeList getChildren() { return mChildren; } public XmlNodeList getChildren(String name) { XmlNodeList list = new XmlNodeList(); for (int i = 0; i < mChildren.getLength(); i++) { XmlNode n = mChildren.item(i); if (name.equals(n.getName())) { list.add(n); } } return list; } public boolean hasAttr(String attrName) { return mAttrs.containsKey(attrName); } public boolean hasChild(String childName) { return getChild(childName) != null; } public boolean hasChildren() { return mChildren.getList().isEmpty(); } //获取制定名称的属性 public String getAttr(String attrName) { return mAttrs.get(attrName); } // public Map<String, String> getAttrs() { // return mAttrs; // } //设置属性值 public void setAttr(String attrName, String val) { mAttrs.put(attrName, val); } public void setParent(XmlNode parent) { mParent = parent; } public void setName(String name) { mName = name; } /** * 获取该节点所在的Xml树的根节点 * @return 该节点所在的Xml树的根节点 */ public XmlNode getRoot() { XmlNode root = this; while (root.getParent() != null) root = root.getParent(); return root; } /** * (在本节点所在的xml树内)传入一个Xml节点路径,传出该路径所描述的节点。 * @param path 描述一个节点的字符串。该字符串是一串以斜杠(/)分隔开的xml节点名。不需要传入根节点名。如果要使用根节点,则传入空字符串或者"/"。 * 例如:根节点(AUTO)--->子节点1(NODE1)----> 子节点2(NODE2)。其所对应的XmlPath字符串为"/NODE1/NODE2"或者"NODE1/NODE2" * @return 指定Xml节点 */ public XmlNode getXmlNodeByPath(String path) { XmlNode root = getRoot(); String[] paths = path.split("/"); if (paths.length == 0) return root; if (paths[0].isEmpty()) { for (int i = 1; i < paths.length; ++i) { root = root.getChild(paths[i]); } } else { for (int i = 0; i < paths.length; ++i) { root = root.getChild(paths[i]); } } return root; } public String getXmlPath() { StringBuilder sb = new StringBuilder(); getXmlPath(sb); return sb.toString(); } private void getXmlPath(StringBuilder sb) { XmlNode parent = getParent(); if (parent != null) parent.getXmlPath(sb); sb.append('/').append(getName()); } }---------------------------------------------package com.fcar.frameworks.utils; import java.io.Serializable; import java.util.ArrayList; import java.util.List; public class XmlNodeList implements Serializable { // private static final long serialVersionUID = 8516515565121423132L; private List<XmlNode> mList; public XmlNodeList() { mList = new ArrayList<XmlNode>(); } public List<XmlNode> getList(){ return mList; } public XmlNode find(String name) { for(int i =0; i<mList.size(); i++) { if(mList.get(i).getName().equals(name)) return item(i); } return null; } public void add(XmlNode n) { mList.add(n); } //获取并列节点个数 public int getLength() { return mList.size(); } //获取其中的一个节点 public XmlNode item(int index) { return mList.get(index); } }----------------------------------------package com.fcar.frameworks.utils.xjson; import com.fcar.frameworks.core.GlobalVar; import com.fcar.frameworks.utils.io.DoubleBuffer; import com.fcar.frameworks.utils.WordBuilder; import com.fcar.frameworks.utils.XmlNode; import java.io.*; import java.util.Stack; /** * 将XJson文件解析成{@link XmlNode} 对象的工具类<br/> * Created by carl on 2016/4/7. */ public class XJsonToXmlNodeParser implements Closeable { private static final String TAG = "XJsonParser"; private static final int EXPECT_TYPE_STRING = 1; private static final int EXPECT_TYPE_SQUARE_BRACKET_START = 2; private static final int EXPECT_TYPE_SQUARE_BRACKET_END = 4; private static final int EXPECT_TYPE_COLON = 8; private static final int EXPECT_TYPE_CURLY_BRACE_START = 16; private static final int EXPECT_TYPE_CURLY_BRACE_END = 32; private static final int EXPECT_TYPE_COMMA = 64; private static final int EXPECT_TYPE_NAME_STRING = 128; private static final int EXPECT_TYPE_TEXT_STRING = 256; private static final int EXPECT_TYPE_COLON_BEFORE_TEXT = 512; private static final char START_CURLY_BRACE = '{'; private static final char END_CURLY_BRACE = '}'; private static final char START_SQUARE_BRACKET = '['; private static final char END_SQUARE_BRACKET = ']'; private static final char COLON = ':'; private static final char BACK_SLASH = '\\'; private static final char QUOTATION = '"'; private static final char COMMA = ','; private DoubleBuffer doubleBuffer; /** * 存储当前正在处理的对象的栈 */ private Stack<XmlNode> stack; // 以下变量用于类内建输入流,解析完毕时自动关闭输入流 private InputStream inputStream; public XJsonToXmlNodeParser(InputStream is) throws IOException { this.stack = new Stack<>(); this.doubleBuffer = new DoubleBuffer(is); } /** * 本方法不能读取被加密的文件 * @param fileName # * @throws IOException # */ public XJsonToXmlNodeParser(String fileName) throws IOException { File f = new File(fileName); if (f.exists()) inputStream = new FileInputStream(f); else inputStream = GlobalVar.getContext().getAssets().open(fileName); this.stack = new Stack<>(); this.doubleBuffer = new DoubleBuffer(new BufferedInputStream(inputStream)); } @Override public void close() { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } inputStream = null; } } /** * 解析XJson字符流,解析直到一个对象解析完或者字符流结束。换句话说处理一个花括号对。 * @return 解析出来的对应的XmlNode * @throws IOException # */ public XmlNode parse() throws IOException { if (this.doubleBuffer == null) return null; int ch; int expectedType = EXPECT_TYPE_CURLY_BRACE_START; while ((ch = doubleBuffer.read()) != -1) { if (Character.isWhitespace(ch)) continue; if (ch == START_CURLY_BRACE) { if ((expectedType & EXPECT_TYPE_CURLY_BRACE_START) != 0) { onStartObject(); expectedType = EXPECT_TYPE_NAME_STRING; } else { throw new XJsonSyntaxException(); } } else if (ch == END_CURLY_BRACE) { if ((expectedType & EXPECT_TYPE_TEXT_STRING) != 0) { // 没有读取到可选的text值就遇到了反花括号 stack.peek().setText(""); onEndObject(); return stack.pop(); } else if ((expectedType & EXPECT_TYPE_CURLY_BRACE_END) != 0) { onEndObject(); return stack.pop(); } else { throw new XJsonSyntaxException(); } } else if (ch == START_SQUARE_BRACKET) { if ((expectedType & EXPECT_TYPE_SQUARE_BRACKET_START) != 0) { onStartArray(); expectedType = EXPECT_TYPE_CURLY_BRACE_END; } else { throw new XJsonSyntaxException(); } } else if (ch == COLON) { if ((expectedType & EXPECT_TYPE_COLON) != 0) { onMeetColon(); expectedType = EXPECT_TYPE_STRING; } else if ((expectedType & EXPECT_TYPE_COLON_BEFORE_TEXT) != 0) { onMeetColonBeforeText(); expectedType = EXPECT_TYPE_TEXT_STRING; } else { throw new XJsonSyntaxException(); } } else if (ch == COMMA) { if ((expectedType & EXPECT_TYPE_TEXT_STRING) != 0) { // 没有读取到可选的text值就遇到了逗号 stack.peek().setText(""); expectedType = EXPECT_TYPE_SQUARE_BRACKET_START | EXPECT_TYPE_STRING; } else if ((expectedType & EXPECT_TYPE_COMMA) != 0) { expectedType = EXPECT_TYPE_SQUARE_BRACKET_START | EXPECT_TYPE_STRING; } else { throw new XJsonSyntaxException(); } } else if (ch == QUOTATION) { // 是一般属性名或者属性值 if ((expectedType & EXPECT_TYPE_STRING) != 0) { onStartString(); if (isKey) expectedType = EXPECT_TYPE_COMMA | EXPECT_TYPE_CURLY_BRACE_END; // 属性值已经读取完毕 else expectedType = EXPECT_TYPE_COLON; // 属性名已经读取完毕 } else if ((expectedType & EXPECT_TYPE_NAME_STRING) != 0) { // 标签名 onStartNameString(); expectedType = EXPECT_TYPE_COLON_BEFORE_TEXT; } else if ((expectedType & EXPECT_TYPE_TEXT_STRING) != 0) { // 标签内部文本值 onStartTextString(); expectedType = EXPECT_TYPE_COMMA | EXPECT_TYPE_CURLY_BRACE_END; } else { throw new XJsonSyntaxException(); } } else { // 其它非空白字符 throw new XJsonSyntaxException(); } } throw new XJsonStreamEndsUnexpectlyException(); // 理论上在读到数据流尾之前解析出XJson对象 } /** * 获取指定字符转意以后的字符,目前并没有什么处理,转义符后面是什么字符就转意什么出来 * @param ch 指定字符 * @return 转意以后的字符 */ public char getEscapeCharacter(int ch) { return (char) ch; } protected void onStartObject() { stack.push(new XmlNode()); } protected void onEndObject() { } protected void onStartArray() throws IOException { XmlNode parent = stack.peek(); do { XmlNode child = parse(); parent.addChild(child); child.setParent(parent); int ch; while ((ch = doubleBuffer.read()) != -1) { if (Character.isWhitespace(ch)) continue; if (ch == COMMA) break; if (ch == END_SQUARE_BRACKET) { return; } } } while (true); } @SuppressWarnings("unused") protected void onEndArray() { } protected void onMeetColon() { } protected void onMeetColonBeforeText() { } private WordBuilder wb = new WordBuilder(); private boolean isKey = true; // true表示当前正在扫描的字符串是属性,否则表示值 private String key = null; protected void onStartString() throws IOException { wb.clear(); int ch; while ((ch = doubleBuffer.read()) != -1) { if (ch == BACK_SLASH) { ch = getEscapeCharacter(doubleBuffer.read()); wb.append(ch); } else if (ch == QUOTATION) { // 在这里遇到引号("),说明遇到了字符串终结的引号 break; } else { wb.append(ch); } } String string = wb.toString(); if (isKey) { key = string; isKey = false; } else { stack.peek().setAttr(key, string); isKey = true; } } protected void onStartTextString() throws IOException { wb.clear(); int ch; while ((ch = doubleBuffer.read()) != -1) { if (ch == BACK_SLASH) { ch = getEscapeCharacter(doubleBuffer.read()); wb.append(ch); } else if (ch == QUOTATION) { // 在这里遇到引号(")说明,遇到了字符串终结的引号 break; } else { wb.append(ch); } } String string = wb.toString(); stack.peek().setText(string); } protected void onStartNameString() throws IOException { wb.clear(); int ch; while ((ch = doubleBuffer.read()) != -1) { if (ch == BACK_SLASH) { ch = getEscapeCharacter(doubleBuffer.read()); wb.append(ch); } else if (ch == QUOTATION) { // 在这里遇到引号(")说明,遇到了字符串终结的引号 break; } else { wb.append(ch); } } String string = wb.toString(); stack.peek().setName(string); } } ---------------------------------------------------------------package com.fcar.frameworks.utils.io; import com.fcar.frameworks.utils.ByteEncryptor; import java.io.IOException; import java.io.InputStream; /** * Created by carl on 2016/4/12. */ public class EncryptedInputStream extends InputStream implements EncryptionInterface { private InputStream inputStream; /** * 正文读到哪个字节了 */ private int count = 0; private int version; public EncryptedInputStream(InputStream is) throws IOException { inputStream = is; readVersion(); } public void readVersion() throws IOException { byte[] buf = new byte[EncryptionInterface.HEADER_SIZE]; if (inputStream.read(buf) != buf.length) { throw new EncryptedFileFormatException(); } if (buf[0] != buf[1]) throw new EncryptedFileFormatException(); version = (buf[0] & 0xff) - 0x54; switch (version) { case 1: // 后面什么都不用管了 break; default: throw new EncryptedFileFormatVersionUnsupported(); } } @Override public int read() throws IOException { switch (version) { case 1: return readVersion1(); default: // 不可能出现了 } // 不可能走到这里 return -1; } public int readVersion1() throws IOException { int aByte = inputStream.read(); if (aByte == -1) return -1; aByte = ByteEncryptor.decrypt(aByte, count++); return aByte & 0xff; } @Override public int available() throws IOException { return inputStream.available(); } }-----------------------------------------------------------------------------
package com.fcar.frameworks.utils; /** * 该类要与发布工具的加密算法一致 * Created by carl on 2016/4/12. */ public class ByteEncryptor { private static final int[] MAGIC_NUMBER = { 0x376fac2, 0x339677BE // 都要用偶数,不改变原数的奇偶性,通过原数据的奇偶性选择Magic Number }; public static int hashKey(int key) { // return key * 99839 + 26573 & 0xfffffffe; return key & 0xfffffffe; } public static int encrypt(int toEncrypt, int key) { key = hashKey(key); // key的最低位丢弃,避免改变原数的奇偶性,通过原数据的奇偶性选择Magic Number return (toEncrypt ^ key) + MAGIC_NUMBER[(toEncrypt & 0x7fffffff) % MAGIC_NUMBER.length]; } public static int decrypt(int toDecrypt, int key) { key = hashKey(key); // key的最低位丢弃,避免改变原数的奇偶性,通过原数据的奇偶性选择Magic Number return toDecrypt - MAGIC_NUMBER[(toDecrypt & 0x7fffffff) % MAGIC_NUMBER.length] ^ key; } }package com.fcar.frameworks.utils; import com.fcar.frameworks.core.GlobalVar; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /** * 读取Zip文件内容的辅助类,目前仅用于读取数据库<br/> * Created by carl on 2016/4/20. */ public class ZipFileManager { private static ZipFileManager instance; static { L.e("ZipFile: " + GlobalVar.getCurrDatabase()); instance = new ZipFileManager(new File(GlobalVar.getCurrDatabase())); } public static ZipFileManager instance() { return instance; } private ZipFile zipFile; private ZipFileManager(File zip) { try { zipFile = new ZipFile(zip); } catch (IOException e) { e.printStackTrace(); zipFile = null; } } public InputStream getFileInputStream(String file) { if (zipFile == null) return null; ZipEntry entry = zipFile.getEntry(file); if (entry == null) return null; try { return zipFile.getInputStream(entry); } catch (IOException e) { return null; } } public void close() throws IOException { if (zipFile != null) zipFile.close(); } }----------------------------------------------------package com.fcar.frameworks.utils; /** * Created by carl on 2016/4/7. */ public class WordBuilder { private static final int DEFAULT_SIZE = 4096; private char[] buffer; private int index; public WordBuilder(int bufferSize) { buffer = new char[bufferSize]; index = 0; } public WordBuilder() { this(DEFAULT_SIZE); } public WordBuilder append(char ch) { if (fullFilled()) { char[] newBuf = new char[buffer.length * 2]; System.arraycopy(buffer, 0, newBuf, 0, buffer.length); buffer = newBuf; } buffer[index++] = ch; return this; } public boolean fullFilled() { return index == buffer.length; } public WordBuilder append(int ch) { return append((char) ch); } public void clear() { index = 0; } public String toString() { return new String(buffer, 0, index); } } ----------------------------------------------------------------package com.fcar.frameworks.utils; import java.math.BigDecimal; import java.util.Random; public class Hex { private Hex(){} public static boolean isHex(char c) { return (c>='0' && c <= '9') || (c>='a' && c <= 'f')|| (c>='A' && c <= 'F'); } public static byte parseChar(char c) { if(c>='0' && c <= '9') return (byte)(c - '0'); if(c>='a' && c <= 'f') return (byte)(c-'a'+10); if(c>='A' && c <= 'F') return (byte)(c-'A'+10); return 0; } public static int auto(String s){ if(s.length() == 1) s = "0" + s; byte[] buf = Hex.parse(s); switch (buf.length){ case 1: return buf[0]&0xff; case 2: return toShortB(buf)&0xffff; case 3: case 4: return toIntB(buf); default: break; } return 0; } //转换字符串到byte //例如 parseByte("5A") == (byte)0x5A public static byte parseByte(String s) { if(s == null || s.isEmpty()) return 0; if(s.length() == 1) return parseChar(s.charAt(0)); return (byte)(parseChar(s.charAt(0)) * 0x10 + parseChar(s.charAt(1))); } public static BigDecimal paresBigdec(String s){ BigDecimal b = new BigDecimal(0); if(s == null) return b; if(s.length() <= 15){ L.e("Hex", "只转换长度大于15的字符串"); return b; } byte[] bs = Hex.parse(s); for(byte bb: bs){ b = b.multiply(new BigDecimal(0x100)); b = b.add(new BigDecimal((int)bb&0xff)); } return b; } public static long parseLong(String s){ if(s == null) return 0; if(s.length() <= 8){ L.e("Hex", "只转换长度大于8的字符串"); return 0; } byte[] bs = Hex.parse(s); long result = 0; for(byte b: bs){ result = (result << 8) + b; } return result; } public static int parseInt(String s) { if(s == null) return 0; if(s.length() != 8) { L.e("Hex", "只转换长度为8的字符串"); return 0; } byte[] bs = Hex.parse(s); return (bs[0]&0xff)*0x1000000+(bs[1]&0xff)*0x10000+(bs[2]&0xff)*0x100+(bs[3]&0xff); } //转换字符串到byte数组 //例如 parse("5A 5A") == { 0x5A, 0x5A}; // parse("5A,5A") == {0x5A, 0x5A}; // parse("0x5a,0x5a") == {0x5A, 0x5A}; public static byte[] parse(String s) { byte[] res = new byte[s.length()/2]; int c = 0; for(int i =0; i<s.length()-1; i++) { if(isHex(s.charAt(i)) && isHex(s.charAt(i+1))) { res[c++] = parseByte(s.substring(i)); i++; } else if ((s.charAt(i) == '?') && (s.charAt(i+1) == '?')) { res[c++] = (byte) new Random().nextInt(); i++; } } byte[] res2 = new byte[c]; System.arraycopy(res, 0, res2, 0, c); return res2; } //转换byte数组到字符串 //例如: byte[] b = {(byte)0xa5, (byte)0xa5}; // toString(b).equels == "A5 A5 "; //@SuppressLint("DefaultLocale") public static String toString(byte[] b) { return toString(b, 0, b.length); } //@SuppressLint("DefaultLocale") public static String toString(byte[] b, int len) { return toString(b, 0, len); } //转换byte数组到字符串 //与上面函数不同的是指定了转换的个数 //@SuppressLint("DefaultLocale") public static String toString(byte[] b, int from, int len) { String res = ""; for(int i = from; i<from+len; i++) { String hex = Integer.toHexString(b[i] & 0xFF); if(hex.length() == 1) hex = '0' + hex; res += hex.toUpperCase(); res += " "; } return res; } //转换int 到byte数组 len=4 //大端 public static byte[] fromIntB(int val) { byte[] b = new byte[4]; b[3] = (byte) (val & 0xff); b[2] = (byte) ((val>>8) & 0xff); b[1] = (byte) ((val>>16) & 0xff); b[0] = (byte) ((val>>24) & 0xff); return b; } //转换int 到byte数组 len=4 //小端 public static byte[] fromIntL(int val) { byte[] b = new byte[4]; b[0] = (byte) (val & 0xff); b[1] = (byte) ((val>>8) & 0xff); b[2] = (byte) ((val>>16) & 0xff); b[3] = (byte) ((val>>24) & 0xff); return b; } //转换short 到byte数组 2字节 大端 public static byte[] fromShortB(short val) { byte[] b = new byte[2]; b[1] = (byte) (val & 0xff); b[0] = (byte) ((val>>8) & 0xff); return b; } //转换short 到byte数组, 2字节 小端 public static byte[] fromShortL(short val) { byte[] b = new byte[2]; b[0] = (byte) (val & 0xff); b[1] = (byte) ((val>>8) & 0xff); return b; } //转换4字节数组到int, 大端, 数组必须大于等于长度4, 函数不做检查 public static int toIntB(byte[] bs) { int r0=0,r1, r2, r3; //if(bs == null || bs.length < 3) return -1; if(bs.length == 3) { r3 = ((int) bs[2]) & 0xff; r2 = ((int) bs[1]) & 0xff; r1 = ((int) bs[0]) & 0xff; } else { r3 = ((int) bs[3]) & 0xff; r2 = ((int) bs[2]) & 0xff; r1 = ((int) bs[1]) & 0xff; r0 = ((int) bs[0]) & 0xff; } return (r0<<24) | (r1<<16) | (r2 <<8) | r3; } //转换4字节到int, 小端, 数组必须大于等于长度4, 函数不做检查 public static int toIntL(byte[] bs) { int r0, r1 , r2, r3 = 0; //if(bs == null || bs.length < 3) return -1; if(bs.length == 3) { r2 = ((int) bs[2]) & 0xff; r1 = ((int) bs[1]) & 0xff; r0 = ((int) bs[0]) & 0xff; } else { r3 = ((int) bs[3]) & 0xff; r2 = ((int) bs[2]) & 0xff; r1 = ((int) bs[1]) & 0xff; r0 = ((int) bs[0]) & 0xff; } return (r3<<24) | (r2<<16) | (r1 <<8) | r0; } public static short toShortB(byte[] bs) { int r1 = ((int)bs[1]) & 0xff; int r0 = ((int)bs[0]) & 0xff; return (short)(r0<<8 | r1); } public static short toShortL(byte[] bs) { int r1 = ((int)bs[1]) & 0xff; int r0 = ((int)bs[0]) & 0xff; return (short)(r1<<8 | r0); } //合并四个数组 public static byte[] merge(byte[] b1, byte[] b2, byte[] b3, byte[] b4) { byte[] res = new byte[b1.length + b2.length + b3.length + b4.length]; System.arraycopy(b1, 0, res, 0, b1.length); System.arraycopy(b2, 0, res, b1.length, b2.length); System.arraycopy(b3, 0, res, b1.length+b2.length, b3.length); System.arraycopy(b4, 0, res, b1.length+b2.length+b3.length, b4.length); return res; } //合并三个数组 public static byte[] merge(byte[] b1, byte[] b2, byte[] b3) { byte[] res = new byte[b1.length + b2.length + b3.length]; System.arraycopy(b1, 0, res, 0, b1.length); System.arraycopy(b2, 0, res, b1.length, b2.length); System.arraycopy(b3, 0, res, b1.length+b2.length, b3.length); return res; } //合并两个数组 public static byte[] merge(byte[] b1, byte[] b2) { byte[] res = new byte[b1.length + b2.length]; System.arraycopy(b1, 0, res, 0, b1.length); System.arraycopy(b2, 0, res, b1.length, b2.length); return res; } //复制source数组的内容到 dest public static int copy(byte[] dest, byte[] source) { return copy(dest, 0, source, 0, source.length); } //从spos位置复制source数组count长度的数据到dest位置destpos public static int copy(byte[] dest, int destpos, byte[] source, int spos, int count) { if(dest.length < destpos + count) count = dest.length - destpos; if(source.length < spos + count) count = source.length - spos; System.arraycopy(source, spos, dest, destpos, count); return count; } //一字节和 GetCrcOneAdd //一字节和取反 GetCreOneAddUn //一字节和取补 GetCrcOneAddRe //一字节异或 GetCrcOneXor //一字节CRC校验 GetCrcOneCrc //一字节除倒数第二位(也是校验和,少算一位即可) GetCrcOneDiv //benz 5bps 两字节校验和,低字节在前,高字节在后 GetCrcOneAdd2 //卡特专用 pro_seekcat //gaz_0d倒数第三字节 校验 一字节取补 倒数第二字节为0x0d, gaz_0d //国产kwp协议, 2字节校验和,高字节在前 GetCrcOneAdd2 private static byte toByte(int a) { return (byte)(a & 0xff);} private static int toInt(byte a) { return (int)a & 0xff; } public static byte[] getCrcOneAdd(byte[] data, int from, int len) { int res = 0; for(int i =from; i<from+len; i++) res += toInt(data[i]); return fromIntL(res); } public static byte getCrcOneAddUn(byte[] data, int from, int len) { int res = toInt(getCrcOneAdd(data, from, len)[0]); res = ~res; return toByte(res); } public static byte getCrcOneAddRe(byte[] data, int from, int len) { return toByte(getCrcOneAddUn(data, from, len) + 1); } public static byte getCrcOneXor(byte[] data, int from, int len) { int res = 0; for(int i=from; i<from+len; i++) res = res ^ data[i]; return toByte(res); } public static byte getCrcOneCrc(byte[] data, int from, int len) { //L.i("getcrc "+ Hex.toString(data, from, len)); byte res = 0x59; switch (len + 1) { case 6: res = 0x10; break; case 7: res = (byte)0xf6; break; case 8: res = 0x0a; break; case 9: res = (byte)0xe9; break; case 10:res = 0x7c; break; case 11:res = (byte)0xfe; break; case 12:res = (byte)0xe2; break; } int j = toInt(data[from]); int n; for(int i =1+from; i<from+len; i++) { for(int k=0; k<8; k++) { j = j << 1; n = (data[i]>>(7-k)) & 0x01; j += n; if(j>255) j = j ^ 285; } } for(int k=0; k<8; k++) { j = j << 1; n = (res>>(7-k)) & 0x01; j += n; if(j>255) j = j ^ 285; } //L.i("crc result:", Integer.toHexString(j)); return toByte(j); } // static public byte getCrc(byte val, byte crc) { // for (int i = 0; i < 8; i++) { // if(((val ^ crc) & 0x80) != 0) { // crc^= 0x0e; // crc = (byte)((crc << 1) | 1); // } else { // crc= (byte)(crc << 1); // } // val = (byte)(val << 1); // } // return crc; // } } ----------------------------------------------------------package com.fcar.frameworks.utils.xjson; /** * Created by carl on 2016/4/21. */ public class XJsonStreamEndsUnexpectlyException extends XJsonSyntaxException { public XJsonStreamEndsUnexpectlyException() { } public XJsonStreamEndsUnexpectlyException(String message) { super(message); } public XJsonStreamEndsUnexpectlyException(String message, Throwable cause) { super(message, cause); } public XJsonStreamEndsUnexpectlyException(Throwable cause) { super(cause); } }
xml文件解析成树状结构
最新推荐文章于 2025-06-25 19:09:24 发布