// Read a name token, calling Error if there are no valid characters. public virtual String ReadNameToken() { // push a new log Logger.Push(new StringBuilder()); // require at least one name character if (!NextChar()) { Error("Xml_UnexpectedEOF"); } if (!XmlCharInfo.IsNameChar(currChar)) { Error(/* TODO */); } // read until we consume all the name characters while (PeekChar() && XmlCharInfo.IsNameChar(peekChar)) { NextChar(); } // get the result from the log and pop it from the logger String result = Logger.Pop().ToString(); // return our result return(nameTable.Add(result)); }
// Skip whitespace characters, returning false if nothing is skipped. public virtual bool SkipWhitespace() { bool skipped = false; while (PeekChar() && XmlCharInfo.IsWhitespace(peekChar)) { NextChar(); skipped = true; } return(skipped); }
// Move to the next character, returning false on EOF. public override bool NextChar() { bool retval; if (peValue == null) { retval = input.NextChar(); currChar = input.currChar; if (!scanForPE) { return(retval); } if (currChar == '%') { if (input.PeekChar() && XmlCharInfo.IsNameInit(input.peekChar)) { String name = input.ReadName(); input.Expect(';'); peValue = parameterEntities[name]; pePosition = 0; currChar = ' '; } } } else { retval = true; if (pePosition == -1) { pePosition++; currChar = ' '; } else if (pePosition < peValue.Length) { currChar = peValue[pePosition++]; } else { pePosition = -1; peValue = null; currChar = ' '; } } return(retval); }
// Read a character reference, returning false for general entity references. // // Already read: '&' private bool ReadCharacterReference(out char value) { // check for an empty reference if (!input.PeekChar()) { Error(/* TODO */); } if (input.peekChar == ';') { Error(/* TODO */); } // set the defaults value = (char)0; // handle character or general references if (input.peekChar == '#') { input.NextChar(); // check for an empty character reference if (!input.PeekChar()) { Error(/* TODO */); } if (input.peekChar == ';') { Error(/* TODO */); } // handle a hex or decimal character reference if (input.peekChar == 'x') { input.NextChar(); // check for an empty hex character reference if (!input.PeekChar()) { Error(/* TODO */); } if (input.peekChar == ';') { Error(/* TODO */); } // read until we consume all the digits while (input.NextChar() && input.currChar != ';') { value *= (char)0x10; if (input.currChar >= '0' && input.currChar <= '9') { value += (char)(input.currChar - '0'); } else if (input.currChar >= 'A' && input.currChar <= 'F') { value += (char)((input.currChar - 'A') + 10); } else if (input.currChar >= 'a' && input.currChar <= 'f') { value += (char)((input.currChar - 'a') + 10); } else { Error(/* TODO */); } } } else { // read until we consume all the digits while (input.NextChar() && input.currChar != ';') { value *= (char)10; if (input.currChar >= '0' && input.currChar <= '9') { value += (char)(input.currChar - '0'); } else { Error(/* TODO */); } } } // we hit eof, otherwise we'd have ';', so give an error if (input.currChar != ';') { Error("Xml_UnexpectedEOF"); } // check the range of the character if (!XmlCharInfo.IsChar(value)) { Error(/* TODO */); } return(true); } else { // read the reference name input.ReadName(); // the reference must end with ';' at this point input.Expect(';'); // signal that a general entity reference was encountered return(false); } }
private void ReadExternalOrPublicID(bool allowPub, bool setContext) { // TODO: load external subsets and parse them... // remember not to log them in the internal subset log // handle 'SYSTEM' or 'PUBLIC' if (!input.NextChar()) { Error("Xml_UnexpectedEOF"); } if (input.currChar == 'S') { // require that the input match 'SYSTEM' input.Expect("YSTEM"); // require whitespace if (!input.SkipWhitespace()) { Error(/* TODO */); } // scan for a valid quote character if (!input.NextChar()) { Error("Xml_UnexpectedEOF"); } char quoteChar = input.currChar; if (quoteChar != '"' && quoteChar != '\'') { Error(/* TODO */); } // pe scanning on string literals isn't handled inline input.ScanForPE = false; // create our log and push it onto the log stack StringBuilder log = new StringBuilder(); input.Logger.Push(log); // read until we hit the quote character while (input.NextChar() && input.currChar != quoteChar) { } // we hit eof, otherwise we'd have quoteChar, so give an error if (input.currChar != quoteChar) { Error("Xml_UnexpectedEOF"); } // pop the log from the log stack input.Logger.Pop(); // set the system id if (setContext) { context.SystemId = log.ToString(); } // turn inline pe scanning back on input.ScanForPE = true; } else if (input.currChar == 'P') { // require that the input match 'PUBLIC' input.Expect("UBLIC"); // require whitespace if (!input.SkipWhitespace()) { Error(/* TODO */); } // scan for a valid quote character if (!input.NextChar()) { Error("Xml_UnexpectedEOF"); } char quoteChar = input.currChar; if (quoteChar != '"' && quoteChar != '\'') { Error(/* TODO */); } // pe scanning on string literals isn't handled inline input.ScanForPE = false; // create our log and push it onto the log stack StringBuilder log = new StringBuilder(); input.Logger.Push(log); // read until we hit the quote character while (input.NextChar() && input.currChar != quoteChar) { // ensure we get valid public literal characters if (!XmlCharInfo.IsPublicId(input.currChar)) { Error(/* TODO */); } } // we hit eof, otherwise we'd have quoteChar, so give an error if (input.currChar != quoteChar) { Error("Xml_UnexpectedEOF"); } // pop the log from the log stack input.Logger.Pop(); // set the system id if (setContext) { context.PublicId = log.ToString(); } // reset the log log.Length = 0; // turn inline pe scanning back on input.ScanForPE = true; // skip potentially optional whitespace bool hasWS = input.SkipWhitespace(); // scan for a valid quote character if (!input.PeekChar()) { Error("Xml_UnexpectedEOF"); } quoteChar = input.peekChar; if (quoteChar != '"' && quoteChar != '\'') { // this is permitted to end here only for public ids if (allowPub) { return; } Error(/* TODO */); } input.NextChar(); // the system literal must be preceded by whitespace if (!hasWS) { Error(/* TODO */); } // pe scanning on string literals isn't handled inline input.ScanForPE = false; // push the log onto the log stack input.Logger.Push(log); // read until we hit the quote character while (input.NextChar() && input.currChar != quoteChar) { } // we hit eof, otherwise we'd have quoteChar, so give an error if (input.currChar != quoteChar) { Error("Xml_UnexpectedEOF"); } // pop the log from the log stack input.Logger.Pop(); // set the system id if (setContext) { context.SystemId = log.ToString(); } // turn inline pe scanning back on input.ScanForPE = true; } else { // we didn't see 'SYSTEM' or 'PUBLIC' so give an error Error(/* TODO */); } }