public MarkupDocument(byte* data, int length, string textTagName, List<string> textTags, List<string> noScopeTags, IMarkupElementFactory factory, Encoding encoder) { p_Root = new MarkupElement("{LIP_DOCUMENT}"); Parse(data, length, textTagName, textTags, noScopeTags, p_Root, factory, encoder); OnDocumentLoaded(); }
public void Remove(MarkupElement element) { p_Root.RemoveChild(element); }
public LinkedList<MarkupElement> Find(string[] query, bool matchCase, MarkupElement.FindMode mode) { return p_Root.Find(query, matchCase, mode); }
public LinkedList<MarkupElement> Find(string[] query, bool deepSearch, bool[] matchCase, bool[] matchWhole, MarkupElement.FindMode mode) { return p_Root.Find(query, deepSearch, matchCase, matchWhole, mode); }
public static void Parse(byte* data, int length, string textTagName, List<string> textTags, List<string> noScopeTags, MarkupElement root, IMarkupElementFactory factory, Encoding encoder) { //define the pointer which is right at the end of the data byte* dataEnd = data + length; //define the element in which we are currently adding tags to. Node current = root as Node; //define the pointers which will hold the text which is added as a text tag once //a tag is hit in the data byte* innerTextBufferPtr = data; byte* innerTextBufferPtrEnd = data; //define the list of items that will store the names of every node //which are currently in the LinkedList<STRPTR> currentNameList = new LinkedList<STRPTR>(); LinkedListNode<STRPTR> currentName = null; STRPTR currentNamePtr = default(STRPTR); //iterate over the data while (data < dataEnd) { //is it a tag? if (*data == MarkupTAG_OPEN) { //save where the end of the text is innerTextBufferPtrEnd = data - 1; data++; //is the tag we are about to read, a close tag? bool closeTag = false; Helpers.SkipWhitespaces(ref data, dataEnd); if (*data == MarkupTAG_SCOPECLOSE) { data++; closeTag = true; } //define whether or not the close tag character is in the //code, if it isn't, this isn't a tag bool closeCharFound = false; #region read comment //block comment? (<!--) if (*data == '!' && data < dataEnd - 2 && *(data + 1) == '-' && *(data + 2) == '-') { //skip over the comment data += 3; while (data < dataEnd - 3) { if (*data == '-' && *(data + 1) == '-' && *(data + 2) == MarkupTAG_CLOSE) { data += 3; break; } data++; } continue; } #endregion #region read name //read the name of the tag byte* tagNamePtr, tagNamePtrEnd; readName(ref data, dataEnd, out tagNamePtr, out tagNamePtrEnd, false, false, ref closeCharFound); bool tagHasQM = *tagNamePtr == '?'; #endregion #region close tag? //if it's a close tag, check if the close tag is closing the current tag if (closeTag) { bool closingCurrent = compareData( tagNamePtr, currentNamePtr.PTR, tagNamePtrEnd + 1, currentNamePtr.PTREND + 1); //buffer what the current tag is in case we need to add text to it Node oldCurrent = current; //are we closing the current tag? //if so, we just select the parent of the current tag if (closingCurrent) { currentNamePtr.Destroy(); currentName = currentName.Previous; current = current.Parent; currentNameList.RemoveLast(); } else if(currentName != null) { //find how many nodes up we need to go to find //what tag is being closed LinkedListNode<STRPTR> currentSeek = currentName.Previous; Node currentSeekNode = current.Parent; while (currentSeek != null) { STRPTR currentSeekValue = currentSeek.Value; //if we find a match, we have the element which this tag is closing. if (compareData( tagNamePtr, currentSeekValue.PTR, tagNamePtrEnd + 1, currentSeekValue.PTREND + 1)) { //select the nodes parent as the current currentName = currentSeek.Previous; current = currentSeekNode.Parent; //clean up if (currentName != null) { while (currentName.Next != null) { currentNameList.RemoveLast(); //causes heap corruption for some reason.... //deallocString(dealloc); } } break; } currentSeek = currentSeek.Previous; currentSeekNode = currentSeekNode.Parent; } } //set the current names pointer to the new pointer if (currentName == null) { currentNamePtr = default(STRPTR); } else { currentNamePtr = currentName.Value; } //since we know it is a close tag, skip to the end of the tag while (data < dataEnd && *data != MarkupTAG_CLOSE) { data++; } data++; /* * is there text to be added before the element is added? * * (c&p from text string being added when an element is being added */ #region text if (innerTextBufferPtr != innerTextBufferPtrEnd) { //create the text element if (!isEmptyData(innerTextBufferPtr, innerTextBufferPtrEnd - 1)) { string str = Helpers.ReadString(innerTextBufferPtr, innerTextBufferPtrEnd, encoder); if (oldCurrent is MarkupTextElement) { (oldCurrent as MarkupTextElement).Text = str; } else { oldCurrent.AddChild(factory.CreateText(textTagName, str)); } } } //reset innerTextBufferPtr = data; innerTextBufferPtrEnd = data; #endregion continue; } #endregion //are we currently in a text tag? meaning we need to ignore any children being added? //and just assume all data we are reading right now is within that element if (current is MarkupTextElement) { innerTextBufferPtrEnd = data; continue; } //because we now know it's an open tag, start building the element MarkupElement element; string tagNameStr = Helpers.ReadString(tagNamePtr, tagNamePtrEnd, encoder); if (textTags.Contains(tagNameStr.ToLower())) { element = factory.CreateText(tagNameStr, ""); } else { element = factory.Create(tagNameStr); } //flag to show if the tag terminates with a "/>" //or has no scope. bool tagDoesTerminate = false; if (tagHasQM || noScopeTags.Contains(tagNameStr.ToLower()) || *tagNamePtr == '!' || *tagNamePtr == '@') { tagDoesTerminate = true; } #region attributes //read the attributes for this tag while (data < dataEnd) { Helpers.SkipWhitespaces(ref data, dataEnd); if (*data == MarkupTAG_CLOSE) { break; } if (tagHasQM && *data == '?') { break; } //tag closed? if (*data == MarkupTAG_SCOPECLOSE) { tagDoesTerminate = true; break; } //is the attribute a quote? if (*data == '"' || *data == '\'') { //read as a string and set the attributes name as null //(since it's just a value) byte* valuePtr, valuePtrEnd; readStringValue(ref data, dataEnd, out valuePtr, out valuePtrEnd, tagHasQM, ref closeCharFound); element.AddAttribute( null, Helpers.ReadString(valuePtr, valuePtrEnd, encoder)); continue; } //read the name byte* attrNamePtr, attrNamePtrEnd; if (readName(ref data, dataEnd, out attrNamePtr, out attrNamePtrEnd, false, tagHasQM, ref closeCharFound)) { break; } //skip to the value if (Helpers.SkipWhitespaces(ref data, dataEnd)) { break; } //read the value byte* attrValuePtr = data, attrValuePtrEnd = (byte*)NULLPTR; if (*data == '=') { data++; if (Helpers.SkipWhitespaces(ref data, dataEnd)) { break; } //read the value readStringValue(ref data, dataEnd, out attrValuePtr, out attrValuePtrEnd, tagHasQM, ref closeCharFound); } //add the attribute string valueString = (attrValuePtrEnd == (byte*)0) ? null : Helpers.ReadString(attrValuePtr, attrValuePtrEnd, encoder); element.AddAttribute( Helpers.ReadString(attrNamePtr, attrNamePtrEnd, encoder), valueString); } #endregion //skip to the end of the tag while (data < dataEnd && *data != MarkupTAG_CLOSE) { if (*data == MarkupTAG_SCOPECLOSE) { tagDoesTerminate = true; } data++; } if (*data == MarkupTAG_CLOSE) { closeCharFound = true; } #region create inner text if required //is there text to be added before the element is added? if (innerTextBufferPtr != innerTextBufferPtrEnd) { //create the text element if (!isEmptyData(innerTextBufferPtr, innerTextBufferPtrEnd - 1)) { string str = Helpers.ReadString(innerTextBufferPtr, innerTextBufferPtrEnd, encoder); if (current is MarkupTextElement) { (current as MarkupTextElement).Text = str; } else { current.AddChild(factory.CreateText(textTagName, str)); } } } //reset innerTextBufferPtr = data + 1; innerTextBufferPtrEnd = data + 1; #endregion //is this a valid tag? if (!closeCharFound) { //just presume what we just processed was text innerTextBufferPtrEnd = data; continue; } //add the tag current.AddChild(element); //change the current name to the new element //but only if the tag has not been terminated immidiately //(otherwise there is no point adding to it.) if (!tagDoesTerminate) { current = element; currentNamePtr = element.TagName; currentName = currentNameList.AddLast(currentNamePtr); } } innerTextBufferPtrEnd++; data++; } //is there text left? if (innerTextBufferPtrEnd != innerTextBufferPtr && innerTextBufferPtrEnd > innerTextBufferPtr && !isEmptyData(innerTextBufferPtr, innerTextBufferPtrEnd - 1)) { current.AddChild(factory.CreateText( textTagName, Helpers.ReadString( innerTextBufferPtr, innerTextBufferPtrEnd, encoder))); } //clean up IEnumerator<STRPTR> destructCurrentNameList = currentNameList.GetEnumerator(); while (destructCurrentNameList.MoveNext()) { destructCurrentNameList.Current.Destroy(); } destructCurrentNameList.Dispose(); }
public MarkupDocument() { p_Root = new MarkupElement("{LIP_DOCUMENT}"); }
public static void Parse(string data, string textTagName, List<string> textTags, List<string> noScopeTags, MarkupElement root, IMarkupElementFactory factory, Encoding encoder) { Parse(encoder.GetBytes(data), textTagName, textTags, noScopeTags, root, factory, encoder); }
public static void Parse(byte[] data, string textTagName, List<string> textTags, List<string> noScopeTags, MarkupElement root, IMarkupElementFactory factory, Encoding encoder) { fixed (byte* ptr = data) { Parse(ptr, data.Length, textTagName, textTags, noScopeTags, root, factory, encoder); } }
public static LinkedList<MarkupElement> Parse(byte[] data, string textTagName, List<string> textTags, List<string> noScopeTags, IMarkupElementFactory factory, Encoding encoder) { MarkupElement root = new MarkupElement("{LIP_DOCUMENT"); Parse( data, textTagName, textTags, noScopeTags, root, factory, encoder); //get all the elements from the parent node LinkedList<MarkupElement> buffer = new LinkedList<MarkupElement>(); LinkedList<Node> children = root.Children; IEnumerator<Node> e = children.GetEnumerator(); while (e.MoveNext()) { MarkupElement c = e.Current as MarkupElement; buffer.AddLast(c); } //clean up e.Dispose(); return buffer; }
public static void Parse(byte* data, int length, string textTagName, List<string> textTags, List<string> noScopeTags, IMarkupElementFactory factory, MarkupElement root) { Parse( data, length, textTagName, textTags, noScopeTags, root, factory, Encoding.ASCII); }
public static void Parse(string data, string textTagName, List<string> textTags, List<string> noScopeTags, IMarkupElementFactory factory, MarkupElement root) { Parse( data, textTagName, textTags, noScopeTags, factory, Encoding.ASCII); }
public bool AppliesTo(MarkupElement originalElement, MarkupElement pipeElement) { //get the index of the element int index = pipeElement.Index; //odd/even? if (p_Odd) { return index % 2 != 0; } if (p_Even) { return index % 2 == 0; } //substitute for n? if (!p_HasNSubstitute) { //index has to match the result of the calculation return index == p_ExpressionResult; } //use the n substitute as an accumulator and //see if the result of the expression //matches the elements index. ArithmeticSubstitute n = new ArithmeticSubstitute( new ArithmeticOperand(0), 'n'); LinkedList<ArithmeticSubstitute> subs = new LinkedList<ArithmeticSubstitute>(); subs.AddLast(n); for (int c = 0; c <= index; c++) { n.Operand.setValue(c, false, true); ArithmeticNumeric res = p_Expression.Calculate(subs); if (res == index) { return true; } } //no match return false; }
public void MergeWith(MarkupElement element) { //element cannot be a text node! if (element is MarkupTextElement) { throw new Exception("Unable to merge with a text element!"); } //merge the elements attributes MergeWith(element.Attributes); //add all of the elements children IEnumerator<Node> children = element.Children.GetEnumerator(); while (children.MoveNext()) { element.AddChild(children.Current); } //clean up children.Dispose(); }