[PATCH] fdo#39053 writerfilter: implement RTF_BIN

Miklos Vajna vmiklos at suse.cz
Sun Apr 15 05:10:49 PDT 2012


Conflicts:

	writerfilter/source/rtftok/rtfdocumentimpl.cxx
	writerfilter/source/rtftok/rtftokenizer.cxx
---
 writerfilter/source/rtftok/rtfdocumentimpl.cxx |   64 +++++++++++++++++-------
 writerfilter/source/rtftok/rtfdocumentimpl.hxx |    4 ++
 writerfilter/source/rtftok/rtftokenizer.cxx    |    4 +-
 3 files changed, 52 insertions(+), 20 deletions(-)

diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 023b6c6..621288d 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -609,34 +609,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)
+            char ch = str[i];
+            if (ch != 0x0d && ch != 0x0a)
             {
-                aStream << (char)b;
-                count = 2;
-                b = 0;
+                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;
@@ -775,6 +783,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);
 
@@ -2784,6 +2805,10 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
                 lcl_putNestedSprm(m_aStates.top().aTableSprms, NS_ooxml::LN_CT_Lvl_rPr, NS_sprm::LN_CRgFtc0, pValue);
             }
             break;
+        case RTF_BIN:
+            m_aStates.top().nInternalState = INTERNAL_BIN;
+            m_aStates.top().nBinaryToRead = nParam;
+            break;
         default:
 #if OSL_DEBUG_LEVEL > 1
             OSL_TRACE("%s: TODO handle value '%s'", OSL_THIS_FUNC, lcl_RtfToString(nKeyword));
@@ -3601,6 +3626,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 0126882..1d0a37d 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -281,6 +281,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;
@@ -467,6 +469,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 8a0f155..8fa5992 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)
         {
-            OSL_TRACE("%s: TODO, binary internal state", OSL_THIS_FUNC);
+            ret = m_rImport.resolveChars(ch);
+            if (ret)
+                return ret;
         }
         else
         {
-- 
1.7.7


--ikeVEW9yuYc//A+q--


More information about the LibreOffice mailing list