/// <summary> /// 执行 /// </summary> /// <param name="context">操作执行上下文</param> /// <param name="next">委托</param> public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (next == null) { throw new ArgumentNullException(nameof(next)); } _logger = Web.GetService <ILogger <ApiErrorAttribute> >(); Str logString = new Str(); OnActionExecuting(context); await OnActionExecutingAsync(context, logString); if (context.Result != null) { return; } var executedContext = await next(); OnActionExecuted(executedContext); logString.Clear(); OnActionExecuted(executedContext, logString); }
public void TestPerformance_Clear() { Str str = new Str(); str.Add("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); str.Add("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); str.Add("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); str.Add("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); for (int i = 0; i < 10000000; i++) { str.Clear(); } }
string ParseName(ref int pos) { str.Clear(); int p = pos; for (;;) { if (p >= length) { return(null); } int b = this[p++]; if (b == '=') { pos = p; return(str.ToString()); } else { str.Accept(b); } } }
JObj ParseObj(ref int pos) { JObj jo = new JObj(); int p = pos; for (;;) { for (;;) { if (p >= length - 1) { throw ParseEx; } int b = this[++p]; if (b == ' ' || b == '\t' || b == '\n' || b == '\r') { continue; } if (b == '"') { break; // meet first quote } if (b == '}') // close early empty { pos = p; return(jo); } throw ParseEx; } str.Clear(); // parse name for (;;) { if (p >= length - 1) { throw ParseEx; } int b = this[++p]; if (b == '"') { break; // meet second quote } str.Add((char)b); } for (;;) // till a colon { if (p >= length - 1) { throw ParseEx; } int b = this[++p]; if (b == ' ' || b == '\t' || b == '\n' || b == '\r') { continue; } if (b == ':') { break; } throw ParseEx; } string name = str.ToString(); // parse the value part for (;;) { if (p >= length - 1) { throw ParseEx; } int b = this[++p]; if (b == ' ' || b == '\t' || b == '\n' || b == '\r') { continue; // skip ws } if (b == '{') { JObj v = ParseObj(ref p); jo.Add(name, v); } else if (b == '[') { JArr v = ParseArr(ref p); jo.Add(name, v); } else if (b == '"') { string v = ParseString(ref p); jo.Add(name, v); } else if (b == 'n') { if (ParseNull(ref p)) { jo.AddNull(name); } } else if (b == 't' || b == 'f') { bool v = ParseBool(ref p, b); jo.Add(name, v); } else if (b == '-' || b >= '0' && b <= '9') { JNumber v = ParseNumber(ref p, b); jo.Add(name, v); } else if (b == '&') // bytes extension { byte[] v = ParseBytes(p); jo.Add(name, v); } else { throw ParseEx; } break; } // comma or end for (;;) { if (p >= length - 1) { throw ParseEx; } int b = this[++p]; if (b == ' ' || b == '\t' || b == '\n' || b == '\r') { continue; } if (b == ',') { break; } if (b == '}') // close normal { pos = p; return(jo); } throw ParseEx; } } }
public void TestPerformance_Clear() { Str str = new Str(); str.Add( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ); str.Add( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ); str.Add( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ); str.Add( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ); for ( int i = 0; i < 10000000; i++ ) { str.Clear(); } }
XElem ParseElem(ref int pos, int startchar) { int p = pos; int b; // parse element tag name str.Clear(); str.Accept(startchar); while (IsNameChar(b = this[++p])) { str.Accept(b); // to comprise start tag } string tag = str.ToString(); XElem elem = new XElem(tag); // optionally parse attributes while (IsWs(b)) { while (IsWs(b = this[++p])) { } // skip ws if (IsNameStartChar(b)) { // attribute name str.Clear(); str.Accept(b); while ((b = this[++p]) != '=') { str.Accept(b); } string name = str.ToString(); // attribute value if (this[++p] != '"') { throw ParseEx; // left quote } str.Clear(); while ((b = this[++p]) != '"') // till right quote { if (b == '&') // escape < > & " { int b1 = this[p + 1]; int b2 = this[p + 2]; int b3 = this[p + 3]; if (b1 == 'l' && b2 == 't' && b3 == ';') { b = '<'; p += 3; } else if (b1 == 'g' && b2 == 't' && b3 == ';') { b = '>'; p += 3; } else if (b1 == 'a' && b2 == 'm' && b3 == 'p' && this[p + 4] == ';') { b = '&'; p += 4; } else if (b1 == 'q' && b2 == 'u' && b3 == 'o' && this[p + 4] == 't' && this[p + 5] == ';') { b = '"'; p += 5; } } str.Accept(b); } string value = str.ToString(); elem.AddAttr(name, value); b = this[++p]; // step } } // end of attributes if (b == '>') // a start tag just finished, expecting the ending-tag { for (;;) // child nodes iteration { while (IsWs(b = this[++p])) // skip ws { } if (b == '<') { b = this[++p]; if (b == '/') // the ending tag { // consume str.Clear(); while ((b = this[++p]) != '>') { str.Accept(b); } if (!str.Equals(tag)) { throw ParseEx; } pos = p; // adjust current position return(elem); } else if (b == '!') // CDATA section { if (this[p + 1] == '[' && this[p + 2] == 'C' && this[p + 3] == 'D' && this[p + 4] == 'A' && this[p + 5] == 'T' && this[p + 6] == 'A' && this[p + 7] == '[') { str.Clear(); p += 7; while ((b = this[++p]) != ']' || this[p + 1] != ']' || this[p + 2] != '>') { str.Accept(b); } elem.Text = str.ToString(); p += 2; // skip ]> } } else if (IsNameStartChar(b)) { XElem child = ParseElem(ref p, b); elem.AddChild(child); } } else // text node { str.Clear(); while ((b = this[p]) != '<') // NOTE from the first char { if (b == '&') // escape < > & " { int b1 = this[p + 1]; int b2 = this[p + 2]; int b3 = this[p + 3]; if (b1 == 'l' && b2 == 't' && b3 == ';') { b = '<'; p += 3; } else if (b1 == 'g' && b2 == 't' && b3 == ';') { b = '>'; p += 3; } else if (b1 == 'a' && b2 == 'm' && b3 == 'p' && this[p + 4] == ';') { b = '&'; p += 4; } else if (b1 == 'q' && b2 == 'u' && b3 == 'o' && this[p + 4] == 't' && this[p + 5] == ';') { b = '"'; p += 5; } } str.Accept(b); ++p; } if (str.Count > 0) { elem.Text = str.ToString(); } // NOTE decrease in position to behave as other child nodes --p; } } // child nodes iteration } if (b == '/' && this[++p] == '>') // empty-element { pos = p; // adjust current position return(elem); } throw ParseEx; }
public Form Parse() { // locality for performance byte[] bound_ = this.bound; byte[] buffer_ = this.buffer; int length_ = this.length; // UTF-8 header builder Header hdr = new Header(128); Str str = new Str(128); // keep local for speed int boundlen = bound_.Length; // shall init lately Form frm = null; int p = 0; // skip first bound line whatever for (;;) { if (buffer_[p++] == '\r' && buffer_[p++] == '\n') { break; } } // parse parts for (;;) { string name = null; string filename = null; string ctype = null; // parse headers for (;;) { hdr.Clear(); // parse a header line for (;;) { if (p >= length_ - 2) { throw ParseEx; } byte b; if ((b = buffer_[p++]) == '\r' && buffer_[p++] == '\n') { break; } hdr.Accept(b); // lineup the byte } if (hdr.Count == 0) // if empty line then quit header section { break; } if (name == null && hdr.Check("Content-Disposition")) { name = hdr.SeekParam("name"); filename = hdr.SeekParam("filename"); } else if (ctype == null && hdr.Check("Content-Type")) { ctype = hdr.GetVvalue(); } } // get part's content str.Clear(); bool plain = ctype == null || "text/plain".Equals(ctype); int start = p; // mark down content start int idx = 0; // index on bound for (;;) { byte b = buffer_[p++]; if (b == bound_[idx]) { idx++; if (idx >= boundlen) // fully matched the bound accumulatively { if (frm == null) { frm = new Form(true) { Buffer = buffer_ } } ; if (plain) { frm.Add(name, str.ToString()); } else { frm.Add(name, filename, start, p - start - boundlen); } // goto the ending CRLF/-- check break; } } else if (idx > 0) // if fail-match { if (plain) // re-add { for (int i = 0; i < idx; i++) { str.Accept(bound_[i]); } } idx = 0; // reset } else { if (plain) { str.Accept(b); } } } // check if any more part if (buffer_[p++] == '\r' && buffer_[p++] == '\n') { continue; } break; } // parts return(frm ?? Empty); } }