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