static void CollapseStringBuilder(StringBuilder sb, XString outdata, ref int tabs, ref int spaces) { if (sb.Length > 0) { outdata.Append(new XStringSeg(tabs, spaces, sb.ToString())); sb.Length = 0; tabs = 0; spaces = 0; } }
public static void Burst(XString outdata, string s, bool quote, bool parenthize, bool allow_escapes) { //lock( Preload ) { XStringSeg seg; ParenStack paren_stack = parenthize ? new ParenStack() : null; StringBuilder sb = new StringBuilder(s.Length); int spaces = 0; int tabs = 0; char quote_char = '\0'; bool escape = false; int charnum; bool elipses = false; for (charnum = 0; charnum < s.Length; charnum++) { Char character = s[charnum]; if (parenthize && paren_stack.Count > 0) { BurstParenState paren_state = paren_stack.Peek(); if (character == paren_state.CloseChar) { if (escape) { escape = false; } else { CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); paren_state.outdata_previous.Append(new XStringSeg( paren_state.tabs , paren_state.spaces , paren_state.OpenChar.ToString() , outdata , paren_state.CloseChar.ToString())); paren_stack.Pop(); outdata = paren_state.outdata_previous; sb = paren_state.sb_previous; continue; } } else { if (allow_escapes && character == '\\') { escape = true; continue; } } } if (quote_char != 0) { if (character == quote_char) { if (escape) { escape = false; } else { quote_char = '\0'; } } else { if (character == '\\') { escape = true; } sb.Append(character); } continue; } if (elipses && character != '.') { CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); elipses = false; } else if (elipses) // elipses and character is . - continue { sb.Append(character); continue; } switch (character) { case '\n': CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); outdata.Add(seg = new XStringSeg(0, 0, "")); break; case ' ': CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); spaces++; break; case '\t': CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); if (spaces != 0) { //lprintf( WIDE("Input stream has mangled spaces and tabs.") ); spaces = 0; } tabs++; break; case '\r': // a space space character... CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); break; case '.': // handle multiple periods grouped (elipses) //goto NormalPunctuation; { char c; if ((!elipses && ((c = ((charnum + 1 < s.Length) ? s[charnum + 1] : (char)0)) != 0) && (c == '.'))) { CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); sb.Append("."); elipses = true; break; } if (((c = ((charnum + 1 < s.Length) ? s[charnum + 1] : (char)0)) != 0) && (c >= '0' && c <= '9')) { // gather together as a floating point number... sb.Append(character); break; } } goto continue_case; case '-': // work seperations flaming-long-sword goto continue_case; case '+': continue_case: { int c; if (((c = ((charnum + 1 < s.Length) ? s[charnum + 1] : 0)) != 0) && (c >= '0' && c <= '9')) { CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); // gather together as a sign indication on a number. sb.Append(character); break; } } goto continue_case2; case '\'': // single quote bound case '\"': // double quote bound if (quote) { CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); paren_stack.PushParen(character, character, ref outdata, ref sb, ref tabs, ref spaces); break; } goto continue_case2; case '(': // expression bounders if (parenthize) { CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); paren_stack.PushParen(character, ')', ref outdata, ref sb, ref tabs, ref spaces); break; } goto continue_case2; case '{': if (parenthize) { CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); paren_stack.PushParen(character, '}', ref outdata, ref sb, ref tabs, ref spaces); break; } goto continue_case2; case '[': if (parenthize) { CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); paren_stack.PushParen(character, ']', ref outdata, ref sb, ref tabs, ref spaces); break; } goto continue_case2; case '<': if (parenthize) { CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); paren_stack.PushParen(character, '>', ref outdata, ref sb, ref tabs, ref spaces); break; } goto continue_case2; case ')': // expression closers case '}': case ']': case '>': case '\\': // escape next thingy... unusable in c processor case ':': // internet addresses case '@': // email addresses case '%': case '/': case ',': case ';': case '!': case '?': case '=': case '*': case '&': case '$': case '^': case '~': case '#': case '`': continue_case2: // NormalPunctuation: CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); sb.Append(character); /* * if( parenthize && paren_stack.Count > 0 ) * { * BurstParenState state = paren_stack.Peek(); * * // if it is in a paren condition, then * // don't put this out yet... otherwise emit directly. * state.outdata.Add( seg = new XStringSeg( tabs, spaces, sb.ToString() ) ); * if( state.outdata.Count > 1 ) * { * seg.prior = state.outdata[state.outdata.Count - 2]; * state.outdata[state.outdata.Count - 2].next = seg; * } * sb.Length = 0; * tabs = 0; * spaces = 0; * } * else */ CollapseStringBuilder(sb, outdata, ref tabs, ref spaces); break; default: if (elipses) { if (sb.Length > 0) { outdata.Append(seg = new XStringSeg(tabs, spaces, sb.ToString())); sb.Length = 0; tabs = 0; spaces = 0; } elipses = false; } sb.Append(character); break; } } // here at the end I have collection without a push. if (sb.Length > 0) { outdata.Append(seg = new XStringSeg(tabs, spaces, sb.ToString())); sb.Length = 0; tabs = 0; spaces = 0; } } }