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