/// <summary> /// Split on token recursively /// </summary> /// <param name="el"></param> /// <param name="token"></param> protected void splitOnToken(DataElement el, char token) { if (el is Dom.String) { var strEl = (Dom.String)el; var str = (string)el.DefaultValue; var tokenIndex = str.IndexOf(token); if (tokenIndex == -1) { return; } var preString = new Dom.String() { stringType = strEl.stringType }; var tokenString = new Dom.String() { stringType = strEl.stringType }; var postString = new Dom.String() { stringType = strEl.stringType }; preString.stringType = encodingType; tokenString.stringType = encodingType; postString.stringType = encodingType; preString.DefaultValue = new Variant(str.Substring(0, tokenIndex)); tokenString.DefaultValue = new Variant(token.ToString()); postString.DefaultValue = new Variant(str.Substring(tokenIndex + 1)); var block = new Dom.Block(el.name); block.Add(preString); block.Add(tokenString); block.Add(postString); el.parent[el.name] = block; splitOnToken(postString, token); } else if (el is Dom.Block) { List <DataElement> children = new List <DataElement>(); foreach (DataElement child in ((Block)el)) { children.Add(child); } foreach (DataElement child in children) { splitOnToken(child, token); } } }
public void RecursiveSizeRelation2() { string xml = @" <Peach> <DataModel name=""DM""> <Block name=""TheBlock""> <Number name=""Length"" size=""8""> <Relation type=""size"" of=""TheBlock""/> </Number> <Blob name=""data""/> </Block> </DataModel> <DataModel name=""DM2"" ref=""DM""> <Block name=""TheBlock.data""> <Block name=""R1"" ref=""DM"" /> </Block> </DataModel> </Peach>"; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); BitStream data = new BitStream(); data.LittleEndian(); data.WriteBytes(new byte[] { 0x03, 0x02, 0x60 }); data.SeekBits(0, SeekOrigin.Begin); DataCracker cracker = new DataCracker(); cracker.CrackData(dom.dataModels[1], data); Assert.AreEqual(1, dom.dataModels[1].Count); Assert.IsTrue(dom.dataModels[1][0] is Dom.Block); Dom.Block outerBlock = (Dom.Block)dom.dataModels[1][0]; Assert.AreEqual(2, outerBlock.Count); Assert.IsTrue(outerBlock[0] is Dom.Number); Assert.AreEqual(new byte[] { 0x03 }, ((Dom.Number)outerBlock[0]).Value.Value); Assert.IsTrue(outerBlock[1] is Dom.Block); Dom.Block outerDataBlock = (Dom.Block)outerBlock[1]; Assert.AreEqual(1, outerDataBlock.Count); Assert.IsTrue(outerDataBlock[0] is Dom.Block); Assert.AreEqual(1, ((Dom.Block)outerDataBlock[0]).Count); Assert.IsTrue(((Dom.Block)outerDataBlock[0])[0] is Dom.Block); Dom.Block innerBlock = (Dom.Block)(((Dom.Block)outerDataBlock[0])[0]); Assert.AreEqual(2, innerBlock.Count); Assert.IsTrue(innerBlock[0] is Dom.Number); Assert.AreEqual(new byte[] { 0x02 }, ((Dom.Number)innerBlock[0]).Value.Value); Assert.IsTrue(innerBlock[1] is Dom.Blob); Assert.AreEqual(new byte[] { 0x60 }, ((Dom.Blob)innerBlock[1]).Value.Value); }
public void ChoiceSizeRelations2() { string xml = @" <Peach> <DataModel name=""DM""> <Block name=""TheBlock""> <Choice> <Block name=""C1""> <Number name=""version"" size=""8"" value=""1"" token=""true""/> <Number name=""LengthBig"" size=""16""> <Relation type=""size"" of=""TheBlock""/> </Number> </Block> <Block name=""C2""> <Number name=""version"" size=""8"" value=""2"" token=""true""/> <Number name=""LengthSmall"" size=""8""> <Relation type=""size"" of=""TheBlock""/> </Number> </Block> </Choice> <Blob name=""data""/> </Block> <Blob/> </DataModel> </Peach>"; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); BitStream data = new BitStream(); data.LittleEndian(); data.WriteBytes(new byte[] { 0x02, 0x05, 0x33, 0x44, 0x55 }); data.SeekBits(0, SeekOrigin.Begin); DataCracker cracker = new DataCracker(); cracker.CrackData(dom.dataModels[0], data); Dom.Block TheBlock = (Dom.Block)dom.dataModels[0][0]; Assert.AreEqual(2, TheBlock.Count); Assert.IsTrue(TheBlock[0] is Dom.Choice); Assert.IsTrue(TheBlock[1] is Blob); Assert.IsTrue(dom.dataModels[0][1] is Blob); Assert.AreEqual(3, TheBlock[1].Value.LengthBytes); Assert.AreEqual(0, ((Dom.Blob)dom.dataModels[0][1]).Value.LengthBytes); }
/// <summary> /// Split on token recursively /// </summary> /// <param name="el"></param> /// <param name="token"></param> /// <param name="offset"></param> protected void splitOnToken(DataElement el, char token, ref long offset) { if (el is Dom.String) { var strEl = (Dom.String)el; var str = (string)el.DefaultValue; var tokenIndex = str.IndexOf(token); if (tokenIndex == -1) { if (positions != null) { offset = positions[el].end; } return; } var preString = new Dom.String() { stringType = strEl.stringType }; var tokenString = new Dom.String() { stringType = strEl.stringType }; var postString = new Dom.String() { stringType = strEl.stringType }; preString.stringType = encodingType; tokenString.stringType = encodingType; postString.stringType = encodingType; preString.DefaultValue = new Variant(str.Substring(0, tokenIndex)); tokenString.DefaultValue = new Variant(token.ToString()); postString.DefaultValue = new Variant(str.Substring(tokenIndex + 1)); var block = new Dom.Block(el.name); block.Add(preString); block.Add(tokenString); block.Add(postString); el.parent[el.name] = block; if (positions != null) { var lenPre = 8 * encoding.GetByteCount((string)preString.DefaultValue); var lenToken = 8 * encoding.GetByteCount((string)tokenString.DefaultValue); var lenPost = 8 * encoding.GetByteCount((string)postString.DefaultValue); var prePos = new Position() { begin = offset, end = offset + lenPre }; var tokenPos = new Position() { begin = prePos.end, end = prePos.end + lenToken }; var postPos = new Position() { begin = tokenPos.end, end = tokenPos.end + lenPost }; var blockPos = new Position() { begin = prePos.begin, end = postPos.end }; positions.Remove(el); positions[block] = blockPos; positions[preString] = prePos; positions[tokenString] = tokenPos; positions[postString] = postPos; offset = postPos.begin; } splitOnToken(postString, token, ref offset); } else if (el is Dom.Block) { List <DataElement> children = new List <DataElement>(); foreach (DataElement child in ((Block)el)) { children.Add(child); } foreach (DataElement child in children) { splitOnToken(child, token, ref offset); } } }