コード例 #1
0
 // holder to not have to keep creating arrays
 internal char[] ConsumeCharacterReference(char?additionalAllowedCharacter, bool inAttribute)
 {
     if (reader.IsEmpty())
     {
         return(null);
     }
     if (additionalAllowedCharacter != null && additionalAllowedCharacter == reader.Current())
     {
         return(null);
     }
     if (reader.MatchesAnySorted(notCharRefCharsSorted))
     {
         return(null);
     }
     char[] charRef = charRefHolder;
     reader.Mark();
     if (reader.MatchConsume("#"))
     {
         // numbered
         bool   isHexMode = reader.MatchConsumeIgnoreCase("X");
         String numRef    = isHexMode ? reader.ConsumeHexSequence() : reader.ConsumeDigitSequence();
         if (numRef.Length == 0)
         {
             // didn't match anything
             CharacterReferenceError("numeric reference with no numerals");
             reader.RewindToMark();
             return(null);
         }
         if (!reader.MatchConsume(";"))
         {
             CharacterReferenceError("missing semicolon");
         }
         // missing semi
         int charval = -1;
         try {
             int @base = isHexMode ? 16 : 10;
             charval = Convert.ToInt32(numRef, @base);
         }
         catch (FormatException) {
         }
         // skip
         if (charval == -1 || (charval >= 0xD800 && charval <= 0xDFFF) || charval > 0x10FFFF)
         {
             CharacterReferenceError("character outside of valid range");
             charRef[0] = replacementChar;
             return(charRef);
         }
         else
         {
             // todo: implement number replacement table
             // todo: check for extra illegal unicode points as parse errors
             if (charval < iText.IO.Util.TextUtil.CHARACTER_MIN_SUPPLEMENTARY_CODE_POINT)
             {
                 charRef[0] = (char)charval;
                 return(charRef);
             }
             else
             {
                 return(iText.IO.Util.TextUtil.ToChars(charval));
             }
         }
     }
     else
     {
         // named
         // get as many letters as possible, and look for matching entities.
         String nameRef    = reader.ConsumeLetterThenDigitSequence();
         bool   looksLegit = reader.Matches(';');
         // found if a base named entity without a ;, or an extended entity with the ;.
         bool found = (Entities.IsBaseNamedEntity(nameRef) || (Entities.IsNamedEntity(nameRef) && looksLegit));
         if (!found)
         {
             reader.RewindToMark();
             if (looksLegit)
             {
                 // named with semicolon
                 CharacterReferenceError(MessageFormatUtil.Format("invalid named referenece " + PortUtil.EscapedSingleBracket
                                                                  + "{0}" + PortUtil.EscapedSingleBracket, nameRef));
             }
             return(null);
         }
         if (inAttribute && (reader.MatchesLetter() || reader.MatchesDigit() || reader.MatchesAny('=', '-', '_')))
         {
             // don't want that to match
             reader.RewindToMark();
             return(null);
         }
         if (!reader.MatchConsume(";"))
         {
             CharacterReferenceError("missing semicolon");
         }
         // missing semi
         charRef[0] = (char)Entities.GetCharacterByName(nameRef);
         return(charRef);
     }
 }