diff options
author | Miklos Vajna <vmiklos@suse.cz> | 2012-04-15 14:10:49 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@suse.cz> | 2012-04-15 14:40:38 +0200 |
commit | 5187174cd4054486100ef29125ee4a36f7e3bee3 (patch) | |
tree | 58347aebcf9ecb57623ffa2638e8e9e6d05884a7 | |
parent | 1d256da4dcbeb623c146e197bc20d3583d9bb3b8 (diff) |
fdo#39053 writerfilter: implement RTF_BIN
-rw-r--r-- | writerfilter/source/rtftok/rtfdocumentimpl.cxx | 66 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfdocumentimpl.hxx | 4 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtftokenizer.cxx | 4 |
3 files changed, 53 insertions, 21 deletions
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index e00458d6d2db..54fdac204482 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -574,34 +574,42 @@ void RTFDocumentImpl::resolve(Stream & rMapper) int RTFDocumentImpl::resolvePict(bool bInline) { SvMemoryStream aStream; - int b = 0, count = 2; + SvStream *pStream = 0; - // Feed the destination text to a stream. - OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US); - const char *str = aStr.getStr(); - for (int i = 0; i < aStr.getLength(); ++i) + if (!m_pBinaryData.get()) { - char ch = str[i]; - if (ch != 0x0d && ch != 0x0a) + pStream = &aStream; + int b = 0, count = 2; + + // Feed the destination text to a stream. + OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US); + const char *str = aStr.getStr(); + for (int i = 0; i < aStr.getLength(); ++i) { - b = b << 4; - sal_Int8 parsed = m_pTokenizer->asHex(ch); - if (parsed == -1) - return ERROR_HEX_INVALID; - b += parsed; - count--; - if (!count) - { - aStream << (char)b; - count = 2; - b = 0; + char ch = str[i]; + if (ch != 0x0d && ch != 0x0a) + { + b = b << 4; + sal_Int8 parsed = m_pTokenizer->asHex(ch); + if (parsed == -1) + return ERROR_HEX_INVALID; + b += parsed; + count--; + if (!count) + { + aStream << (char)b; + count = 2; + b = 0; + } } } } + else + pStream = m_pBinaryData.get(); // Store, and get its URL. - aStream.Seek(0); - uno::Reference<io::XInputStream> xInputStream(new utl::OInputStreamWrapper(&aStream)); + pStream->Seek(0); + uno::Reference<io::XInputStream> xInputStream(new utl::OInputStreamWrapper(pStream)); WMF_EXTERNALHEADER aExtHeader; aExtHeader.mapMode = m_aStates.top().aPicture.eWMetafile; aExtHeader.xExt = m_aStates.top().aPicture.nWidth; @@ -736,6 +744,19 @@ int RTFDocumentImpl::resolvePict(bool bInline) int RTFDocumentImpl::resolveChars(char ch) { + if (m_aStates.top().nInternalState == INTERNAL_BIN) + { + m_pBinaryData.reset(new SvMemoryStream()); + *m_pBinaryData << ch; + for (int i = 0; i < m_aStates.top().nBinaryToRead - 1; ++i) + { + Strm() >> ch; + *m_pBinaryData << ch; + } + m_aStates.top().nInternalState = INTERNAL_NORMAL; + return 0; + } + if (m_aStates.top().nInternalState != INTERNAL_HEX) checkUnicode(false, true); @@ -2758,6 +2779,10 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) case RTF_VIEWSCALE: m_aSettingsTableAttributes->push_back(make_pair(NS_ooxml::LN_CT_Zoom_percent, pIntValue)); break; + case RTF_BIN: + m_aStates.top().nInternalState = INTERNAL_BIN; + m_aStates.top().nBinaryToRead = nParam; + break; default: SAL_INFO("writerfilter", OSL_THIS_FUNC << ": TODO handle value '" << lcl_RtfToString(nKeyword) << "'"); aSkip.setParsed(false); @@ -3545,6 +3570,7 @@ RTFParserState::RTFParserState(RTFDocumentImpl *pDocumentImpl) nCurrentEncoding(0), nUc(1), nCharsToSkip(0), + nBinaryToRead(0), nListLevelNum(0), aListLevelEntries(), aLevelNumbers(), diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx index 898fb57fe3f4..81f05c395999 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx @@ -280,6 +280,8 @@ namespace writerfilter { int nUc; /// Characters to skip, set to nUc by \u. int nCharsToSkip; + /// Characters to read, once in binary mode. + int nBinaryToRead; /// Next list level index to use when parsing list table. int nListLevelNum; @@ -466,6 +468,8 @@ namespace writerfilter { bool m_bObject; /// Contents of the objdata group. boost::shared_ptr<SvStream> m_pObjectData; + /// If the data for a picture is a binary one, it's stored here. + boost::shared_ptr<SvStream> m_pBinaryData; RTFReferenceTable::Entries_t m_aFontTableEntries; int m_nCurrentFontIndex; diff --git a/writerfilter/source/rtftok/rtftokenizer.cxx b/writerfilter/source/rtftok/rtftokenizer.cxx index 125319e6deeb..f247317789ad 100644 --- a/writerfilter/source/rtftok/rtftokenizer.cxx +++ b/writerfilter/source/rtftok/rtftokenizer.cxx @@ -95,7 +95,9 @@ int RTFTokenizer::resolveParse() return ERROR_GROUP_UNDER; if (!m_rImport.isEmpty() && m_rImport.getState().nInternalState == INTERNAL_BIN) { - SAL_INFO("writerfilter", OSL_THIS_FUNC << ": TODO, binary internal state"); + ret = m_rImport.resolveChars(ch); + if (ret) + return ret; } else { |