xref: /aoo41x/main/oox/source/xls/excelhandlers.cxx (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 #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