1 /******************************************************************************
2 * $Id: ogrxlsdatasource.cpp 28382 2015-01-30 15:29:41Z rouault $
3 *
4 * Project: XLS Translator
5 * Purpose: Implements OGRXLSDataSource class
6 * Author: Even Rouault, even dot rouault at mines dash paris dot org
7 *
8 ******************************************************************************
9 * Copyright (c) 2011, Even Rouault <even dot rouault at mines-paris dot org>
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included
19 * in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 * DEALINGS IN THE SOFTWARE.
28 ****************************************************************************/
29
30 #include <freexl.h>
31
32 #ifdef _WIN32
33 # include <windows.h>
34 #endif
35
36 #include "ogr_xls.h"
37 #include "cpl_conv.h"
38 #include "cpl_string.h"
39
40 CPL_CVSID("$Id: ogrxlsdatasource.cpp 28382 2015-01-30 15:29:41Z rouault $");
41
42 /************************************************************************/
43 /* OGRXLSDataSource() */
44 /************************************************************************/
45
OGRXLSDataSource()46 OGRXLSDataSource::OGRXLSDataSource()
47
48 {
49 papoLayers = NULL;
50 nLayers = 0;
51
52 pszName = NULL;
53
54 xlshandle = NULL;
55 }
56
57 /************************************************************************/
58 /* ~OGRXLSDataSource() */
59 /************************************************************************/
60
~OGRXLSDataSource()61 OGRXLSDataSource::~OGRXLSDataSource()
62
63 {
64 for( int i = 0; i < nLayers; i++ )
65 delete papoLayers[i];
66 CPLFree( papoLayers );
67
68 CPLFree( pszName );
69
70 if (xlshandle)
71 freexl_close(xlshandle);
72 }
73
74 /************************************************************************/
75 /* TestCapability() */
76 /************************************************************************/
77
TestCapability(CPL_UNUSED const char * pszCap)78 int OGRXLSDataSource::TestCapability( CPL_UNUSED const char * pszCap )
79
80 {
81 return FALSE;
82 }
83
84 /************************************************************************/
85 /* GetLayer() */
86 /************************************************************************/
87
GetLayer(int iLayer)88 OGRLayer *OGRXLSDataSource::GetLayer( int iLayer )
89
90 {
91 if( iLayer < 0 || iLayer >= nLayers )
92 return NULL;
93 else
94 return papoLayers[iLayer];
95 }
96
97 /************************************************************************/
98 /* Open() */
99 /************************************************************************/
100
Open(const char * pszFilename,int bUpdateIn)101 int OGRXLSDataSource::Open( const char * pszFilename, int bUpdateIn)
102
103 {
104 if (bUpdateIn)
105 {
106 return FALSE;
107 }
108
109 #ifdef _WIN32
110 if( CSLTestBoolean( CPLGetConfigOption( "GDAL_FILENAME_IS_UTF8", "YES" ) ) )
111 pszName = CPLRecode( pszFilename, CPL_ENC_UTF8, CPLString().Printf( "CP%d", GetACP() ) );
112 else
113 pszName = CPLStrdup( pszFilename );
114 #else
115 pszName = CPLStrdup( pszFilename );
116 #endif
117
118 // --------------------------------------------------------------------
119 // Does this appear to be a .xls file?
120 // --------------------------------------------------------------------
121
122 /* Open only for getting info. To get cell values, we have to use freexl_open */
123 if (freexl_open_info (pszName, &xlshandle) != FREEXL_OK)
124 return FALSE;
125
126 unsigned int nSheets = 0;
127 if (freexl_get_info (xlshandle, FREEXL_BIFF_SHEET_COUNT, &nSheets) != FREEXL_OK)
128 return FALSE;
129
130 for(unsigned short i=0; i<(unsigned short)nSheets; i++)
131 {
132 freexl_select_active_worksheet(xlshandle, i);
133
134 const char* pszSheetname = NULL;
135 if (freexl_get_worksheet_name(xlshandle, i, &pszSheetname) != FREEXL_OK)
136 return FALSE;
137
138 unsigned int nRows = 0;
139 unsigned short nCols = 0;
140 if (freexl_worksheet_dimensions(xlshandle, &nRows, &nCols) != FREEXL_OK)
141 return FALSE;
142
143 /* Skip empty sheets */
144 if (nRows == 0)
145 continue;
146
147 papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
148 papoLayers[nLayers ++] = new OGRXLSLayer(this, pszSheetname, i, (int)nRows, nCols);
149 }
150
151 freexl_close(xlshandle);
152 xlshandle = NULL;
153
154 return TRUE;
155 }
156
157 /************************************************************************/
158 /* GetXLSHandle() */
159 /************************************************************************/
160
GetXLSHandle()161 const void* OGRXLSDataSource::GetXLSHandle()
162 {
163 if (xlshandle)
164 return xlshandle;
165
166 if (freexl_open (pszName, &xlshandle) != FREEXL_OK)
167 return NULL;
168
169 return xlshandle;
170 }
171