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