static internal void AdjustLineInfo( char[] chars, int startPos, int endPos, bool isNormalized, ref LineInfo lineInfo ) {
     int lastNewLinePos = -1;
     int i = startPos;
     while ( i < endPos ) {
         switch ( chars[i] ) {
             case '\n':
                 lineInfo.lineNo++;
                 lastNewLinePos = i;
                 break;
             case '\r':
                 if ( isNormalized ) {
                     break;
                 }
                 lineInfo.lineNo++;
                 lastNewLinePos = i;
                 if ( i + 1 < endPos && chars[i+1] == '\n' ) {
                     i++;
                     lastNewLinePos++;
                 }
                 break;
         }
         i++;
     }
     if ( lastNewLinePos >= 0 ) {
         lineInfo.linePos = endPos - lastNewLinePos;
     }
 }
        private async Task< Tuple<string, string> > ParseExternalIdAsync(Token idTokenType, Token declType) {
            Tuple<string, string> tuple;
            string publicId;
            string systemId;

            LineInfo keywordLineInfo = new LineInfo( LineNo, LinePos - 6 );
            publicId = null;
            systemId = null;

            if ( await GetTokenAsync( true ).ConfigureAwait(false) != Token.Literal ) {
                ThrowUnexpectedToken( curPos, "\"", "'" );
            }

            if ( idTokenType == Token.SYSTEM ) {
                systemId = GetValue();

                if ( systemId.IndexOf( '#' ) >= 0 ) {
                    Throw( curPos - systemId.Length - 1, Res.Xml_FragmentId, new string[] { systemId.Substring( systemId.IndexOf( '#' ) ), systemId } );
                }

                if ( declType == Token.DOCTYPE && !freeFloatingDtd ) {
                    literalLineInfo.linePos++;
                    readerAdapter.OnSystemId( systemId, keywordLineInfo, literalLineInfo );
                }
            }
            else {
                Debug.Assert( idTokenType == Token.PUBLIC );
                publicId = GetValue();

                // verify if it contains chars valid for public ids
                int i;
                if ( ( i = xmlCharType.IsPublicId( publicId ) ) >= 0 ) {
                    ThrowInvalidChar( curPos - 1 - publicId.Length + i, publicId, i );
                }

                if ( declType == Token.DOCTYPE && !freeFloatingDtd ) {
                    literalLineInfo.linePos++;
                    readerAdapter.OnPublicId( publicId, keywordLineInfo, literalLineInfo );

                    if ( await GetTokenAsync( false ).ConfigureAwait(false) == Token.Literal ) {
                        if ( !whitespaceSeen ) {
                            Throw( Res.Xml_ExpectingWhiteSpace, new string( literalQuoteChar, 1 ), (int)literalLineInfo.lineNo, (int)literalLineInfo.linePos );
                        }
                        systemId = GetValue();
                        literalLineInfo.linePos++;
                        readerAdapter.OnSystemId( systemId, keywordLineInfo, literalLineInfo );
                    }
                    else {
                        ThrowUnexpectedToken( curPos, "\"", "'" );
                    }
                }
                else {
                    if ( await GetTokenAsync( false ).ConfigureAwait(false) == Token.Literal ) {
                        if ( !whitespaceSeen ) {
                            Throw( Res.Xml_ExpectingWhiteSpace, new string( literalQuoteChar, 1 ), (int)literalLineInfo.lineNo, (int)literalLineInfo.linePos );
                        }
                        systemId = GetValue();
                    }
                    else if ( declType != Token.NOTATION ) {
                        ThrowUnexpectedToken( curPos, "\"", "'" );
                    } 
                }
            }

        tuple = new Tuple<string, string>(publicId, systemId);
        return tuple;

        }
        private Task ParseEndElementAsync_CheckEndTag(int nameLen, NodeData startTagNode, LineInfo endTagLineInfo) {

            int pos;
            char[] chars;
            for (; ; ) {
                pos = ps.charPos + nameLen;
                chars = ps.chars;

                if (pos == ps.charsUsed) {
                    parseEndElement_NextFunc = ParseEndElementParseFunction.ReadData;
                    return AsyncHelper.DoneTask;
                }

                bool tagMismatch = false;

                unsafe {
#if SILVERLIGHT
                    if ( xmlCharType.IsNCNameSingleChar( chars[pos] ) ||
#else // Optimization due to the lack of inlining when a method uses byte*
                    if (((xmlCharType.charProperties[chars[pos]] & XmlCharType.fNCNameSC) != 0) ||
#endif
 (chars[pos] == ':')
#if XML10_FIFTH_EDITION
                         || xmlCharType.IsNCNameHighSurrogateChar( chars[pos] ) 
#endif
) {
                        tagMismatch = true;
                    }
                }
                                
                if (tagMismatch) {
                    return ThrowTagMismatchAsync(startTagNode);
                }
                
                // eat whitespaces
                if (chars[pos] != '>') {
                    char tmpCh;
                    while (xmlCharType.IsWhiteSpace(tmpCh = chars[pos])) {
                        pos++;
                        switch (tmpCh) {
                            case (char)0xA:
                                OnNewLine(pos);
                                continue;
                            case (char)0xD:
                                if (chars[pos] == (char)0xA) {
                                    pos++;
                                }
                                else if (pos == ps.charsUsed && !ps.isEof) {
                                    break;
                                }
                                OnNewLine(pos);
                                continue;
                        }
                    }
                }

                if (chars[pos] == '>') {
                    break;
                }
                else if (pos == ps.charsUsed) {
                    parseEndElement_NextFunc = ParseEndElementParseFunction.ReadData;
                    return AsyncHelper.DoneTask;
                }
                else {
                    ThrowUnexpectedToken(pos, ">");
                }

                Debug.Assert(false, "We should never get to this point.");
            }

            Debug.Assert(index > 0);
            index--;
            curNode = nodes[index];

            // set the element data
            Debug.Assert(curNode == startTagNode);
            startTagNode.lineInfo = endTagLineInfo;
            startTagNode.type = XmlNodeType.EndElement;
            ps.charPos = pos + 1;

            // set next parsing function
            nextParsingFunction = (index > 0) ? parsingFunction : ParsingFunction.DocumentContent;
            parsingFunction = ParsingFunction.PopElementContext;

            parseEndElement_NextFunc = ParseEndElementParseFunction.Done;
            return AsyncHelper.DoneTask;
        }
Esempio n. 4
0
            internal void AdjustLineInfo(int valueOffset, bool isNormalized, ref LineInfo lineInfo)
            {
                if (valueOffset == 0)
                {
                    return;
                }

                if (valueStartPos != -1)
                {
                    XmlTextReader.AdjustLineInfo(chars, valueStartPos, valueStartPos + valueOffset, isNormalized, ref lineInfo);
                }
                else
                {
                    char[] chars = value.Substring(0, valueOffset).ToCharArray();
                    XmlTextReader.AdjustLineInfo(chars, 0, chars.Length, isNormalized, ref lineInfo);
                }
            }
Esempio n. 5
0
        internal static unsafe void AdjustLineInfo(char[] chars, int startPos, int endPos, bool isNormalized, ref LineInfo lineInfo)
        {
            Debug.Assert(startPos >= 0);
            Debug.Assert(endPos < chars.Length);
            Debug.Assert(startPos <= endPos);

            fixed (char* pChars = &chars[startPos])
            {
                AdjustLineInfo(pChars, endPos - startPos, isNormalized, ref lineInfo);
            }
        }
Esempio n. 6
0
 internal static unsafe void AdjustLineInfo(char* pChars, int length, bool isNormalized, ref LineInfo lineInfo)
 {
     int lastNewLinePos = -1;
     for (int i = 0; i < length; i++)
     {
         switch (pChars[i])
         {
             case '\n':
                 lineInfo.lineNo++;
                 lastNewLinePos = i;
                 break;
             case '\r':
                 if (isNormalized)
                 {
                     break;
                 }
                 lineInfo.lineNo++;
                 lastNewLinePos = i;
                 if (i + 1 < length && pChars[i + 1] == '\n')
                 {
                     i++;
                     lastNewLinePos++;
                 }
                 break;
         }
     }
     if (lastNewLinePos >= 0)
     {
         lineInfo.linePos = length - lastNewLinePos;
     }
 }
        private Task ParseEndElementAsync_CheckNameAndParse()
        {
            NodeData startTagNode = _nodes[_index - 1];
            int prefLen = startTagNode.prefix.Length;
            int locLen = startTagNode.localName.Length;

            int nameLen;
            char[] chars = _ps.chars;
            if (startTagNode.prefix.Length == 0)
            {
                if (!XmlConvert.StrEqual(chars, _ps.charPos, locLen, startTagNode.localName))
                {
                    return ThrowTagMismatchAsync(startTagNode);
                }
                nameLen = locLen;
            }
            else
            {
                int colonPos = _ps.charPos + prefLen;
                if (!XmlConvert.StrEqual(chars, _ps.charPos, prefLen, startTagNode.prefix) ||
                        chars[colonPos] != ':' ||
                        !XmlConvert.StrEqual(chars, colonPos + 1, locLen, startTagNode.localName))
                {
                    return ThrowTagMismatchAsync(startTagNode);
                }
                nameLen = locLen + prefLen + 1;
            }
            LineInfo endTagLineInfo = new LineInfo(_ps.lineNo, _ps.LinePos);
            return ParseEndElementAsync_Finish(nameLen, startTagNode, endTagLineInfo);
        }
Esempio n. 8
0
        // parses the element end tag
        private void ParseEndElement()
        {
            // check if the end tag name equals start tag name
            NodeData startTagNode = _nodes[_index - 1];

            int prefLen = startTagNode.prefix.Length;
            int locLen = startTagNode.localName.Length;

            while (_ps.charsUsed - _ps.charPos < prefLen + locLen + 1)
            {
                if (ReadData() == 0)
                {
                    break;
                }
            }

            int nameLen;
            char[] chars = _ps.chars;
            if (startTagNode.prefix.Length == 0)
            {
                if (!XmlConvert.StrEqual(chars, _ps.charPos, locLen, startTagNode.localName))
                {
                    ThrowTagMismatch(startTagNode);
                }
                nameLen = locLen;
            }
            else
            {
                int colonPos = _ps.charPos + prefLen;
                if (!XmlConvert.StrEqual(chars, _ps.charPos, prefLen, startTagNode.prefix) ||
                        chars[colonPos] != ':' ||
                        !XmlConvert.StrEqual(chars, colonPos + 1, locLen, startTagNode.localName))
                {
                    ThrowTagMismatch(startTagNode);
                }
                nameLen = locLen + prefLen + 1;
            }

            LineInfo endTagLineInfo = new LineInfo(_ps.lineNo, _ps.LinePos);

            int pos;
            for (;;)
            {
                pos = _ps.charPos + nameLen;
                chars = _ps.chars;

                if (pos == _ps.charsUsed)
                {
                    goto ReadData;
                }

                unsafe
                {
                    if (_xmlCharType.IsNCNameSingleChar(chars[pos]) || (chars[pos] == ':')
#if XML10_FIFTH_EDITION
                         || xmlCharType.IsNCNameHighSurrogateChar(chars[pos])
#endif
                        )
                    {
                        ThrowTagMismatch(startTagNode);
                    }
                }

                // eat whitespaces
                if (chars[pos] != '>')
                {
                    char tmpCh;
                    while (_xmlCharType.IsWhiteSpace(tmpCh = chars[pos]))
                    {
                        pos++;
                        switch (tmpCh)
                        {
                            case (char)0xA:
                                OnNewLine(pos);
                                continue;
                            case (char)0xD:
                                if (chars[pos] == (char)0xA)
                                {
                                    pos++;
                                }
                                else if (pos == _ps.charsUsed && !_ps.isEof)
                                {
                                    break;
                                }
                                OnNewLine(pos);
                                continue;
                        }
                    }
                }

                if (chars[pos] == '>')
                {
                    break;
                }
                else if (pos == _ps.charsUsed)
                {
                    goto ReadData;
                }
                else
                {
                    ThrowUnexpectedToken(pos, ">");
                }

                Debug.Assert(false, "We should never get to this point.");

            ReadData:
                if (ReadData() == 0)
                {
                    ThrowUnclosedElements();
                }
            }

            Debug.Assert(_index > 0);
            _index--;
            _curNode = _nodes[_index];

            // set the element data
            Debug.Assert(_curNode == startTagNode);
            startTagNode.lineInfo = endTagLineInfo;
            startTagNode.type = XmlNodeType.EndElement;
            _ps.charPos = pos + 1;

            // set next parsing function
            _nextParsingFunction = (_index > 0) ? _parsingFunction : ParsingFunction.DocumentContent;
            _parsingFunction = ParsingFunction.PopElementContext;
        }
Esempio n. 9
0
 void IDtdParserAdapter.OnSystemId(string systemId, LineInfo keywordLineInfo, LineInfo systemLiteralLineInfo)
 {
     _reader.DtdParserProxy_OnSystemId(systemId, keywordLineInfo, systemLiteralLineInfo);
 }
Esempio n. 10
0
 void IDtdParserAdapter.OnPublicId(string publicId, LineInfo keywordLineInfo, LineInfo publicLiteralLineInfo)
 {
     _reader.DtdParserProxy_OnPublicId(publicId, keywordLineInfo, publicLiteralLineInfo);
 }
 void IDtdParserAdapter.OnPublicId( string publicId, LineInfo keywordLineInfo, LineInfo publicLiteralLineInfo ) { 
     reader.DtdParserProxy_OnPublicId( publicId, keywordLineInfo, publicLiteralLineInfo ); 
 }
 void IDtdParserAdapter.OnSystemId( string systemId, LineInfo keywordLineInfo, LineInfo systemLiteralLineInfo ) { 
     reader.DtdParserProxy_OnSystemId( systemId, keywordLineInfo, systemLiteralLineInfo ); 
 }
        private async Task ParseAttributeValueSlowAsync( int curPos, char quoteChar, NodeData attr ) {
            int pos = curPos;
            char[] chars = ps.chars;
            int attributeBaseEntityId = ps.entityId;
#if !SILVERLIGHT // Needed only for XmlTextReader (reporting of entities)
            int valueChunkStartPos = 0;
            LineInfo valueChunkLineInfo = new LineInfo(ps.lineNo, ps.LinePos);
            NodeData lastChunk = null;
#endif

            Debug.Assert( stringBuilder.Length == 0 );

            for (;;) {
                // parse the rest of the attribute value
#if SILVERLIGHT
                while (xmlCharType.IsAttributeValueChar(chars[pos])) {
                    pos++;
                }
#else // Optimization due to the lack of inlining when a method uses byte*
                unsafe {
                    while (((xmlCharType.charProperties[chars[pos]] & XmlCharType.fAttrValue) != 0)) {
                        pos++;
                    }
                }
#endif

                if ( pos - ps.charPos > 0 ) {
                    stringBuilder.Append( chars, ps.charPos, pos - ps.charPos );
                    ps.charPos = pos;
                }

                if ( chars[pos] == quoteChar && attributeBaseEntityId == ps.entityId ) {
                    break;
                }
                else {
                    switch ( chars[pos] ) {
                        // eol
                        case (char)0xA:
                            pos++;
                            OnNewLine( pos );
                            if ( normalize ) {
                                stringBuilder.Append( (char)0x20 );  // CDATA normalization of 0xA
                                ps.charPos++;
                            }
                            continue;
                        case (char)0xD:
                            if ( chars[pos+1] == (char)0xA ) {
                                pos += 2;
                                if ( normalize ) {
                                    stringBuilder.Append( ps.eolNormalized ? "\u0020\u0020" : "\u0020" ); // CDATA normalization of 0xD 0xA
                                    ps.charPos = pos;
                                }
                            }
                            else if ( pos+1 < ps.charsUsed || ps.isEof ) { 
                                pos++;
                                if ( normalize ) {
                                    stringBuilder.Append( (char)0x20 );  // CDATA normalization of 0xD and 0xD 0xA
                                    ps.charPos = pos;
                                }
                            } 
                            else {
                                goto ReadData;
                            }
                            OnNewLine( pos );
                            continue;
                        // tab
                        case (char)0x9:
                            pos++;
                            if ( normalize ) {
                                stringBuilder.Append( (char)0x20 );  // CDATA normalization of 0x9
                                ps.charPos++;
                            }
                            continue;
                        case '"':
                        case '\'':
                        case '>':
                            pos++;
                            continue;
                        // attribute values cannot contain '<'
                        case '<':
                            Throw( pos, Res.Xml_BadAttributeChar, XmlException.BuildCharExceptionArgs( '<', '\0' ) );
                            break;
                        // entity referece
                        case '&':
                            if ( pos - ps.charPos > 0 ) {
                                stringBuilder.Append( chars, ps.charPos, pos - ps.charPos );
                            }
                            ps.charPos = pos;

#if !SILVERLIGHT // Needed only for XmlTextReader (reporting of entities)
                            int enclosingEntityId = ps.entityId;
                            LineInfo entityLineInfo = new LineInfo( ps.lineNo, ps.LinePos + 1 );
#endif

                            var tuple_8 = await HandleEntityReferenceAsync( true,  EntityExpandType.All).ConfigureAwait(false);
                            pos = tuple_8.Item1;

                            switch ( tuple_8.Item2 ) {

                                case EntityType.CharacterDec:
                                case EntityType.CharacterHex:
                                case EntityType.CharacterNamed:
                                    break;
#if !SILVERLIGHT // Needed only for XmlTextReader (reporting of entities)
                                case EntityType.Unexpanded:
                                    if ( parsingMode == ParsingMode.Full && ps.entityId == attributeBaseEntityId ) {
                                        // construct text value chunk
                                        int valueChunkLen = stringBuilder.Length - valueChunkStartPos;
                                        if ( valueChunkLen > 0 ) {
                                            NodeData textChunk = new NodeData();
                                            textChunk.lineInfo = valueChunkLineInfo;
                                            textChunk.depth = attr.depth + 1;
                                            textChunk.SetValueNode( XmlNodeType.Text, stringBuilder.ToString( valueChunkStartPos, valueChunkLen ) );
                                            AddAttributeChunkToList( attr, textChunk, ref lastChunk );
                                        }

                                        // parse entity name
                                        ps.charPos++;
                                        string entityName = await ParseEntityNameAsync().ConfigureAwait(false);
                                             
                                        // construct entity reference chunk
                                        NodeData entityChunk = new NodeData();
                                        entityChunk.lineInfo = entityLineInfo;
                                        entityChunk.depth = attr.depth + 1;
                                        entityChunk.SetNamedNode( XmlNodeType.EntityReference, entityName );
                                        AddAttributeChunkToList( attr, entityChunk, ref lastChunk );

                                        // append entity ref to the attribute value
                                        stringBuilder.Append( '&' );
                                        stringBuilder.Append( entityName );
                                        stringBuilder.Append( ';' );

                                        // update info for the next attribute value chunk
                                        valueChunkStartPos = stringBuilder.Length;
                                        valueChunkLineInfo.Set( ps.LineNo, ps.LinePos );

                                        fullAttrCleanup = true;
                                    }
                                    else {
                                        ps.charPos++;
                                        await ParseEntityNameAsync().ConfigureAwait(false);
                                    }
                                    pos = ps.charPos;
                                    break;

                                case EntityType.ExpandedInAttribute:
                                    if ( parsingMode == ParsingMode.Full && enclosingEntityId == attributeBaseEntityId  ) {
                                        
                                        // construct text value chunk
                                        int valueChunkLen = stringBuilder.Length - valueChunkStartPos;
                                        if ( valueChunkLen > 0 ) {
                                            NodeData textChunk = new NodeData();
                                            textChunk.lineInfo = valueChunkLineInfo;
                                            textChunk.depth = attr.depth + 1;
                                            textChunk.SetValueNode( XmlNodeType.Text, stringBuilder.ToString( valueChunkStartPos, valueChunkLen ) );
                                            AddAttributeChunkToList( attr, textChunk, ref lastChunk );
                                        }

                                        // construct entity reference chunk
                                        NodeData entityChunk = new NodeData();
                                        entityChunk.lineInfo = entityLineInfo;
                                        entityChunk.depth = attr.depth + 1;
                                        entityChunk.SetNamedNode( XmlNodeType.EntityReference, ps.entity.Name );
                                        AddAttributeChunkToList( attr, entityChunk, ref lastChunk );

                                        fullAttrCleanup = true;

                                        // Note: info for the next attribute value chunk will be updated once we
                                        // get out of the expanded entity
                                    }
                                    pos = ps.charPos;
                                    break;
#endif
                                default:
                                    pos = ps.charPos;
                                    break;
                            }
                            chars = ps.chars;
                            continue;
                        default:
                            // end of buffer
                            if ( pos == ps.charsUsed ) {
                                goto ReadData;
                            }
                            // surrogate chars
                            else { 
                                char ch = chars[pos];
                                if ( XmlCharType.IsHighSurrogate(ch) ) {
                                    if ( pos + 1 == ps.charsUsed ) {
                                        goto ReadData;
                                    }
                                    pos++;
                                    if ( XmlCharType.IsLowSurrogate( chars[pos] ) ) {
                                        pos++;
                                        continue;
                                    }
                                }
                                ThrowInvalidChar( chars, ps.charsUsed, pos );
                                break;
                            }
                    }
                }
            
            ReadData:
                // read new characters into the buffer
                if ( await ReadDataAsync().ConfigureAwait(false) == 0 ) {
                    if ( ps.charsUsed - ps.charPos > 0 ) {
                        if ( ps.chars[ps.charPos] != (char)0xD ) {
                            Debug.Assert( false, "We should never get to this point." );
                            Throw( Res.Xml_UnexpectedEOF1 );
                        }
                        Debug.Assert( ps.isEof );
                    }
                    else {
                        if ( !InEntity ) {
                            if ( fragmentType == XmlNodeType.Attribute ) {
                                if ( attributeBaseEntityId != ps.entityId ) {
                                    Throw( Res.Xml_EntityRefNesting );
                                }
                                break;
                            }
                            Throw( Res.Xml_UnclosedQuote );
                        }
#if SILVERLIGHT // Needed only for XmlTextReader (reporting of entities)
                        HandleEntityEnd( true );
#else 
                        if ( HandleEntityEnd( true ) ) { // no EndEntity reporting while parsing attributes
                            Debug.Assert( false );
                            Throw( Res.Xml_InternalError );
                        }
                        // update info for the next attribute value chunk
                        if ( attributeBaseEntityId == ps.entityId ) {
                            valueChunkStartPos = stringBuilder.Length;
                            valueChunkLineInfo.Set( ps.LineNo, ps.LinePos );
                        }
#endif
                    }
                }

                pos = ps.charPos;
                chars = ps.chars;
            }

#if !SILVERLIGHT // Needed only for XmlTextReader (reporting of entities)
            if ( attr.nextAttrValueChunk != null ) {
                // construct last text value chunk
                int valueChunkLen = stringBuilder.Length - valueChunkStartPos;
                if ( valueChunkLen > 0 ) {
                    NodeData textChunk = new NodeData();
                    textChunk.lineInfo = valueChunkLineInfo;
                    textChunk.depth = attr.depth + 1;
                    textChunk.SetValueNode( XmlNodeType.Text, stringBuilder.ToString( valueChunkStartPos, valueChunkLen ) );
                    AddAttributeChunkToList( attr, textChunk, ref lastChunk );
                }
            }
#endif

            ps.charPos = pos + 1;

            attr.SetValue( stringBuilder.ToString() );
            stringBuilder.Length = 0;
        }
Esempio n. 14
0
 internal void DtdParserProxy_OnSystemId(string systemId, LineInfo keywordLineInfo, LineInfo systemLiteralLineInfo)
 {
     NodeData attr = AddAttributeNoChecks("SYSTEM", _index + 1);
     attr.SetValue(systemId);
     attr.lineInfo = keywordLineInfo;
     attr.lineInfo2 = systemLiteralLineInfo;
 }
Esempio n. 15
0
        private Task ParseEndElementAsync_Finish(int nameLen, NodeData startTagNode, LineInfo endTagLineInfo)
        {
            Task task = ParseEndElementAsync_CheckEndTag(nameLen, startTagNode, endTagLineInfo);
            while (true)
            {
                if (!task.IsSuccess())
                {
                    return ParseEndElementAsync_Finish(task, nameLen, startTagNode, endTagLineInfo);
                }

                switch (_parseEndElement_NextFunc)
                {
                    case ParseEndElementParseFunction.CheckEndTag:
                        task = ParseEndElementAsync_CheckEndTag(nameLen, startTagNode, endTagLineInfo);
                        break;
                    case ParseEndElementParseFunction.ReadData:
                        task = ParseEndElementAsync_ReadData();
                        break;
                    case ParseEndElementParseFunction.Done:
                        return task;
                }
            }
        }
Esempio n. 16
0
 internal void DtdParserProxy_OnPublicId(string publicId, LineInfo keywordLineInfo, LineInfo publicLiteralLineInfo)
 {
     NodeData attr = AddAttributeNoChecks("PUBLIC", _index + 1);
     attr.SetValue(publicId);
     attr.lineInfo = keywordLineInfo;
     attr.lineInfo2 = publicLiteralLineInfo;
 }
Esempio n. 17
0
 private async Task ParseEndElementAsync_Finish(Task task, int nameLen, NodeData startTagNode, LineInfo endTagLineInfo)
 {
     while (true)
     {
         await task.ConfigureAwait(false);
         switch (_parseEndElement_NextFunc)
         {
             case ParseEndElementParseFunction.CheckEndTag:
                 task = ParseEndElementAsync_CheckEndTag(nameLen, startTagNode, endTagLineInfo);
                 break;
             case ParseEndElementParseFunction.ReadData:
                 task = ParseEndElementAsync_ReadData();
                 break;
             case ParseEndElementParseFunction.Done:
                 return;
         }
     }
 }
Esempio n. 18
0
        private void ParseAttributeValueSlow(int curPos, char quoteChar, NodeData attr)
        {
            int pos = curPos;
            char[] chars = _ps.chars;
            int attributeBaseEntityId = _ps.entityId;
            int valueChunkStartPos = 0;
            LineInfo valueChunkLineInfo = new LineInfo(_ps.lineNo, _ps.LinePos);
            NodeData lastChunk = null;

            Debug.Assert(_stringBuilder.Length == 0);

            for (;;)
            {
                // parse the rest of the attribute value
                unsafe
                {
                    while (_xmlCharType.IsAttributeValueChar(chars[pos]))
                    {
                        pos++;
                    }
                }

                if (pos - _ps.charPos > 0)
                {
                    _stringBuilder.Append(chars, _ps.charPos, pos - _ps.charPos);
                    _ps.charPos = pos;
                }

                if (chars[pos] == quoteChar && attributeBaseEntityId == _ps.entityId)
                {
                    break;
                }
                else
                {
                    switch (chars[pos])
                    {
                        // eol
                        case (char)0xA:
                            pos++;
                            OnNewLine(pos);
                            if (_normalize)
                            {
                                _stringBuilder.Append((char)0x20);  // CDATA normalization of 0xA
                                _ps.charPos++;
                            }
                            continue;
                        case (char)0xD:
                            if (chars[pos + 1] == (char)0xA)
                            {
                                pos += 2;
                                if (_normalize)
                                {
                                    _stringBuilder.Append(_ps.eolNormalized ? "\u0020\u0020" : "\u0020"); // CDATA normalization of 0xD 0xA
                                    _ps.charPos = pos;
                                }
                            }
                            else if (pos + 1 < _ps.charsUsed || _ps.isEof)
                            {
                                pos++;
                                if (_normalize)
                                {
                                    _stringBuilder.Append((char)0x20);  // CDATA normalization of 0xD and 0xD 0xA
                                    _ps.charPos = pos;
                                }
                            }
                            else
                            {
                                goto ReadData;
                            }
                            OnNewLine(pos);
                            continue;
                        // tab
                        case (char)0x9:
                            pos++;
                            if (_normalize)
                            {
                                _stringBuilder.Append((char)0x20);  // CDATA normalization of 0x9
                                _ps.charPos++;
                            }
                            continue;
                        case '"':
                        case '\'':
                        case '>':
                            pos++;
                            continue;
                        // attribute values cannot contain '<'
                        case '<':
                            Throw(pos, SR.Xml_BadAttributeChar, XmlException.BuildCharExceptionArgs('<', '\0'));
                            break;
                        // entity referece
                        case '&':
                            if (pos - _ps.charPos > 0)
                            {
                                _stringBuilder.Append(chars, _ps.charPos, pos - _ps.charPos);
                            }
                            _ps.charPos = pos;

                            int enclosingEntityId = _ps.entityId;
                            LineInfo entityLineInfo = new LineInfo(_ps.lineNo, _ps.LinePos + 1);
                            switch (HandleEntityReference(true, EntityExpandType.All, out pos))
                            {
                                case EntityType.CharacterDec:
                                case EntityType.CharacterHex:
                                case EntityType.CharacterNamed:
                                    break;
                                case EntityType.Unexpanded:
                                    if (_parsingMode == ParsingMode.Full && _ps.entityId == attributeBaseEntityId)
                                    {
                                        // construct text value chunk
                                        int valueChunkLen = _stringBuilder.Length - valueChunkStartPos;
                                        if (valueChunkLen > 0)
                                        {
                                            NodeData textChunk = new NodeData();
                                            textChunk.lineInfo = valueChunkLineInfo;
                                            textChunk.depth = attr.depth + 1;
                                            textChunk.SetValueNode(XmlNodeType.Text, _stringBuilder.ToString(valueChunkStartPos, valueChunkLen));
                                            AddAttributeChunkToList(attr, textChunk, ref lastChunk);
                                        }

                                        // parse entity name
                                        _ps.charPos++;
                                        string entityName = ParseEntityName();

                                        // construct entity reference chunk
                                        NodeData entityChunk = new NodeData();
                                        entityChunk.lineInfo = entityLineInfo;
                                        entityChunk.depth = attr.depth + 1;
                                        entityChunk.SetNamedNode(XmlNodeType.EntityReference, entityName);
                                        AddAttributeChunkToList(attr, entityChunk, ref lastChunk);

                                        // append entity ref to the attribute value
                                        _stringBuilder.Append('&');
                                        _stringBuilder.Append(entityName);
                                        _stringBuilder.Append(';');

                                        // update info for the next attribute value chunk
                                        valueChunkStartPos = _stringBuilder.Length;
                                        valueChunkLineInfo.Set(_ps.LineNo, _ps.LinePos);

                                        _fullAttrCleanup = true;
                                    }
                                    else
                                    {
                                        _ps.charPos++;
                                        ParseEntityName();
                                    }
                                    pos = _ps.charPos;
                                    break;

                                case EntityType.ExpandedInAttribute:
                                    if (_parsingMode == ParsingMode.Full && enclosingEntityId == attributeBaseEntityId)
                                    {
                                        // construct text value chunk
                                        int valueChunkLen = _stringBuilder.Length - valueChunkStartPos;
                                        if (valueChunkLen > 0)
                                        {
                                            NodeData textChunk = new NodeData();
                                            textChunk.lineInfo = valueChunkLineInfo;
                                            textChunk.depth = attr.depth + 1;
                                            textChunk.SetValueNode(XmlNodeType.Text, _stringBuilder.ToString(valueChunkStartPos, valueChunkLen));
                                            AddAttributeChunkToList(attr, textChunk, ref lastChunk);
                                        }

                                        // construct entity reference chunk
                                        NodeData entityChunk = new NodeData();
                                        entityChunk.lineInfo = entityLineInfo;
                                        entityChunk.depth = attr.depth + 1;
                                        entityChunk.SetNamedNode(XmlNodeType.EntityReference, _ps.entity.Name);
                                        AddAttributeChunkToList(attr, entityChunk, ref lastChunk);

                                        _fullAttrCleanup = true;

                                        // Note: info for the next attribute value chunk will be updated once we
                                        // get out of the expanded entity
                                    }
                                    pos = _ps.charPos;
                                    break;
                                default:
                                    pos = _ps.charPos;
                                    break;
                            }
                            chars = _ps.chars;
                            continue;
                        default:
                            // end of buffer
                            if (pos == _ps.charsUsed)
                            {
                                goto ReadData;
                            }
                            // surrogate chars
                            else
                            {
                                char ch = chars[pos];
                                if (XmlCharType.IsHighSurrogate(ch))
                                {
                                    if (pos + 1 == _ps.charsUsed)
                                    {
                                        goto ReadData;
                                    }
                                    pos++;
                                    if (XmlCharType.IsLowSurrogate(chars[pos]))
                                    {
                                        pos++;
                                        continue;
                                    }
                                }
                                ThrowInvalidChar(chars, _ps.charsUsed, pos);
                                break;
                            }
                    }
                }

            ReadData:
                // read new characters into the buffer
                if (ReadData() == 0)
                {
                    if (_ps.charsUsed - _ps.charPos > 0)
                    {
                        if (_ps.chars[_ps.charPos] != (char)0xD)
                        {
                            Debug.Assert(false, "We should never get to this point.");
                            Throw(SR.Xml_UnexpectedEOF1);
                        }
                        Debug.Assert(_ps.isEof);
                    }
                    else
                    {
                        if (!InEntity)
                        {
                            if (_fragmentType == XmlNodeType.Attribute)
                            {
                                if (attributeBaseEntityId != _ps.entityId)
                                {
                                    Throw(SR.Xml_EntityRefNesting);
                                }
                                break;
                            }
                            Throw(SR.Xml_UnclosedQuote);
                        }
                        if (HandleEntityEnd(true))
                        { // no EndEntity reporting while parsing attributes
                            Debug.Assert(false);
                            Throw(SR.Xml_InternalError);
                        }
                        // update info for the next attribute value chunk
                        if (attributeBaseEntityId == _ps.entityId)
                        {
                            valueChunkStartPos = _stringBuilder.Length;
                            valueChunkLineInfo.Set(_ps.LineNo, _ps.LinePos);
                        }
                    }
                }

                pos = _ps.charPos;
                chars = _ps.chars;
            }

            if (attr.nextAttrValueChunk != null)
            {
                // construct last text value chunk
                int valueChunkLen = _stringBuilder.Length - valueChunkStartPos;
                if (valueChunkLen > 0)
                {
                    NodeData textChunk = new NodeData();
                    textChunk.lineInfo = valueChunkLineInfo;
                    textChunk.depth = attr.depth + 1;
                    textChunk.SetValueNode(XmlNodeType.Text, _stringBuilder.ToString(valueChunkStartPos, valueChunkLen));
                    AddAttributeChunkToList(attr, textChunk, ref lastChunk);
                }
            }

            _ps.charPos = pos + 1;

            attr.SetValue(_stringBuilder.ToString());
            _stringBuilder.Length = 0;
        }
Esempio n. 19
0
        private Task ParseEndElementAsync_CheckEndTag(int nameLen, NodeData startTagNode, LineInfo endTagLineInfo)
        {
            int pos;
            char[] chars;
            for (; ;)
            {
                pos = _ps.charPos + nameLen;
                chars = _ps.chars;

                if (pos == _ps.charsUsed)
                {
                    _parseEndElement_NextFunc = ParseEndElementParseFunction.ReadData;
                    return Task.CompletedTask;
                }

                bool tagMismatch = false;

                unsafe
                {
                    if (_xmlCharType.IsNCNameSingleChar(chars[pos]) || (chars[pos] == ':')
#if XML10_FIFTH_EDITION
                         || xmlCharType.IsNCNameHighSurrogateChar(chars[pos])
#endif
)
                    {
                        tagMismatch = true;
                    }
                }

                if (tagMismatch)
                {
                    return ThrowTagMismatchAsync(startTagNode);
                }

                // eat whitespaces
                if (chars[pos] != '>')
                {
                    char tmpCh;
                    while (_xmlCharType.IsWhiteSpace(tmpCh = chars[pos]))
                    {
                        pos++;
                        switch (tmpCh)
                        {
                            case (char)0xA:
                                OnNewLine(pos);
                                continue;
                            case (char)0xD:
                                if (chars[pos] == (char)0xA)
                                {
                                    pos++;
                                }
                                else if (pos == _ps.charsUsed && !_ps.isEof)
                                {
                                    break;
                                }
                                OnNewLine(pos);
                                continue;
                        }
                    }
                }

                if (chars[pos] == '>')
                {
                    break;
                }
                else if (pos == _ps.charsUsed)
                {
                    _parseEndElement_NextFunc = ParseEndElementParseFunction.ReadData;
                    return Task.CompletedTask;
                }
                else
                {
                    ThrowUnexpectedToken(pos, ">");
                }

                Debug.Assert(false, "We should never get to this point.");
            }

            Debug.Assert(_index > 0);
            _index--;
            _curNode = _nodes[_index];

            // set the element data
            Debug.Assert(_curNode == startTagNode);
            startTagNode.lineInfo = endTagLineInfo;
            startTagNode.type = XmlNodeType.EndElement;
            _ps.charPos = pos + 1;

            // set next parsing function
            _nextParsingFunction = (_index > 0) ? _parsingFunction : ParsingFunction.DocumentContent;
            _parsingFunction = ParsingFunction.PopElementContext;

            _parseEndElement_NextFunc = ParseEndElementParseFunction.Done;
            return Task.CompletedTask;
        }
Esempio n. 20
0
        internal static unsafe void AdjustLineInfo(string str, int startPos, int endPos, bool isNormalized, ref LineInfo lineInfo)
        {
            Debug.Assert(startPos >= 0);
            Debug.Assert(endPos < str.Length);
            Debug.Assert(startPos <= endPos);

            fixed (char* pChars = str)
            {
                AdjustLineInfo(pChars + startPos, endPos - startPos, isNormalized, ref lineInfo);
            }
        }
Esempio n. 21
0
        private void ParseAttributeValueSlow(int curPos, char quoteChar, NodeData attr)
        {
            int pos = curPos;
            char[] chars = ps.chars;
            int valueChunkStartPos = 0;
            LineInfo valueChunkLineInfo = new LineInfo(ps.lineNo, ps.LinePos);
            NodeData lastChunk = null;

            Debug.Assert(stringBuilder.Length == 0);

            for (; ; )
            {
                // parse the rest of the attribute value
                while (chars[pos] > XmlCharType.MaxAsciiChar || (xmlCharType.charProperties[chars[pos]] & XmlCharType.fAttrValue) != 0)
                {
                    pos++;
                }

                if (pos - ps.charPos > 0)
                {
                    stringBuilder.Append(chars, ps.charPos, pos - ps.charPos);
                    ps.charPos = pos;
                }

                if (chars[pos] == quoteChar)
                {
                    break;
                }
                else
                {
                    switch (chars[pos])
                    {
                        // eol
                        case (char)0xA:
                            pos++;
                            OnNewLine(pos);
                            if (normalize)
                            {
                                stringBuilder.Append((char)0x20);  // CDATA normalization of 0xA
                                ps.charPos++;
                            }
                            continue;
                        case (char)0xD:
                            if (chars[pos + 1] == (char)0xA)
                            {
                                pos += 2;
                                if (normalize)
                                {
                                    stringBuilder.Append(ps.eolNormalized ? "\u0020\u0020" : "\u0020"); // CDATA normalization of 0xD 0xA
                                    ps.charPos = pos;
                                }
                            }
                            else if (pos + 1 < ps.charsUsed || ps.isEof)
                            {
                                pos++;
                                if (normalize)
                                {
                                    stringBuilder.Append((char)0x20);  // CDATA normalization of 0xD and 0xD 0xA
                                    ps.charPos = pos;
                                }
                            }
                            else
                            {
                                goto ReadData;
                            }

                            OnNewLine(pos);
                            continue;
                        // tab
                        case (char)0x9:
                            pos++;
                            if (normalize)
                            {
                                stringBuilder.Append((char)0x20);  // CDATA normalization of 0x9
                                ps.charPos++;
                            }
                            continue;
                        case '"':
                        case '\'':
                        case '>':
                            pos++;
                            continue;
                        // attribute values cannot contain '<'
                        case '<':
                            Throw(pos, Res.Xml_BadAttributeChar, XmlException.BuildCharExceptionStr('<'));
                            break;
                        // entity referece
                        case '&':
                            if (pos - ps.charPos > 0)
                            {
                                stringBuilder.Append(chars, ps.charPos, pos - ps.charPos);
                            }

                            ps.charPos = pos;

                            LineInfo entityLineInfo = new LineInfo(ps.lineNo, ps.LinePos + 1);
                            switch (HandleEntityReference(true, EntityExpandType.All, out pos))
                            {
                                case EntityType.CharacterDec:
                                case EntityType.CharacterHex:
                                case EntityType.CharacterNamed:
                                    break;
                                case EntityType.Unexpanded:
                                    Debug.Assert(false, "The document contains an entity reference");
                                    throw new NotSupportedException();

                                case EntityType.ExpandedInAttribute:
                                    Debug.Assert(false, "The document contains an entity reference");
                                    throw new NotSupportedException();
                                default:
                                    pos = ps.charPos;
                                    break;
                            }

                            chars = ps.chars;
                            continue;
                        default:
                            // end of buffer
                            if (pos == ps.charsUsed)
                            {
                                goto ReadData;
                            }

                            // surrogate chars
                            else
                            {
                                char ch = chars[pos];
                                if (ch >= SurHighStart && ch <= SurHighEnd)
                                {
                                    if (pos + 1 == ps.charsUsed)
                                    {
                                        goto ReadData;
                                    }

                                    pos++;
                                    if (chars[pos] >= SurLowStart && chars[pos] <= SurLowEnd)
                                    {
                                        pos++;
                                        continue;
                                    }
                                }

                                ThrowInvalidChar(pos, ch);
                                break;
                            }
                    }
                }

            ReadData:
                // read new characters into the buffer
                if (ReadData() == 0)
                {
                    if (ps.charsUsed - ps.charPos > 0)
                    {
                        if (ps.chars[ps.charPos] != (char)0xD)
                        {
                            Debug.Assert(false, "We should never get to this point.");
                            Throw(Res.Xml_UnexpectedEOF1);
                        }

                        Debug.Assert(ps.isEof);
                    }
                    else
                    {
                        if (fragmentType == XmlNodeType.Attribute)
                        {
                            break;
                        }

                        Throw(Res.Xml_UnclosedQuote);
                    }
                }

                pos = ps.charPos;
                chars = ps.chars;
            }

            if (attr.nextAttrValueChunk != null)
            {
                // construct last text value chunk
                int valueChunkLen = stringBuilder.Length - valueChunkStartPos;
                if (valueChunkLen > 0)
                {
                    NodeData textChunk = new NodeData();
                    textChunk.lineInfo = valueChunkLineInfo;
                    textChunk.depth = attr.depth + 1;
                    textChunk.SetValueNode(XmlNodeType.Text, stringBuilder.ToString(valueChunkStartPos, valueChunkLen));
                    AddAttributeChunkToList(attr, textChunk, ref lastChunk);
                }
            }

            ps.charPos = pos + 1;

            attr.SetValue(stringBuilder.ToString());
            stringBuilder.Length = 0;
        }
Esempio n. 22
0
        private void ParseExternalId(Token idTokenType, Token declType, out string publicId, out string systemId)
        {
            LineInfo keywordLineInfo = new LineInfo(LineNo, LinePos - 6);
            publicId = null;
            systemId = null;

            if (GetToken(true) != Token.Literal)
            {
                ThrowUnexpectedToken(_curPos, "\"", "'");
            }

            if (idTokenType == Token.SYSTEM)
            {
                systemId = GetValue();

                if (systemId.IndexOf('#') >= 0)
                {
                    Throw(_curPos - systemId.Length - 1, SR.Xml_FragmentId, new string[] { systemId.Substring(systemId.IndexOf('#')), systemId });
                }

                if (declType == Token.DOCTYPE && !_freeFloatingDtd)
                {
                    _literalLineInfo.linePos++;
                    _readerAdapter.OnSystemId(systemId, keywordLineInfo, _literalLineInfo);
                }
            }
            else
            {
                Debug.Assert(idTokenType == Token.PUBLIC);
                publicId = GetValue();

                // verify if it contains chars valid for public ids
                int i;
                if ((i = _xmlCharType.IsPublicId(publicId)) >= 0)
                {
                    ThrowInvalidChar(_curPos - 1 - publicId.Length + i, publicId, i);
                }

                if (declType == Token.DOCTYPE && !_freeFloatingDtd)
                {
                    _literalLineInfo.linePos++;
                    _readerAdapter.OnPublicId(publicId, keywordLineInfo, _literalLineInfo);

                    if (GetToken(false) == Token.Literal)
                    {
                        if (!_whitespaceSeen)
                        {
                            Throw(SR.Xml_ExpectingWhiteSpace, new string(_literalQuoteChar, 1), (int)_literalLineInfo.lineNo, (int)_literalLineInfo.linePos);
                        }
                        systemId = GetValue();
                        _literalLineInfo.linePos++;
                        _readerAdapter.OnSystemId(systemId, keywordLineInfo, _literalLineInfo);
                    }
                    else
                    {
                        ThrowUnexpectedToken(_curPos, "\"", "'");
                    }
                }
                else
                {
                    if (GetToken(false) == Token.Literal)
                    {
                        if (!_whitespaceSeen)
                        {
                            Throw(SR.Xml_ExpectingWhiteSpace, new string(_literalQuoteChar, 1), (int)_literalLineInfo.lineNo, (int)_literalLineInfo.linePos);
                        }
                        systemId = GetValue();
                    }
                    else if (declType != Token.NOTATION)
                    {
                        ThrowUnexpectedToken(_curPos, "\"", "'");
                    }
                }
            }
        }
Esempio n. 23
0
        protected override void Render(HtmlTextWriter writer)
        {
            int nRet = 0;

            string strError = "";
            List<LineInfo> infos = new List<LineInfo>();

            int nPageNo = this.StartIndex / this.PageMaxLines;

            if (this.DatabaseMode == false)
            {
                // return:
                //      -1  出错
                //      0   成功
                //      1   尚未登录
                nRet = this.LoadReaderXml(out strError);
                if (nRet == -1)
                {
                    writer.Write(strError);
                    return;
                }

                if (nRet == 1)
                {
                    sessioninfo.LoginCallStack.Push(this.Page.Request.RawUrl);
                    this.Page.Response.Redirect("login.aspx", true);
                    return;
                }

                XmlNodeList nodes = ReaderDom.DocumentElement.SelectNodes("borrowHistory/borrow");

                SetResultInfo(nodes.Count);

                for (int i = this.StartIndex; i < this.StartIndex + this.PageMaxLines; i++)
                {
                    if (i >= nodes.Count)
                    {
                        infos.Add(new LineInfo());
                    }
                    else
                    {
                        XmlNode node = nodes[i];
                        infos.Add(new LineInfo(node as XmlElement));
                    }
                }
            }
            else
            {
                List<ChargingItemWrapper> results = null;

                // return:
                //      -2  尚未登录
                //      -1  出错
                //      其它  符合条件的事项总数
                nRet = GetChargingHistory(nPageNo,
            this.PageMaxLines,
            out results,
            out strError);
                if (nRet == -1)
                {
                    writer.Write(strError);
                    return;
                }
                if (nRet == -2)
                {
                    sessioninfo.LoginCallStack.Push(this.Page.Request.RawUrl);
                    this.Page.Response.Redirect("login.aspx", true);
                    return;
                }

                SetResultInfo(nRet);

                if (results != null)    // 2016/10/30
                {
                    for (int i = 0; i < this.PageMaxLines; i++)
                    {
                        if (i >= results.Count)
                        {
                            infos.Add(new LineInfo());
                        }
                        else
                        {
                            ChargingItemWrapper wrapper = results[i];
                            LineInfo info = new LineInfo(wrapper);
                            infos.Add(info);
                        }
                    }
                }
            }

            if (infos.Count != 0)
            {
                //OpacApplication app = (OpacApplication)this.Page.Application["app"];
                //SessionInfo sessioninfo = (SessionInfo)this.Page.Session["sessioninfo"];

                // 显示本页中的浏览行
                {
                    int i = 0;
                    foreach (LineInfo info in infos)
                    {
                        StringBuilder text = new StringBuilder();

                        string strBarcodeLink = "<a href='book.aspx?barcode=" + info.strBarcode + "&forcelogin=userid' target='_blank'>" + info.strBarcode + "</a>";
                        string strItemBarcode = info.strBarcode;
                        if (info.strAction == "read")
                        {
                            if (string.IsNullOrEmpty(strItemBarcode) == true)
                                strItemBarcode = "@biblioRecPath:" + info.strBiblioRecPath;
                            strBarcodeLink = "<a href='book.aspx?barcode=" + strItemBarcode + "&forcelogin=userid' target='_blank'>" + strItemBarcode + "</a>";
                        }

                        string strTrClass = " class='dark content " + info.strAction + "' ";

                        if ((i % 2) == 1)
                            strTrClass = " class='light content " + info.strAction + "' ";

                        text.Append("<tr " + strTrClass + ">");

                        text.Append("<td class='no'>" + (i + this.StartIndex + 1).ToString() + "</td>");
                        text.Append("<td class='action'>" + HttpUtility.HtmlEncode(GetActionName(info.strAction)) + "</td>");
                        text.Append("<td class='barcode'>" + strBarcodeLink + "</td>");
                        text.Append("<td class='summary pending' >" + HttpUtility.HtmlEncode(strItemBarcode) + "</td>");

                        info.strBorrowPeriod = app.GetDisplayTimePeriodStringEx(info.strBorrowPeriod);

                        if (info.IsEmpty() == true)
                            text.Append("<td class='borrowinfo'>" + "</td>");
                        else
                        {
                            if (info.strAction == "read")
                                text.Append("<td class='borrowinfo'>"
    + "<div class='returndate'>"
    + this.GetString("操作日期")
    + ":" + info.strReturnDate + "</div>"
    + "</td>");
                            else
                                text.Append("<td class='borrowinfo'>"
                                    + "<div class='borrowno'>"
                                    + this.GetString("续借次")
                                    + "  :" + info.strNo + "</div>"
                                    + "<div class='borrowdate'>"
                                    + this.GetString("借阅日期")
                                    + ":" + info.strBorrowDate + "</div>"
                                    + "<div class='borrowperiod'>"
                                    + this.GetString("期限")
                                    + ":    " + info.strBorrowPeriod + "</div>"
                                    + "<div class='returndate'>"
                                    + this.GetString("还书日期")
                                    + ":" + info.strReturnDate + "</div>"
                                    + "</td>");
                        }

                        text.Append("<td class='renewcomment'>" + HttpUtility.HtmlEncode(info.strRenewComment) + "</td>");

                        if (this.DatabaseMode == false || info.IsEmpty())
                            text.Append("<td class='operator'>" + info.strOperator + "</td>");
                        else
                        {
                            if (info.strAction == "read")
                                text.Append("<td class='operator'>"
                                    + HttpUtility.HtmlEncode(info.strOperator)
                                    + "</td>");
                            else
                                text.Append("<td class='operator'>"
        + "<div class='borrowoperator'>"
        + this.GetString("借")
        + ": " + HttpUtility.HtmlEncode(info.strBorrowOperator) + "</div>"
        + "<div class='returnoperator'>"
        + this.GetString("还")
        + ": " + HttpUtility.HtmlEncode(info.strOperator) + "</div>"
        + "</td>");
                        }

                        text.Append("</tr>");

                        PlaceHolder line = (PlaceHolder)this.FindControl("line" + Convert.ToString(i));
                        if (line == null)
                        {
                            PlaceHolder insertpoint = (PlaceHolder)this.FindControl("insertpoint");
                            PlaceHolder content = (PlaceHolder)this.FindControl("content");

                            line = this.NewContentLine(content, i, insertpoint);
                        }

                        LiteralControl contentcontrol = (LiteralControl)this.FindControl("line" + Convert.ToString(i) + "_content");
                        contentcontrol.Text = text.ToString();
                        i++;
                    } // end of for
                }

                this.LineCount = Math.Max(this.LineCount, this.PageMaxLines);
            }
            else
            {
                // 显示空行
                for (int i = 0; i < this.PageMaxLines; i++)
                {
                    PlaceHolder line = (PlaceHolder)this.FindControl("line" + Convert.ToString(i));
                    if (line == null)
                        continue;
                }
            }

            base.Render(writer);
        }