public bool ParseFirstLine() { _reader.Consume('\r', '\n'); if (!_reader.Contains('\n')) { throw new ParseException("Invalid firstline."); } var firstLine = _reader.ReadFoldedLine(); if (firstLine.EndsWith(SipConstants.SipTwoZeroString)) { SipRequestLine requestLine = new SipRequestLineParser().Parse(firstLine); _listener.OnRequest(requestLine); } else if (firstLine.StartsWith(SipConstants.SipTwoZeroString)) { var message = new SipResponse(); var statusLine = new SipStatusLineParser().Parse(firstLine); _listener.OnResponse(statusLine); } else { throw new ParseException(ExceptionMessage.InvalidFirstLineFormat); } _parserMethod = GetHeaderName; return(true); }
/// <summary> /// Try to find a header name. /// </summary> /// <returns></returns> private bool GetHeaderName() { // empty line. body is begining. if (_reader.Current == '\r' && _reader.Peek == '\n') { // Eat the line break _reader.Consume('\r', '\n'); // Don't have a body? if (_bodyBytesLeft == 0) { OnComplete(); _parserMethod = ParseFirstLine; } else { _parserMethod = GetBody; } return(true); } _headerName = _reader.ReadUntil(':'); if (_headerName == null) { return(false); } _reader.Consume(); // eat colon _parserMethod = GetHeaderValue; return(true); }
private bool ParseFirstLine() { _reader.Consume('\r', '\n'); if (!_reader.Contains('\n')) { throw new ParseException("Invalid firstline."); } var firstLine = _reader.ReadFoldedLine(); _onFirstLine(firstLine); _parserMethod = GetHeaderName; return(true); }
/// <summary> /// 解析请求或响应消息的第一行 /// </summary> /// <returns><c>true</c> if first line is well formatted; otherwise <c>false</c>.</returns> /// <exception cref="BadRequestException">Invalid request/response line.</exception> private bool ParseFirstLine() { /* HTTP Message Example * GET /path/file.html HTTP/1.0 * From: [email protected] * User-Agent: HTTPTool/1.0 * [blank line here] * * HTTP/1.0 200 OK * Date: Fri, 31 Dec 1999 23:59:59 GMT * Content-Type: text/html * Content-Length: 1354 * * <html> * <body> * <h1>Happy New Millennium!</h1> * (more file contents) * </body> * </html> */ _reader.Consume('\r', '\n'); // Do not contain a complete first line. if (!_reader.Contains('\n')) { return(false); } var words = new string[3]; words[0] = _reader.ReadUntil(' '); _reader.Consume(); // eat delimiter words[1] = _reader.ReadUntil(' '); _reader.Consume(); // eat delimiter words[2] = _reader.ReadLine(); if (string.IsNullOrEmpty(words[0]) || string.IsNullOrEmpty(words[1]) || string.IsNullOrEmpty(words[2])) { throw new BadRequestException("Invalid request/response line."); } // 成功找到消息的第一行 OnFirstLine(words); // 指定下一步解析方式 _parserMethod = GetHeaderName; return(true); }
private void TestReadUntilOneHeader() { byte[] bytes = _encoding.GetBytes("Welcome : Here\r\n"); _reader.Assign(bytes, 0, bytes.Length); Assert.Equal("Welcome", _reader.ReadUntil(':')); _reader.Consume(); // eat delimiter _reader.Consume('\t', ' '); Assert.Equal("Here", _reader.ReadLine()); }
private static TypeSpec ParseInternal(ref ReadOnlySpan <char> input) { TypeSpec result; char c; BufferReader s = default; s.Input = input; // Read namespace and class name, including generic arity, which is a part of the class name. NamedTypeSpec named = null; while (true) { var typeName = ParseTypeName(ref s); named = new NamedTypeSpec(named, typeName.ToString(), s.TotalGenericArity); if (s.TryPeek(out c) && c == NestedTypeIndicator) { // Consume the nested type indicator, then loop to parse the nested type. s.ConsumeCharacter(NestedTypeIndicator); continue; } break; } // Parse generic type parameters if (s.TotalGenericArity > 0 && s.TryPeek(out c) && c == ArrayStartIndicator) { s.ConsumeCharacter(ArrayStartIndicator); var arguments = new TypeSpec[s.TotalGenericArity]; for (var i = 0; i < s.TotalGenericArity; i++) { if (i > 0) { s.ConsumeCharacter(ParameterSeparator); } // Parse the argument type s.ConsumeCharacter(ArrayStartIndicator); var remaining = s.Remaining; arguments[i] = ParseInternal(ref remaining); var consumed = s.Remaining.Length - remaining.Length; s.Consume(consumed); s.ConsumeCharacter(ArrayEndIndicator); } s.ConsumeCharacter(ArrayEndIndicator); result = new ConstructedGenericTypeSpec(named, arguments); } else { // This is not a constructed generic type result = named; } // Parse modifiers bool hadModifier; do { hadModifier = false; if (!s.TryPeek(out c)) { break; } switch (c) { case ArrayStartIndicator: var dimensions = ParseArraySpecifier(ref s); result = new ArrayTypeSpec(result, dimensions); hadModifier = true; break; case PointerIndicator: result = new PointerTypeSpec(result); s.ConsumeCharacter(PointerIndicator); hadModifier = true; break; case ReferenceIndicator: result = new ReferenceTypeSpec(result); s.ConsumeCharacter(ReferenceIndicator); hadModifier = true; break; } } while (hadModifier); // Extract the assembly, if specified. if (s.TryPeek(out c) && c == AssemblyIndicator) { s.ConsumeCharacter(AssemblyIndicator); var assembly = ExtractAssemblySpec(ref s); result = new AssemblyQualifiedTypeSpec(result, assembly.ToString()); } input = s.Remaining; return(result); }
public void ReadHannes_ConsumeH_ExpectIndexToBeOne() { CreateBufferReader("hannes"); _reader.Consume('h'); _reader.Index.Should().Be(1); }