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 #include "oox/xls/excelhandlers.hxx" 25 26 #include "oox/core/filterbase.hxx" 27 #include "oox/xls/biffinputstream.hxx" 28 29 namespace oox { 30 namespace xls { 31 32 // ============================================================================ 33 34 using ::oox::core::FilterBase; 35 using ::oox::core::FragmentHandler2; 36 using ::rtl::OUString; 37 38 // ============================================================================ 39 // ============================================================================ 40 41 WorkbookFragmentBase::WorkbookFragmentBase( 42 const WorkbookHelper& rHelper, const OUString& rFragmentPath ) : 43 FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ), 44 WorkbookHelper( rHelper ) 45 { 46 } 47 48 // ============================================================================ 49 50 WorksheetFragmentBase::WorksheetFragmentBase( 51 const WorksheetHelper& rHelper, const OUString& rFragmentPath ) : 52 FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ), 53 WorksheetHelper( rHelper ) 54 { 55 } 56 57 // ============================================================================ 58 // ============================================================================ 59 60 BiffContextHandler::~BiffContextHandler() 61 { 62 } 63 64 // ---------------------------------------------------------------------------- 65 66 BiffWorkbookContextBase::BiffWorkbookContextBase( const WorkbookHelper& rHelper ) : 67 WorkbookHelper( rHelper ) 68 { 69 } 70 71 // ---------------------------------------------------------------------------- 72 73 BiffWorksheetContextBase::BiffWorksheetContextBase( const WorksheetHelper& rHelper ) : 74 WorksheetHelper( rHelper ) 75 { 76 } 77 78 // ============================================================================ 79 80 namespace { 81 82 const sal_uInt16 BIFF_BOF_GLOBALS = 0x0005; /// BIFF5-BIFF8 workbook globals. 83 const sal_uInt16 BIFF_BOF_MODULE = 0x0006; /// BIFF5-BIFF8 Visual Basic module. 84 const sal_uInt16 BIFF_BOF_SHEET = 0x0010; /// BIFF2-BIFF8 worksheet/dialog sheet. 85 const sal_uInt16 BIFF_BOF_CHART = 0x0020; /// BIFF2-BIFF8 chart sheet. 86 const sal_uInt16 BIFF_BOF_MACRO = 0x0040; /// BIFF4-BIFF8 macro sheet. 87 const sal_uInt16 BIFF_BOF_WORKSPACE = 0x0100; /// BIFF3-BIFF8 workspace. 88 89 } // namespace 90 91 // ---------------------------------------------------------------------------- 92 93 BiffFragmentHandler::BiffFragmentHandler( const FilterBase& rFilter, const OUString& rStrmName ) 94 { 95 // do not automatically close the root stream (indicated by empty stream name) 96 bool bRootStrm = rStrmName.getLength() == 0; 97 mxXInStrm.reset( new BinaryXInputStream( rFilter.openInputStream( rStrmName ), !bRootStrm ) ); 98 mxBiffStrm.reset( new BiffInputStream( *mxXInStrm ) ); 99 } 100 101 BiffFragmentHandler::~BiffFragmentHandler() 102 { 103 } 104 105 BiffFragmentType BiffFragmentHandler::startFragment( BiffType eBiff ) 106 { 107 BiffFragmentType eFragment = BIFF_FRAGMENT_UNKNOWN; 108 /* #i23425# Don't rely on BOF record ID to read BOF contents, but on 109 the detected BIFF version. */ 110 if( mxBiffStrm->startNextRecord() && BiffHelper::isBofRecord( *mxBiffStrm ) ) 111 { 112 // BOF is always written unencrypted 113 mxBiffStrm->enableDecoder( false ); 114 mxBiffStrm->skip( 2 ); 115 sal_uInt16 nType = mxBiffStrm->readuInt16(); 116 117 // decide which fragment types are valid for current BIFF version 118 switch( eBiff ) 119 { 120 case BIFF2: switch( nType ) 121 { 122 case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_EMPTYSHEET; break; 123 case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACROSHEET; break; 124 // #i51490# Excel interprets invalid types as worksheet 125 default: eFragment = BIFF_FRAGMENT_WORKSHEET; 126 } 127 break; 128 129 case BIFF3: switch( nType ) 130 { 131 case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_EMPTYSHEET; break; 132 case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACROSHEET; break; 133 case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_UNKNOWN; break; 134 // #i51490# Excel interprets invalid types as worksheet 135 default: eFragment = BIFF_FRAGMENT_WORKSHEET; 136 }; 137 break; 138 139 case BIFF4: switch( nType ) 140 { 141 case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_EMPTYSHEET; break; 142 case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACROSHEET; break; 143 case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_WORKSPACE; break; 144 // #i51490# Excel interprets invalid types as worksheet 145 default: eFragment = BIFF_FRAGMENT_WORKSHEET; 146 }; 147 break; 148 149 case BIFF5: 150 case BIFF8: switch( nType ) 151 { 152 case BIFF_BOF_GLOBALS: eFragment = BIFF_FRAGMENT_GLOBALS; break; 153 case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_CHARTSHEET; break; 154 case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACROSHEET; break; 155 case BIFF_BOF_MODULE: eFragment = BIFF_FRAGMENT_MODULESHEET; break; 156 case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_UNKNOWN; break; 157 // #i51490# Excel interprets invalid types as worksheet 158 default: eFragment = BIFF_FRAGMENT_WORKSHEET; 159 }; 160 break; 161 162 case BIFF_UNKNOWN: break; 163 } 164 } 165 return eFragment; 166 } 167 168 bool BiffFragmentHandler::skipFragment() 169 { 170 while( mxBiffStrm->startNextRecord() && (mxBiffStrm->getRecId() != BIFF_ID_EOF) ) 171 if( BiffHelper::isBofRecord( *mxBiffStrm ) ) 172 skipFragment(); 173 return !mxBiffStrm->isEof() && (mxBiffStrm->getRecId() == BIFF_ID_EOF); 174 } 175 176 // ============================================================================ 177 178 BiffWorkbookFragmentBase::BiffWorkbookFragmentBase( const WorkbookHelper& rHelper, const OUString& rStrmName, bool bCloneDecoder ) : 179 BiffFragmentHandler( rHelper.getBaseFilter(), rStrmName ), 180 WorkbookHelper( rHelper ) 181 { 182 if( bCloneDecoder ) 183 getCodecHelper().cloneDecoder( getInputStream() ); 184 } 185 186 // ---------------------------------------------------------------------------- 187 188 BiffWorksheetFragmentBase::BiffWorksheetFragmentBase( const WorksheetHelper& rHelper, const BiffWorkbookFragmentBase& rParent ) : 189 BiffFragmentHandler( rParent ), 190 WorksheetHelper( rHelper ) 191 { 192 } 193 194 // ---------------------------------------------------------------------------- 195 196 BiffSkipWorksheetFragment::BiffSkipWorksheetFragment( const WorksheetHelper& rHelper, const BiffWorkbookFragmentBase& rParent ) : 197 BiffWorksheetFragmentBase( rHelper, rParent ) 198 { 199 } 200 201 bool BiffSkipWorksheetFragment::importFragment() 202 { 203 return skipFragment(); 204 } 205 206 // ============================================================================ 207 // ============================================================================ 208 209 } // namespace xls 210 } // namespace oox 211