package com.aionemu.packetsamurai.protocol.protocoltree; import java.util.List; import com.aionemu.packetsamurai.Util; import com.aionemu.packetsamurai.parser.PartType; import com.aionemu.packetsamurai.parser.PartTypeManager; import com.aionemu.packetsamurai.parser.formattree.Format; import com.aionemu.packetsamurai.parser.formattree.Part; import com.aionemu.packetsamurai.protocol.Protocol; import javolution.text.TextBuilder; import javolution.util.FastList; /** * This class represents a packet format in the protocol definition tree. * It is a container for {@link PacketParts PacketParts} * @author Gilles Duboscq * TODO: find a way to ensure part IDs unicity */ public class PacketFormat extends ProtocolNode { private Format _format; private String _name; private String _opStr; private String _partStr; private Protocol _containingProtocol; public PacketFormat(int id, String name) { super(id); _name = name; _format = new Format(this); } public PacketFormat() { _format = new Format(this); } public Format getDataFormat() { return _format; } public void setContainingProtocol(Protocol p) { _containingProtocol = p; } public Protocol getContainingProtocol() { return _containingProtocol; } public String getName() { return _name; } public String getOpcodeStr() { if(_opStr == null) { TextBuilder tb = new TextBuilder(); boolean first = true; for(int id : super.getIDs()) { if(!first) { tb.append(":"); } tb.append(Util.zeropad(Integer.toHexString(id), 2).toUpperCase()); first = false; } _opStr = tb.toString(); } return _opStr; } public String getPartsStr() { if (_partStr == null) { _partStr = new String(); TextBuilder tb = new TextBuilder(); tb.append("("); tb.append(Util.makeFormatString(super.getIdParts())); tb.append(") "); tb.append(Util.makeFormatString(this.getDataFormat().getMainBlock().getParts())); _partStr = tb.toString(); } return _partStr; } public String toString() { return getOpcodeStr()+" "+_name; } /** * format : (c) chdfQSsbx[ddd] * ^id ^for * id is mandatory, spaces are allowed * @param str * @param ids * @return */ public static PacketFormat generateFromString(String str, List<Integer> ids) { PacketFormat pf = new PacketFormat(); str = str.trim(); int i = 0; if(str.charAt(i) == '(') { List<PartType> idparts = new FastList<PartType>(); while(str.charAt(i) != ')') { if(str.charAt(i) == ' ') { i++; if(i >= str.length()) return null; } PartType type = PartTypeManager.getInstance().getType(str.substring(i, i+1)); if(type != null) idparts.add(type); else return null; i++; if(i >= str.length()) return null; } pf.addIdPartsAtBegining(idparts, ids); } else return null; while(i < str.length()) { if(str.charAt(i) != '[') { i++; for(Part part : parseForString(str.substring(i, str.substring(i).indexOf(']')))) { pf.getDataFormat().getMainBlock().addPart(part); while(str.charAt(i) == ' ') { i++; if(i >= str.length()) return null; } i++; if(i >= str.length()) return null; } } else if(str.charAt(i) == ' ') { i++; if(i >= str.length()) return null; } else { PartType type = PartTypeManager.getInstance().getType(str.substring(i, i+1)); if(type != null) pf.getDataFormat().getMainBlock().addPart(new Part(type,-1,"","","")); else return null; i++; if(i >= str.length()) return null; } } return pf; } private static List<Part> parseForString(String str) { int i = 0; List<Part> parts = new FastList<Part>(); if(str.charAt(i) != '[') { i++; for(Part part : parseForString(str.substring(i, str.substring(i).indexOf(']')))) { parts.add(part); while(str.charAt(i) == ' ') { i++; if(i >= str.length()) return null; } i++; if(i >= str.length()) return null; } } else if(str.charAt(i) == ' ') { i++; if(i >= str.length()) return null; } else { PartType type = PartTypeManager.getInstance().getType(str.substring(i, i+1)); if(type != null) parts.add(new Part(type,-1,"","","")); else return null; i++; if(i >= str.length()) return null; } return parts; } public static int countIdPartsInString(String str) { str = str.trim(); int i = 0; int count = 0; if(str.charAt(i) == '(') { i++; while(str.charAt(i) != ')') { if(str.charAt(i) != ' ') { if(PartTypeManager.getInstance().getType(str.substring(i, i+1)) == null) { return 0; } count++; } i++; } } return count; } public static List<PartType> getIdPartsInString(String str) { FastList<PartType> list = new FastList<PartType>(); str = str.trim(); int i = 0; int count = 0; if(str.charAt(i) == '(') { i++; while(str.charAt(i) != ')') { if(str.charAt(i) != ' ') { PartType type = PartTypeManager.getInstance().getType(str.substring(i, i+1)); if(type == null) { return null; } list.add(type); count++; } i++; } } return list; } }