xref: /aoo4110/main/oox/inc/oox/xls/formulaparser.hxx (revision b1cdbd2c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef OOX_XLS_FORMULAPARSER_HXX
25 #define OOX_XLS_FORMULAPARSER_HXX
26 
27 #include "oox/xls/formulabase.hxx"
28 
29 namespace oox {
30 namespace xls {
31 
32 // formula finalizer ==========================================================
33 
34 /** A generic formula token array finalizer.
35 
36     After building a formula token array from alien binary file formats, or
37     parsing an XML formula string using the com.sun.star.sheet.FormulaParser
38     service, the token array is still not ready to be put into the spreadsheet
39     document. There may be functions with a wrong number of parameters (missing
40     but required parameters, or unsupported parameters) or intermediate tokens
41     used to encode references to macro functions or add-in functions. This
42     helper processes a passed token array and builds a new compatible token
43     array.
44 
45     Derived classes may add more functionality by overwriting the virtual
46     functions.
47  */
48 class FormulaFinalizer : public OpCodeProvider, protected ApiOpCodes
49 {
50 public:
51     explicit            FormulaFinalizer( const OpCodeProvider& rOpCodeProv );
52 
53     /** Finalizes and returns the passed token array. */
54     ApiTokenSequence    finalizeTokenArray( const ApiTokenSequence& rTokens );
55 
56 protected:
57     /** Derived classed may try to find a function info struct from the passed
58         string extracted from an OPCODE_BAD token.
59 
60         @param rTokenData  The string that has been found in an OPCODE_BAD
61             token preceding the function parentheses.
62      */
63     virtual const FunctionInfo* resolveBadFuncName( const ::rtl::OUString& rTokenData ) const;
64 
65     /** Derived classed may try to find the name of a defined name with the
66         passed index extracted from an OPCODE_NAME token.
67 
68         @param nTokenIndex  The index of the defined name that has been found
69             in an OPCODE_NAME token preceding the function parentheses.
70      */
71     virtual ::rtl::OUString resolveDefinedName( sal_Int32 nTokenIndex ) const;
72 
73 private:
74     typedef ::std::vector< const ApiToken* > ParameterPosVector;
75 
76     const FunctionInfo* getFunctionInfo( ApiToken& orFuncToken );
77     const FunctionInfo* getExternCallInfo( ApiToken& orFuncToken, const ApiToken& rECToken );
78 
79     void                processTokens( const ApiToken* pToken, const ApiToken* pTokenEnd );
80     const ApiToken*     processParameters( const FunctionInfo& rFuncInfo, const ApiToken* pToken, const ApiToken* pTokenEnd );
81 
82     bool                isEmptyParameter( const ApiToken* pToken, const ApiToken* pTokenEnd ) const;
83     const ApiToken*     getSingleToken( const ApiToken* pToken, const ApiToken* pTokenEnd ) const;
84     const ApiToken*     skipParentheses( const ApiToken* pToken, const ApiToken* pTokenEnd ) const;
85     const ApiToken*     findParameters( ParameterPosVector& rParams, const ApiToken* pToken, const ApiToken* pTokenEnd ) const;
86     void                appendEmptyParameter( const FunctionInfo& rFuncInfo, size_t nParam );
87     void                appendCalcOnlyParameter( const FunctionInfo& rFuncInfo, size_t nParam );
88     void                appendRequiredParameters( const FunctionInfo& rFuncInfo, size_t nParamCount );
89 
90     bool                appendFinalToken( const ApiToken& rToken );
91 
92 private:
93     ApiTokenVector      maTokens;
94 };
95 
96 // ============================================================================
97 
98 class FormulaParserImpl;
99 
100 /** Import formula parser for OOXML and BIFF filters.
101 
102     This class implements formula import for the OOXML and BIFF filter. One
103     instance is contained in the global filter data to prevent construction and
104     destruction of internal buffers for every imported formula.
105  */
106 class FormulaParser : public FormulaProcessorBase
107 {
108 public:
109     explicit            FormulaParser( const WorkbookHelper& rHelper );
110     virtual             ~FormulaParser();
111 
112     /** Converts an OOXML formula string. */
113     ApiTokenSequence    importFormula(
114                             const ::com::sun::star::table::CellAddress& rBaseAddr,
115                             const ::rtl::OUString& rFormulaString ) const;
116 
117     /** Imports and converts a BIFF12 token array from the passed stream. */
118     ApiTokenSequence    importFormula(
119                             const ::com::sun::star::table::CellAddress& rBaseAddr,
120                             FormulaType eType,
121                             SequenceInputStream& rStrm ) const;
122 
123     /** Imports and converts a BIFF2-BIFF8 token array from the passed stream.
124         @param pnFmlaSize  Size of the token array. If null is passed, reads
125         it from stream (1 byte in BIFF2, 2 bytes otherwise) first. */
126     ApiTokenSequence    importFormula(
127                             const ::com::sun::star::table::CellAddress& rBaseAddr,
128                             FormulaType eType,
129                             BiffInputStream& rStrm,
130                             const sal_uInt16* pnFmlaSize = 0 ) const;
131 
132     /** Converts the passed Boolean value to a similar formula. */
133     ApiTokenSequence    convertBoolToFormula( bool bValue ) const;
134 
135     /** Converts the passed BIFF error code to a similar formula. */
136     ApiTokenSequence    convertErrorToFormula( sal_uInt8 nErrorCode ) const;
137 
138     /** Converts the passed token index of a defined name to a formula calling that name. */
139     ApiTokenSequence    convertNameToFormula( sal_Int32 nTokenIndex ) const;
140 
141     /** Converts the passed number into a HYPERLINK formula with the passed URL. */
142     ApiTokenSequence    convertNumberToHyperlink( const ::rtl::OUString& rUrl, double fValue ) const;
143 
144     /** Converts the passed XML formula to an OLE link target. */
145     ::rtl::OUString     importOleTargetLink( const ::rtl::OUString& rFormulaString );
146 
147     /** Imports and converts an OLE link target from the passed stream. */
148     ::rtl::OUString     importOleTargetLink( SequenceInputStream& rStrm );
149 
150     /** Imports and converts an OLE link target from the passed stream. */
151     ::rtl::OUString     importOleTargetLink( BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize = 0 ) const;
152 
153     /** Converts the passed formula to a macro name for a drawing shape. */
154     ::rtl::OUString     importMacroName( const ::rtl::OUString& rFormulaString );
155 
156 private:
157     ::std::auto_ptr< FormulaParserImpl > mxImpl;
158 };
159 
160 // ============================================================================
161 
162 } // namespace xls
163 } // namespace oox
164 
165 #endif
166