xref: /trunk/main/oox/source/xls/excelhandlers.cxx (revision ca5ec200)
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 
WorkbookFragmentBase(const WorkbookHelper & rHelper,const OUString & rFragmentPath)41 WorkbookFragmentBase::WorkbookFragmentBase(
42         const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
43     FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ),
44     WorkbookHelper( rHelper )
45 {
46 }
47 
48 // ============================================================================
49 
WorksheetFragmentBase(const WorksheetHelper & rHelper,const OUString & rFragmentPath)50 WorksheetFragmentBase::WorksheetFragmentBase(
51         const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :
52     FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ),
53     WorksheetHelper( rHelper )
54 {
55 }
56 
57 // ============================================================================
58 // ============================================================================
59 
~BiffContextHandler()60 BiffContextHandler::~BiffContextHandler()
61 {
62 }
63 
64 // ----------------------------------------------------------------------------
65 
BiffWorkbookContextBase(const WorkbookHelper & rHelper)66 BiffWorkbookContextBase::BiffWorkbookContextBase( const WorkbookHelper& rHelper ) :
67     WorkbookHelper( rHelper )
68 {
69 }
70 
71 // ----------------------------------------------------------------------------
72 
BiffWorksheetContextBase(const WorksheetHelper & rHelper)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 
BiffFragmentHandler(const FilterBase & rFilter,const OUString & rStrmName)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 
~BiffFragmentHandler()101 BiffFragmentHandler::~BiffFragmentHandler()
102 {
103 }
104 
startFragment(BiffType eBiff)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 
skipFragment()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 
BiffWorkbookFragmentBase(const WorkbookHelper & rHelper,const OUString & rStrmName,bool bCloneDecoder)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 
BiffWorksheetFragmentBase(const WorksheetHelper & rHelper,const BiffWorkbookFragmentBase & rParent)188 BiffWorksheetFragmentBase::BiffWorksheetFragmentBase( const WorksheetHelper& rHelper, const BiffWorkbookFragmentBase& rParent ) :
189     BiffFragmentHandler( rParent ),
190     WorksheetHelper( rHelper )
191 {
192 }
193 
194 // ----------------------------------------------------------------------------
195 
BiffSkipWorksheetFragment(const WorksheetHelper & rHelper,const BiffWorkbookFragmentBase & rParent)196 BiffSkipWorksheetFragment::BiffSkipWorksheetFragment( const WorksheetHelper& rHelper, const BiffWorkbookFragmentBase& rParent ) :
197     BiffWorksheetFragmentBase( rHelper, rParent )
198 {
199 }
200 
importFragment()201 bool BiffSkipWorksheetFragment::importFragment()
202 {
203     return skipFragment();
204 }
205 
206 // ============================================================================
207 // ============================================================================
208 
209 } // namespace xls
210 } // namespace oox
211