public byte[] GetBytes() { currentTagCodePage = 0; currentAttributeCodePage = 0; var bytesList = new List <byte>(); //Versionnumber bytesList.Add((byte)(10 * VersionNumber - 10)); //Public identifier (currently implemented as unknown) bytesList.AddRange(GetMultiByte(TagCodeSpace.GetPublicIdentifier())); //Encoding bytesList.AddRange(GetMultiByte(IanaCharacterSets.GetMIBEnum(Encoding))); //String table length int stringTableLength = StringTable.Length; if (stringTableLength > 0) { bytesList.AddRange(GetMultiByte(stringTableLength)); bytesList.AddRange(StringTable.GetStringTableBytes(Encoding)); } else { bytesList.Add(0); } bytesList.AddRange(EncodeNodes(ChildNodes)); return(bytesList.ToArray()); }
private void Decode(IEnumerable <byte> bytes) { currentTagCodePage = 0; currentAttributeCodePage = 0; var isAttribute = false; var tagHasAttributes = false; var tagHasContent = false; XmlNode activeNode = this; XmlAttribute activeAttribute = null; var byteQueue = new Queue <byte>(bytes); //Get the WBXML version number; VersionNumber = (byteQueue.Dequeue() / 10.0) + 1.0; //Get the value of the public identifier PublicIdentifier = GetInt(byteQueue); if (PublicIdentifier == 0) { //TODO the publicIdentifier is defined as string inside the stringtable var publicIdentifierStringTableIndex = GetInt(byteQueue); } //Get the charset for text encoding Encoding = IanaCharacterSets.GetEncoding(GetInt(byteQueue)); var declaration = CreateXmlDeclaration("1.0", Encoding.WebName, null); activeNode.AppendChild(declaration); //Get the string table (use of the string table is not implemented) var stringTableLength = GetInt(byteQueue); if (stringTableLength > 0) { var byteStringTableQueue = new Queue <byte>(); for (int i = 0; i < stringTableLength; i++) { byteStringTableQueue.Enqueue(byteQueue.Dequeue()); } var stringTableList = new List <string>(); while (byteStringTableQueue.Count > 0) { string stringTableItem = GetString(byteStringTableQueue); stringTableList.Add(stringTableItem); } StringTable = new StringTable(stringTableList.ToArray()); } //WBXML body while (byteQueue.Count > 0) { var byteItem = byteQueue.Dequeue(); if (globalTokens.Contains(byteItem)) { var globalToken = globalTokens.GetToken(byteItem); switch (globalToken) { case GlobalTokens.Names.SWITCH_PAGE: currentTagCodePage = byteQueue.Dequeue(); break; case GlobalTokens.Names.END: if (isAttribute) { isAttribute = false; activeAttribute = null; if (!tagHasContent) { activeNode = activeNode.ParentNode; } } else { activeNode = activeNode.ParentNode; } break; case GlobalTokens.Names.ENTITY: var entityValue = GetInt(byteQueue); var encodedEntity = GetEntity(entityValue); if (isAttribute) { activeAttribute.InnerXml += encodedEntity; } else { activeNode.InnerXml += encodedEntity; } break; case GlobalTokens.Names.STR_I: if (isAttribute) { activeAttribute.InnerText += GetString(byteQueue); } else { activeNode.AppendChild(CreateTextNode(GetString(byteQueue))); } break; case GlobalTokens.Names.LITERAL: case GlobalTokens.Names.LITERAL_A: case GlobalTokens.Names.LITERAL_AC: case GlobalTokens.Names.LITERAL_C: //TODO LITERALs are not implemented yet var literalReference = GetInt(byteQueue); break; case GlobalTokens.Names.EXT_I_0: case GlobalTokens.Names.EXT_I_1: case GlobalTokens.Names.EXT_I_2: //TODO EXT_I_x are not implemented yet var extiString = GetString(byteQueue); break; case GlobalTokens.Names.PI: //TODO PI is not implemented yet var piByteList = new List <byte>(); while (byteQueue.Peek() != (byte)GlobalTokens.Names.END) { piByteList.Add(byteQueue.Dequeue()); } byteQueue.Dequeue(); break; case GlobalTokens.Names.EXT_T_0: case GlobalTokens.Names.EXT_T_1: case GlobalTokens.Names.EXT_T_2: //TODO EXT_T_x are not implemented yet var exttReference = GetInt(byteQueue); break; case GlobalTokens.Names.STR_T: int strtReference = GetInt(byteQueue); if (StringTable.ContainsString(strtReference)) { var stringTableItem = StringTable.GetString(strtReference); if (isAttribute) { activeAttribute.InnerText += stringTableItem.Value; } else { activeNode.AppendChild(CreateTextNode(stringTableItem.Value)); } } break; case GlobalTokens.Names.EXT_0: case GlobalTokens.Names.EXT_1: case GlobalTokens.Names.EXT_2: //TODO EXT_x are not implemented yet break; case GlobalTokens.Names.OPAQUE: var opaqueLength = GetInt(byteQueue); var opaqueByteArray = GetByteArray(byteQueue, opaqueLength); var opaqueHexList = new List <string>(); foreach (byte opaqueByteItem in opaqueByteArray) { opaqueHexList.Add(opaqueByteItem.ToString("X2")); } activeNode.InnerText = string.Join("", opaqueHexList.ToArray()); break; } } else if (!isAttribute) { tagHasAttributes = IsBitSet(byteItem, 7); tagHasContent = IsBitSet(byteItem, 6); byteItem &= 127; byteItem &= 63; string tagValue; if (TagCodeSpace.GetCodePage(currentTagCodePage).ContainsTag(byteItem)) { tagValue = TagCodeSpace.GetCodePage(currentTagCodePage).GetTag(byteItem).Name; } else { tagValue = "Tag_" + byteItem.ToString("X2"); } var xmlElement = CreateElement(tagValue); activeNode.AppendChild(xmlElement); if (!tagHasContent && !tagHasAttributes) { continue; } activeNode = xmlElement; if (tagHasAttributes) { isAttribute = true; } } else { if (byteItem < 128) { if (AttributeCodeSpace.GetCodePage(currentAttributeCodePage).ContainsAttributeStart(byteItem)) { var attributeStart = AttributeCodeSpace.GetCodePage(currentAttributeCodePage).GetAttributeStart(byteItem); var xmlAttribute = CreateAttribute(attributeStart.Name); xmlAttribute.InnerText = attributeStart.Prefix; activeNode.Attributes.Append(xmlAttribute); activeAttribute = xmlAttribute; } else { XmlAttribute xmlAttribute = CreateAttribute("attribute_" + byteItem.ToString("X2")); activeNode.Attributes.Append(xmlAttribute); activeAttribute = xmlAttribute; } } else { if (!AttributeCodeSpace.GetCodePage(currentAttributeCodePage).ContainsAttributeValue(byteItem)) { continue; } var attributeValue = AttributeCodeSpace.GetCodePage(currentAttributeCodePage).GetAttributeValue(byteItem); activeAttribute.InnerText += attributeValue.Value; } } } }