mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-15 17:55:30 +08:00
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@52221 954022d7-b5bf-4e40-9824-e11837661b57
This commit is contained in:
committed by
Alexander Trofimov
parent
7299b44189
commit
3779f31d9e
312
ASCOfficeHtmlFile/SDK/HTMLReader/LiteHTMLReader.cpp
Normal file
312
ASCOfficeHtmlFile/SDK/HTMLReader/LiteHTMLReader.cpp
Normal file
@ -0,0 +1,312 @@
|
||||
/**
|
||||
* PROJECT - HTML Reader Class Library
|
||||
*
|
||||
* LiteHTMLReader.cpp - CLiteHTMLReader implementation
|
||||
*
|
||||
* Written By Gurmeet S. Kochar <gomzygotit@hotmail.com>
|
||||
* Copyright (c) 2004. All rights reserved.
|
||||
*
|
||||
* This code may be used in compiled form in any way you desire
|
||||
* (including commercial use). The code may be redistributed
|
||||
* unmodified by any means PROVIDING it is not sold for profit
|
||||
* without the authors written consent, and providing that this
|
||||
* notice and the authors name and all copyright notices remains
|
||||
* intact. However, this file and the accompanying source code may
|
||||
* not be hosted on a website or bulletin board without the authors
|
||||
* written permission.
|
||||
*
|
||||
* This file is provided "AS IS" with no expressed or implied warranty.
|
||||
* The author accepts no liability for any damage/loss of business that
|
||||
* this product may cause.
|
||||
*
|
||||
* Although it is not necessary, but if you use this code in any of
|
||||
* your application (commercial or non-commercial), please INFORM me
|
||||
* so that I may know how useful this library is. This will encourage
|
||||
* me to keep updating it.
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "LiteHTMLReader.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
# define new DEBUG_NEW
|
||||
# undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif // _DEBUG
|
||||
|
||||
#ifndef __LITEHTMLENTITYRESOLVER_H__
|
||||
# include "LiteHTMLEntityResolver.h"
|
||||
#endif // !__LITEHTMLENTITYRESOLVER_H__
|
||||
|
||||
#pragma warning(push, 4)
|
||||
UINT CLiteHTMLReader::parseDocument(void)
|
||||
{
|
||||
ASSERT(m_lpszBuffer != NULL);
|
||||
|
||||
bool bAbort = false; // continue parsing or abort?
|
||||
bool bIsClosingTag = false; // tag parsed is a closing tag?
|
||||
bool bIsOpeningTag = false; // tag parsed is an opening tag?
|
||||
CString strCharacters; // character data
|
||||
CString strComment; // comment data
|
||||
CString strT; // temporary storage
|
||||
DWORD dwCharDataStart = 0L; // starting position of character data
|
||||
DWORD dwCharDataLen = 0L; // length of character data
|
||||
LONG lTemp = 0L; // temporary storage
|
||||
TCHAR ch = 0; // character at current buffer position
|
||||
CLiteHTMLTag oTag; // tag information
|
||||
|
||||
if ( (!m_lpszBuffer) || (!m_dwBufLen) )
|
||||
return (0U);
|
||||
|
||||
// reset seek pointer to beginning
|
||||
ResetSeekPointer();
|
||||
|
||||
// notify event handler about parsing startup
|
||||
if (getEventNotify(notifyStartStop))
|
||||
{
|
||||
bAbort = false;
|
||||
m_pEventHandler->BeginParse(m_dwAppData, bAbort);
|
||||
if (bAbort) goto LEndParse;
|
||||
}
|
||||
|
||||
// skip leading white-space characters
|
||||
while (isWhiteSpace(ReadChar()))
|
||||
;
|
||||
|
||||
ch = UngetChar();
|
||||
while ((ch = ReadChar()) != NULL)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
|
||||
// tag starting delimeter?
|
||||
case _T('<'):
|
||||
{
|
||||
UngetChar();
|
||||
|
||||
strComment.Empty();
|
||||
if (!parseComment(strComment))
|
||||
{
|
||||
bIsOpeningTag = false;
|
||||
bIsClosingTag = false;
|
||||
if (!parseTag(oTag, bIsOpeningTag, bIsClosingTag))
|
||||
{
|
||||
++dwCharDataLen;
|
||||
|
||||
// manually advance buffer position
|
||||
// because the last call to UngetChar()
|
||||
// moved it back one character
|
||||
ch = ReadChar();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// clear pending notifications
|
||||
if ( (dwCharDataLen) || (strCharacters.GetLength()) )
|
||||
{
|
||||
strCharacters += CString(&m_lpszBuffer[dwCharDataStart], dwCharDataLen);
|
||||
NormalizeCharacters(strCharacters);
|
||||
|
||||
if ( (strCharacters.GetLength()) &&
|
||||
(getEventNotify(notifyCharacters)) )
|
||||
{
|
||||
bAbort = false;
|
||||
m_pEventHandler->Characters(strCharacters, m_dwAppData, bAbort);
|
||||
if (bAbort) goto LEndParse;
|
||||
}
|
||||
|
||||
strCharacters.Empty();
|
||||
}
|
||||
|
||||
dwCharDataLen = 0L;
|
||||
dwCharDataStart = m_dwBufPos;
|
||||
|
||||
if (strComment.GetLength())
|
||||
{
|
||||
if (getEventNotify(notifyComment))
|
||||
{
|
||||
bAbort = false;
|
||||
m_pEventHandler->Comment(strComment, m_dwAppData, bAbort);
|
||||
if (bAbort) goto LEndParse;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (bIsOpeningTag) && (getEventNotify(notifyTagStart)) )
|
||||
{
|
||||
bAbort = false;
|
||||
m_pEventHandler->StartTag(&oTag, m_dwAppData, bAbort);
|
||||
if (bAbort) goto LEndParse;
|
||||
}
|
||||
|
||||
if ( (bIsClosingTag) && (getEventNotify(notifyTagEnd)) )
|
||||
{
|
||||
bAbort = false;
|
||||
m_pEventHandler->EndTag(&oTag, m_dwAppData, bAbort);
|
||||
if (bAbort) goto LEndParse;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// entity reference beginning delimeter?
|
||||
case _T('&'):
|
||||
{
|
||||
UngetChar();
|
||||
|
||||
lTemp = 0;
|
||||
if (m_bResolveEntities)
|
||||
lTemp = CLiteHTMLEntityResolver::resolveEntity(&m_lpszBuffer[m_dwBufPos], ch);
|
||||
|
||||
if (lTemp)
|
||||
{
|
||||
strCharacters += CString(&m_lpszBuffer[dwCharDataStart], dwCharDataLen) + ch;
|
||||
m_dwBufPos += lTemp;
|
||||
dwCharDataStart = m_dwBufPos;
|
||||
dwCharDataLen = 0L;
|
||||
}
|
||||
else
|
||||
{
|
||||
ch = ReadChar();
|
||||
++dwCharDataLen;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// any other character
|
||||
default:
|
||||
{
|
||||
++dwCharDataLen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clear pending notifications
|
||||
if ( (dwCharDataLen) || (strCharacters.GetLength()) )
|
||||
{
|
||||
strCharacters += CString(&m_lpszBuffer[dwCharDataStart], dwCharDataLen) + ch;
|
||||
NormalizeCharacters(strCharacters);
|
||||
strCharacters.TrimRight(); // explicit trailing white-space removal
|
||||
|
||||
if ( (strCharacters.GetLength()) &&
|
||||
(getEventNotify(notifyCharacters)) )
|
||||
{
|
||||
bAbort = false;
|
||||
m_pEventHandler->Characters(strCharacters, m_dwAppData, bAbort);
|
||||
if (bAbort) goto LEndParse;
|
||||
}
|
||||
}
|
||||
|
||||
LEndParse:
|
||||
// notify event handler about parsing completion
|
||||
if (getEventNotify(notifyStartStop))
|
||||
m_pEventHandler->EndParse(m_dwAppData, bAbort);
|
||||
|
||||
m_lpszBuffer = NULL;
|
||||
m_dwBufLen = 0L;
|
||||
return (m_dwBufPos);
|
||||
}
|
||||
|
||||
/**
|
||||
* CLiteHTMLReader::Read
|
||||
* The Read method parses an HTML document from an
|
||||
* in-memory string buffer and raises events defined
|
||||
* in ILiteHTMLReaderEvents to notify about variours
|
||||
* elements.
|
||||
*
|
||||
* @param lpszString - string containing HTML text to parse
|
||||
*
|
||||
* @return number of TCHARs successfully parsed
|
||||
* @since 1.0
|
||||
* @author Gurmeet S. Kochar
|
||||
*/
|
||||
UINT CLiteHTMLReader::Read(LPCTSTR lpszString)
|
||||
{
|
||||
ASSERT(AfxIsValidString(lpszString));
|
||||
|
||||
m_dwBufLen = ::_tcslen(lpszString);
|
||||
if (m_dwBufLen)
|
||||
{
|
||||
m_lpszBuffer = lpszString;
|
||||
return (parseDocument());
|
||||
}
|
||||
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/**
|
||||
* CLiteHTMLReader::Read
|
||||
* This method is similar to the Read(LPCTSTR) method,
|
||||
* except that, it accepts a file HANDLE instead of
|
||||
* an in-memory string buffer containing HTML text.
|
||||
*
|
||||
* @param hFile - file handle
|
||||
*
|
||||
* @return number of TCHARs successfully parsed
|
||||
* @since 1.0
|
||||
* @author Gurmeet S. Kochar
|
||||
*/
|
||||
UINT CLiteHTMLReader::ReadFile(HANDLE hFile)
|
||||
{
|
||||
ASSERT(hFile != INVALID_HANDLE_VALUE);
|
||||
ASSERT(::GetFileType(hFile) == FILE_TYPE_DISK);
|
||||
|
||||
HANDLE hFileMap;
|
||||
LPCTSTR lpsz;
|
||||
UINT nRetVal;
|
||||
|
||||
// determine file size
|
||||
m_dwBufLen = ::GetFileSize(hFile, NULL);
|
||||
if (m_dwBufLen == INVALID_FILE_SIZE)
|
||||
{
|
||||
TRACE1("(Error) CLiteHTMLReader::Read:"
|
||||
" GetFileSize() failed;"
|
||||
" GetLastError() returns 0x%08x.\n", ::GetLastError());
|
||||
goto LError;
|
||||
}
|
||||
|
||||
// calculate length, in TCHARs, of the buffer
|
||||
m_dwBufLen /= sizeof(TCHAR);
|
||||
if (!m_dwBufLen)
|
||||
return (0U);
|
||||
|
||||
// create a file-mapping object for the file
|
||||
hFileMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY, 0L, 0L, NULL);
|
||||
if (hFileMap == NULL)
|
||||
{
|
||||
TRACE1("(Error) CLiteHTMLReader::Read:"
|
||||
" CreateFileMapping() failed;"
|
||||
" GetLastError() returns 0x%08x.\n", ::GetLastError());
|
||||
goto LError;
|
||||
}
|
||||
|
||||
// map the entire file into the address-space of the application
|
||||
lpsz = (LPCTSTR)::MapViewOfFile(hFileMap, FILE_MAP_READ, 0L, 0L, 0L);
|
||||
if (lpsz == NULL)
|
||||
{
|
||||
TRACE1("(Error) CLiteHTMLReader::Read:"
|
||||
" MapViewOfFile() failed;"
|
||||
" GetLastError() returns 0x%08x.\n", ::GetLastError());
|
||||
goto LError;
|
||||
}
|
||||
|
||||
m_lpszBuffer = lpsz;
|
||||
nRetVal = parseDocument();
|
||||
goto LCleanExit;
|
||||
|
||||
LError:
|
||||
nRetVal = 0U;
|
||||
m_dwBufLen = 0L;
|
||||
|
||||
LCleanExit:
|
||||
if (lpsz != NULL)
|
||||
VERIFY(::UnmapViewOfFile(lpsz));
|
||||
if (hFileMap)
|
||||
VERIFY(::CloseHandle(hFileMap));
|
||||
return (nRetVal);
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
Reference in New Issue
Block a user