# HG changeset patch
# User Michael Stahl <mst@openoffice.org>
# Date 1285079241 -7200
# Node ID 2dde3e8f45f8225f427986e93798cfc72fd69f47
# Parent  86d903d2218e6540cd86066b42dbf4fb30746b94
rtftok01: writerfilter: replace strings with tokens in rtftok

diff --git a/writerfilter/inc/rtftok/RTFScannerHandler.hxx b/writerfilter/inc/rtftok/RTFScannerHandler.hxx
--- a/writerfilter/inc/rtftok/RTFScannerHandler.hxx
+++ b/writerfilter/inc/rtftok/RTFScannerHandler.hxx
@@ -28,7 +28,7 @@
 #ifndef INCLUDED_RTFSCANNERHANDLER_HXX
 #define INCLUDED_RTFSCANNERHANDLER_HXX
 
-#include <sal/types.h>
+#include <rtftok/RTFTokens.hxx>
 
 namespace writerfilter { namespace rtftok {
 
@@ -36,8 +36,10 @@
 {
 public:
     virtual ~RTFScannerHandler() { }
-    virtual void dest(char const*const token, char const*const value) = 0;
-    virtual void ctrl(char const*const token, char const*const value) = 0;
+    virtual void unknown(char const*const token, char const*const value,
+                         bool const bStar) = 0;
+    virtual void dest(Token_t const token, char const*const value) = 0;
+    virtual void ctrl(Token_t const token, char const*const value) = 0;
     virtual void lbrace() = 0;
     virtual void rbrace() = 0;
     virtual void addSpaces(unsigned int const count) = 0;
diff --git a/writerfilter/source/rtftok/RTFDocumentImpl.cxx b/writerfilter/source/rtftok/RTFDocumentImpl.cxx
--- a/writerfilter/source/rtftok/RTFDocumentImpl.cxx
+++ b/writerfilter/source/rtftok/RTFDocumentImpl.cxx
@@ -259,14 +259,14 @@
     { }
     virtual ~RTFDestination() { }
 
-    virtual Pointer_t dest(char const*const token, char const*const /*value*/)
+    virtual Pointer_t dest(Token_t const token, char const*const /*value*/)
     {
-fprintf(stderr, "RTFDestination::dest: creating default context for %s\n", token);
+fprintf(stderr, "RTFDestination::dest: creating default context for \\%s\n", TokenToId(token));
         return Pointer_t(new RTFDestination(m_rHandler));
     }
-    virtual void ctrl(char const*const token, char const*const /*value*/)
+    virtual void ctrl(Token_t const token, char const*const /*value*/)
     {
-fprintf(stderr, "RTFDestination::ctrl: ignoring control %s\n", token);
+fprintf(stderr, "RTFDestination::ctrl: ignoring control: \\%s\n", TokenToId(token));
     }
     virtual void lbrace()
     {
@@ -364,7 +364,23 @@
         m_Groups.push( RTFGroup() ); // dummy group
     }
     virtual ~RTFScannerHandlerImpl() { }
-    virtual void dest(char const*const token, char const*const value)
+    virtual void unknown(char const*const token, char const*const value,
+                         bool const bStar)
+    {
+        m_NegativeCharacters = 0;
+        checkStrings();
+        if (bStar) { /* star flag: ignore entire destination! */
+            OSL_TRACE("RTFScannerHandlerImpl::unknown: "
+                    "creating default context for \\%s", token);
+            m_Groups.push( RTFGroup(m_Groups.top()) );
+            RTFDestination::Pointer_t const pDestination(
+                    new RTFDestination(*this));
+            m_Destinations.push(::std::make_pair(1, pDestination));
+        }
+        (void) value;
+        OSL_TRACE("RTFScannerHandlerImpl::unknown: ignoring: \\%s", token);
+    }
+    virtual void dest(Token_t const token, char const*const value)
     {
         m_NegativeCharacters = 0;
         checkStrings();
@@ -376,27 +392,35 @@
             m_Destinations.push(::std::make_pair(1, pDestination));
         }
     }
-    virtual void ctrl(char const*const token, char const*const value)
+    virtual void ctrl(Token_t const token, char const*const value)
     {
         m_NegativeCharacters = 0;
         checkStrings();
-        if (('u' == token[0]) && ('\0' == token[1]))
+        switch (token)
         {
-            sal_Int32 const v(::rtl::OString(value).toInt32());
+            case RTF_u:
+            {
+                sal_Int32 const v(::rtl::OString(value).toInt32());
 fprintf(stderr, "RTFScannerHandlerImpl::ctrl: \\u%d\n", v);
-            if ((SAL_MIN_INT16 <= v) && (v <= SAL_MAX_INT16)) {
-                RTFScannerHandlerImpl::addCharU(static_cast<sal_Unicode>(v));
+                if ((SAL_MIN_INT16 <= v) && (v <= SAL_MAX_INT16)) {
+                    RTFScannerHandlerImpl::addCharU(
+                        static_cast<sal_Unicode>(v));
+                }
             }
-        }
-        else if (('u' == token[0]) && ('c' == token[1]) && ('\0' == token[2]))
-        {
-            sal_Int32 const v(::rtl::OString(value).toInt32());
-            if ((0 <= v) && (v < SAL_MAX_UINT16)) {
-                SetUnicodeCharacters(v);
+            break;
+            case RTF_uc:
+            {
+                sal_Int32 const v(::rtl::OString(value).toInt32());
+                if ((0 <= v) && (v < SAL_MAX_UINT16)) {
+                    SetUnicodeCharacters(v);
+                }
             }
-        }
-        else {
-            m_Destinations.top().second->ctrl(token, value);
+            break;
+            default:
+            {
+                m_Destinations.top().second->ctrl(token, value);
+            }
+            break;
         }
     }
     virtual void lbrace()
@@ -620,29 +644,43 @@
     { }
     virtual ~RTFDestinationFontTable() { }
 
-    virtual void ctrl(char const*const token, char const*const value)
+    virtual void ctrl(Token_t const token, char const*const value)
     {
         if (2 <= m_Level) {// nested group
-            if (!strcasecmp(token, "f")) {
-                m_Entry.m_Index = ::rtl::OString(value).toInt32();
+            switch (token)
+            {
+                case RTF_f:
+                {
+                    m_Entry.m_Index = ::rtl::OString(value).toInt32();
 fprintf(stderr, "read: \\f with: %d\n", m_Entry.m_Index);
-            }
-            else if (!strcasecmp(token, "fcharset")) {
-                sal_Int32 const n( ::rtl::OString(value).toInt32() );
-                sal_uInt32 cp(lcl_CharsetToCodePage(n));
-                if (0 == cp) {
-                    m_Entry.m_Encoding = m_DefaultEncoding;
-                } else {
+                }
+                break;
+                case RTF_fcharset:
+                {
+                    sal_Int32 const n( ::rtl::OString(value).toInt32() );
+                    sal_uInt32 cp(lcl_CharsetToCodePage(n));
+                    if (0 == cp) {
+                        m_Entry.m_Encoding = m_DefaultEncoding;
+                    } else {
+                        rtl_TextEncoding const e(
+                            rtl_getTextEncodingFromWindowsCodePage(cp));
+                        m_Entry.m_Encoding = e;
+                    }
+                }
+                break;
+                case RTF_cpg:
+                {
+                    sal_Int32 const n( ::rtl::OString(value).toInt32() );
                     rtl_TextEncoding const e(
-                        rtl_getTextEncodingFromWindowsCodePage(cp));
+                        rtl_getTextEncodingFromWindowsCodePage(n));
                     m_Entry.m_Encoding = e;
                 }
-            }
-            else if (!strcasecmp(token, "cpg")) {
-                sal_Int32 const n( ::rtl::OString(value).toInt32() );
-                rtl_TextEncoding const e(
-                    rtl_getTextEncodingFromWindowsCodePage(n));
-                m_Entry.m_Encoding = e;
+                break;
+                default:
+                {
+fprintf(stderr, "RTFDestinationFontTable::ctrl: ignoring control: \\%s\n", TokenToId(token));
+                }
+                break;
             }
         }
     }
@@ -728,58 +766,90 @@
     { }
     virtual ~RTFDestinationRTF() { }
 
-    virtual Pointer_t dest(char const*const token, char const*const value)
+    virtual Pointer_t dest(Token_t const token, char const*const value)
     {
-        if (!strcasecmp(token, "fonttbl")) {
+        switch (token)
+        {
+            case RTF_fonttbl:
+            {
 fprintf(stderr, "create RTFDestinationFontTable\n");
-            return Pointer_t(new RTFDestinationFontTable(GetHandler()));
-        }
-        return RTFDestination::dest(token, value);
-    }
-    virtual void ctrl(char const*const token, char const*const value)
-    {
-        if (!strcasecmp(token, "rtf")) {
-            if (!strcmp(value, "1")) {
-                OSL_TRACE("RTFDestinationRTF: warning: \\rtf version not 1 ?");
+                return Pointer_t(new RTFDestinationFontTable(GetHandler()));
+            }
+            default:
+            {
+                return RTFDestination::dest(token, value);
             }
         }
-        else if (!strcasecmp(token, "pwd")) {
-            if (!strcmp(value, "1")) {
-                OSL_TRACE("RTFDestinationRTF: warning: \\pwd version not 1 ?");
+    }
+    virtual void ctrl(Token_t const token, char const*const value)
+    {
+        switch (token)
+        {
+            /* it is not clear whether \pwd and \urtf are destinations or
+               controls, so implement both... */
+            case RTF_pwd:
+            {
+                if (strcmp(value, "1")) {
+                    OSL_TRACE(
+                        "RTFDestinationRTF: warning: \\pwd version not 1 ?");
+                }
             }
+            break;
+            case RTF_urtf:
+            {
+                if (strcmp(value, "1")) {
+                    OSL_TRACE(
+                        "RTFDestinationRTF: warning: \\urtf version not 1 ?");
+                }
+                GetHandler().SetEncoding(RTL_TEXTENCODING_UTF8);
+            }
+            break;
+            case RTF_ansi:
+            {
+                GetHandler().SetEncoding(RTL_TEXTENCODING_MS_1252);
+            }
+            break;
+            case RTF_mac:
+            {
+                GetHandler().SetEncoding(RTL_TEXTENCODING_APPLE_ROMAN);
+            }
+            break;
+            case RTF_pc:
+            {
+                GetHandler().SetEncoding(RTL_TEXTENCODING_IBM_437);
+            }
+            break;
+            case RTF_pca:
+            {
+                GetHandler().SetEncoding(RTL_TEXTENCODING_IBM_850);
+            }
+            break;
+            case RTF_ansicpg:
+            {
+                sal_Int32 const n( ::rtl::OString(value).toInt32() );
+                rtl_TextEncoding const e(
+                    rtl_getTextEncodingFromWindowsCodePage(n));
+                GetHandler().SetEncoding(e);
+            }
+            break;
+            case RTF_par:
+            {
+                sal_uInt8 const nl(0x0d);
+                GetHandler().GetStream().text(& nl, sizeof(nl));
+            }
+            break;
+            case RTF_f:
+            {
+                sal_Int32 const n( ::rtl::OString(value).toInt32() );
+                GetHandler().SetEncodingToFont(n);
+            }
+            break;
+            default:
+            {
+fprintf(stderr, "RTFDestinationRTF::ctrl: ignoring control: \\%s\n", TokenToId(token));
+            }
+            break;
         }
-        else if (!strcasecmp(token, "urtf")) {
-            if (!strcmp(value, "1")) {
-                OSL_TRACE("RTFDestinationRTF: warning: \\urtf version not 1 ?");
-            }
-            GetHandler().SetEncoding(RTL_TEXTENCODING_UTF8);
-        }
-        else if (!strcasecmp(token, "ansi")) {
-            GetHandler().SetEncoding(RTL_TEXTENCODING_MS_1252);
-        }
-        else if (!strcasecmp(token, "mac")) {
-            GetHandler().SetEncoding(RTL_TEXTENCODING_APPLE_ROMAN);
-        }
-        else if (!strcasecmp(token, "pc")) {
-            GetHandler().SetEncoding(RTL_TEXTENCODING_IBM_437);
-        }
-        else if (!strcasecmp(token, "pca")) {
-            GetHandler().SetEncoding(RTL_TEXTENCODING_IBM_850);
-        }
-        else if (!strcasecmp(token, "ansicpg")) {
-            sal_Int32 const n( ::rtl::OString(value).toInt32() );
-            rtl_TextEncoding const e(rtl_getTextEncodingFromWindowsCodePage(n));
-            GetHandler().SetEncoding(e);
-        }
-        else if (!strcasecmp(token, "par")) {
-            sal_uInt8 const nl(0x0d);
-            GetHandler().GetStream().text(& nl, sizeof(nl));
-        }
-        else if (!strcasecmp(token, "f")) {
-            sal_Int32 const n( ::rtl::OString(value).toInt32() );
-            GetHandler().SetEncodingToFont(n);
-        }
-else fprintf(stderr, "RTFDestinationRTF::ctrl: ignoring control %s\n", token);
     }
 #if 0
     virtual Pointer_t lbrace()
@@ -817,11 +887,27 @@
     { }
     virtual ~RTFDestinationRoot() { }
 
-    virtual Pointer_t dest(char const*const token, char const*const value)
+    virtual Pointer_t dest(Token_t const token, char const*const value)
     {
-        if (!strcasecmp(token, "rtf")) {
+        switch (token)
+        {
+            /* it is not clear whether \pwd and \urtf are destinations or
+               controls, so implement both... */
+            case RTF_urtf:
+            {
+                GetHandler().SetEncoding(RTL_TEXTENCODING_UTF8);
+                // FALLTHROUGH
+            }
+            case RTF_pwd:
+            case RTF_rtf:
+            {
+                if (strcmp(value, "1")) {
+                    OSL_TRACE("RTFDestinationRoot: warning: "
+                        "\\%s version not 1 ?", TokenToId(token));
+                }
 fprintf(stderr, "create RTFDestinationRTF\n");
-            return Pointer_t(new RTFDestinationRTF(GetHandler()));
+                return Pointer_t(new RTFDestinationRTF(GetHandler()));
+            }
         }
         return RTFDestination::dest(token, value);
     }
diff --git a/writerfilter/source/rtftok/RTFScanner.lex b/writerfilter/source/rtftok/RTFScanner.lex
--- a/writerfilter/source/rtftok/RTFScanner.lex
+++ b/writerfilter/source/rtftok/RTFScanner.lex
@@ -43,6 +43,7 @@
 
 #include <rtftok/RTFInputSource.hxx>
 #include <rtftok/RTFScannerHandler.hxx>
+#include <rtftok/gperffasttoken.hxx>
 
 #include <com/sun/star/uno/Any.hxx>
 
@@ -94,7 +95,7 @@
     o_rpTarget[end - start] = '\0';
 }
 
-static void
+static writerfilter::rtftok::Token_t
 split_token_value(
     char const*const yytext_, char *& o_rpToken, char *& o_rpValue)
 {
@@ -106,10 +107,13 @@
     { i++; }
     size_t start = i;
     while (yytext_[i] != 0 && yytext_[i] >= 'A') { i++; }
+    writerfilter::rtftok::Token_t const ret(
+        writerfilter::rtftok::tokenmap::GetToken(& yytext_[start], i - start) );
     make_string(yytext_, start, i, o_rpToken);
     start = i;
     while (yytext_[i] !=0 && yytext_[i] > ' ') { i++; }
     make_string(yytext_, start, i, o_rpValue);
+    return ret;
 }
 
 static void
@@ -117,9 +121,12 @@
 {
     char * pToken(0);
     char * pValue(0);
-    split_token_value(yytext_, pToken, pValue);
-    if (pToken && pValue) {
-        rHandler.ctrl(pToken, pValue);
+    writerfilter::rtftok::Token_t const token(
+        split_token_value(yytext_, pToken, pValue) );
+    if (pToken && pValue && (writerfilter::rtftok::RTF_TOKENS_END != token)) {
+        rHandler.ctrl(token, pValue);
+    } else {
+        rHandler.unknown(pToken, pValue, false);
     }
     delete[] pToken;
     delete[] pValue;
@@ -130,9 +137,12 @@
 {
     char * pToken(0);
     char * pValue(0);
-    split_token_value(yytext_, pToken, pValue);
-    if (pToken && pValue) {
-        rHandler.dest(pToken, pValue);
+    writerfilter::rtftok::Token_t const token(
+        split_token_value(yytext_, pToken, pValue) );
+    if (pToken && pValue && (writerfilter::rtftok::RTF_TOKENS_END != token)) {
+        rHandler.dest(token, pValue);
+    } else {
+        rHandler.unknown(pToken, pValue, true);
     }
     delete[] pToken;
     delete[] pValue;
@@ -294,17 +304,21 @@
 {
     char * pToken(0);
     char * pValue(0);
-    split_token_value(yytext_, pToken, pValue);
-    if (pToken && pValue) {
+    writerfilter::rtftok::Token_t const token(
+        split_token_value(yytext_, pToken, pValue) );
+    if (pToken && pValue && (writerfilter::rtftok::RTF_TOKENS_END != token)) {
         bool const bFound( ::std::binary_search(
             &g_destctrls[0], &g_destctrls[NUM_OF_DESTCTRLS], pToken,
             case_compare()) );
         if (bFound) {
-            rHandler.dest(pToken, pValue);
+            rHandler.dest(token, pValue);
         } else {
             rHandler.lbrace();
-            rHandler.ctrl(pToken, pValue);
+            rHandler.ctrl(token, pValue);
         }
+    } else {
+        rHandler.lbrace();
+        rHandler.unknown(pToken, pValue, false);
     }
     delete[] pToken;
     delete[] pValue;
