/*---------------------------------------------------------------------------- * %%Function: ReadNCR * %%Qualified: TCore.StreamEx.BufferedStreamEx.ReadNCR * %%Contact: rlittle * * assumes we just read a "&" * * because we are pinning the token starting at &, if we determine that this * isn't an NCR, then we can just reset the read location to the start and * let the caller continue (we will return false). * * it is the caller's responsibility to NOT try to parse this & again as an * NCR. * ----------------------------------------------------------------------------*/ public bool ReadNCR(out string sNCR) { PinTokenStartRelative(-1); byte b; bool fValidNCR = false; // look for the # SwapBuffer.ReadByteBufferState state = ReadByte(out b); if (b == '#') { bool fNeedSingleDigit = true; while (state == SwapBuffer.ReadByteBufferState.Succeeded) { state = ReadByte(out b); if (b >= '0' && b <= '9') { fNeedSingleDigit = false; continue; } if (b == ';') { if (fNeedSingleDigit == false) { fValidNCR = true; } break; } break; // not a valid NCR } } if (!fValidNCR) { BufferCurrent.SetPos(BufferCurrent.TokenStart); ResetPinnedToken(); sNCR = null; return(false); } // we have a valid NCR. sNCR = Encoding.UTF8.GetString(BufferCurrent.Bytes, BufferCurrent.TokenStart, BufferCurrent.Cur - BufferCurrent.TokenStart); ResetPinnedToken(); return(true); }
/*---------------------------------------------------------------------------- * %%Function: ReadLine * %%Qualified: TCore.ListenAz.Stage2.BufferedStreamEx.ReadLine * %%Contact: rlittle * * read a line from the BufferedStreamEx. return the string, or null * if we are out of lines to read. we will always return a line at * the end of the buffer, even if its not terminated with a line ending * ----------------------------------------------------------------------------*/ public string ReadLine() { ResetPinnedToken(); if (BufferCurrent.Cur >= BufferCurrent.Lim) { if (!SwapCurrentBuffer()) // nothing to preserve, just fill the buffer { return(null); } } // start reading the line from the current position in the current buffer PinTokenStartRelative(0); bool fLookingForLF = false; while (true) { byte b; SwapBuffer.ReadByteBufferState state = ReadByte(out b); // after read, process the read then check the state... // otherwise, keep going forward if (state == StreamEx.SwapBuffer.ReadByteBufferState.PinnedTokenExceedsBufferLength || state == StreamEx.SwapBuffer.ReadByteBufferState.SourceDataExhausted) { // hmm, if we got PinnedTokenExceedsBufferLength, then we have the entire buffer // to ourselves, but no line ending was found. just invent a break here // if we got SourceDataExhausted, then we couldn't fill the next buffer, so we are // out of space...just return what we have // in either case , we do the same thing (and if we are beyond the end of the buffer // the next read will fill the buffer for us) return(Encoding.UTF8.GetString(BufferCurrent.Bytes, BufferCurrent.TokenStart, BufferCurrent.Cur - BufferCurrent.TokenStart)); } if (b == 0x0a) { // we're done. If we were looking for it, great. if not, no matter, we're still done... int cbLineEndingAdjust = fLookingForLF ? 2 : 1; // remember we don't want the line ending as part of the string we construct. Since ib hasn't been adjusted // for this character, the only thing we have to worry about is if there was a leading CR return(Encoding.UTF8.GetString(BufferCurrent.Bytes, BufferCurrent.TokenStart, BufferCurrent.Cur - BufferCurrent.TokenStart - cbLineEndingAdjust)); } if (fLookingForLF) { // was looking for a matching LF, but didn't find. must be a naked LF // push back this character (or rather,just don't eat it) BufferCurrent.Unget(); // remember to chop off the LF return(Encoding.UTF8.GetString(BufferCurrent.Bytes, BufferCurrent.TokenStart, BufferCurrent.Cur - BufferCurrent.TokenStart - 1)); } if (b == 0x0d) { fLookingForLF = true; } } }