Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: netCDF read/write Driver
4 : * Purpose: GDAL bindings over netCDF library.
5 : * Author: Even Rouault <even.rouault at spatialys.com>
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2016, Even Rouault <even.rouault at spatialys.com>
9 : *
10 : * Permission is hereby granted, free of charge, to any person obtaining a
11 : * copy of this software and associated documentation files (the "Software"),
12 : * to deal in the Software without restriction, including without limitation
13 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 : * and/or sell copies of the Software, and to permit persons to whom the
15 : * Software is furnished to do so, subject to the following conditions:
16 : *
17 : * The above copyright notice and this permission notice shall be included
18 : * in all copies or substantial portions of the Software.
19 : *
20 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 : * DEALINGS IN THE SOFTWARE.
27 : ****************************************************************************/
28 :
29 : #include "netcdfdataset.h"
30 :
31 13 : bool netCDFWriterConfiguration::SetNameValue(
32 : CPLXMLNode *psNode, std::map<CPLString, CPLString> &oMap)
33 : {
34 13 : const char *pszName = CPLGetXMLValue(psNode, "name", nullptr);
35 13 : const char *pszValue = CPLGetXMLValue(psNode, "value", nullptr);
36 13 : if (pszName != nullptr && pszValue != nullptr)
37 : {
38 4 : oMap[pszName] = pszValue;
39 4 : return true;
40 : }
41 9 : CPLError(CE_Failure, CPLE_IllegalArg, "Missing name/value");
42 9 : return false;
43 : }
44 :
45 4 : bool netCDFWriterConfiguration::Parse(const char *pszFilename)
46 : {
47 4 : CPLXMLNode *psRoot = STARTS_WITH(pszFilename, "<Configuration")
48 4 : ? CPLParseXMLString(pszFilename)
49 1 : : CPLParseXMLFile(pszFilename);
50 4 : if (psRoot == nullptr)
51 2 : return false;
52 2 : CPLXMLTreeCloser oCloser(psRoot);
53 :
54 26 : for (CPLXMLNode *psIter = psRoot->psChild; psIter != nullptr;
55 24 : psIter = psIter->psNext)
56 : {
57 24 : if (psIter->eType != CXT_Element)
58 1 : continue;
59 23 : if (EQUAL(psIter->pszValue, "DatasetCreationOption"))
60 : {
61 4 : SetNameValue(psIter, m_oDatasetCreationOptions);
62 : }
63 19 : else if (EQUAL(psIter->pszValue, "LayerCreationOption"))
64 : {
65 4 : SetNameValue(psIter, m_oLayerCreationOptions);
66 : }
67 15 : else if (EQUAL(psIter->pszValue, "Attribute"))
68 : {
69 12 : netCDFWriterConfigAttribute oAtt;
70 6 : if (oAtt.Parse(psIter))
71 2 : m_aoAttributes.push_back(oAtt);
72 : }
73 9 : else if (EQUAL(psIter->pszValue, "Field"))
74 : {
75 10 : netCDFWriterConfigField oField;
76 5 : if (oField.Parse(psIter))
77 8 : m_oFields[!oField.m_osName.empty()
78 5 : ? oField.m_osName
79 13 : : CPLString("__") + oField.m_osNetCDFName] =
80 4 : oField;
81 : }
82 4 : else if (EQUAL(psIter->pszValue, "Layer"))
83 : {
84 6 : netCDFWriterConfigLayer oLayer;
85 3 : if (oLayer.Parse(psIter))
86 2 : m_oLayers[oLayer.m_osName] = oLayer;
87 : }
88 : else
89 : {
90 1 : CPLDebug("GDAL_netCDF", "Ignoring %s", psIter->pszValue);
91 : }
92 : }
93 :
94 2 : m_bIsValid = true;
95 :
96 2 : return true;
97 : }
98 :
99 15 : bool netCDFWriterConfigAttribute::Parse(CPLXMLNode *psNode)
100 : {
101 15 : const char *pszName = CPLGetXMLValue(psNode, "name", nullptr);
102 15 : const char *pszValue = CPLGetXMLValue(psNode, "value", nullptr);
103 15 : const char *pszType = CPLGetXMLValue(psNode, "type", "string");
104 15 : if (!EQUAL(pszType, "string") && !EQUAL(pszType, "integer") &&
105 3 : !EQUAL(pszType, "double"))
106 : {
107 2 : CPLError(CE_Failure, CPLE_NotSupported, "type='%s' unsupported",
108 : pszType);
109 2 : return false;
110 : }
111 13 : if (pszName == nullptr || pszValue == nullptr)
112 : {
113 6 : CPLError(CE_Failure, CPLE_IllegalArg, "Missing name/value");
114 6 : return false;
115 : }
116 7 : m_osName = pszName;
117 7 : m_osValue = pszValue;
118 7 : m_osType = pszType;
119 7 : return true;
120 : }
121 :
122 8 : bool netCDFWriterConfigField::Parse(CPLXMLNode *psNode)
123 : {
124 8 : const char *pszName = CPLGetXMLValue(psNode, "name", nullptr);
125 8 : const char *pszNetCDFName = CPLGetXMLValue(psNode, "netcdf_name", pszName);
126 8 : const char *pszMainDim = CPLGetXMLValue(psNode, "main_dim", nullptr);
127 8 : if (pszName == nullptr && pszNetCDFName == nullptr)
128 : {
129 2 : CPLError(CE_Failure, CPLE_IllegalArg,
130 : "Bot name and netcdf_name are missing");
131 2 : return false;
132 : }
133 6 : if (pszName != nullptr)
134 4 : m_osName = pszName;
135 6 : if (pszNetCDFName != nullptr)
136 6 : m_osNetCDFName = pszNetCDFName;
137 6 : if (pszMainDim != nullptr)
138 2 : m_osMainDim = pszMainDim;
139 :
140 24 : for (CPLXMLNode *psIter = psNode->psChild; psIter != nullptr;
141 18 : psIter = psIter->psNext)
142 : {
143 18 : if (psIter->eType != CXT_Element)
144 13 : continue;
145 5 : if (EQUAL(psIter->pszValue, "Attribute"))
146 : {
147 8 : netCDFWriterConfigAttribute oAtt;
148 4 : if (oAtt.Parse(psIter))
149 4 : m_aoAttributes.push_back(oAtt);
150 : }
151 : else
152 : {
153 1 : CPLDebug("GDAL_netCDF", "Ignoring %s", psIter->pszValue);
154 : }
155 : }
156 :
157 6 : return true;
158 : }
159 :
160 3 : bool netCDFWriterConfigLayer::Parse(CPLXMLNode *psNode)
161 : {
162 3 : const char *pszName = CPLGetXMLValue(psNode, "name", nullptr);
163 3 : const char *pszNetCDFName = CPLGetXMLValue(psNode, "netcdf_name", pszName);
164 3 : if (pszName == nullptr)
165 : {
166 1 : CPLError(CE_Failure, CPLE_IllegalArg, "Missing name");
167 1 : return false;
168 : }
169 2 : m_osName = pszName;
170 2 : if (pszNetCDFName != nullptr)
171 2 : m_osNetCDFName = pszNetCDFName;
172 :
173 21 : for (CPLXMLNode *psIter = psNode->psChild; psIter != nullptr;
174 19 : psIter = psIter->psNext)
175 : {
176 19 : if (psIter->eType != CXT_Element)
177 5 : continue;
178 14 : if (EQUAL(psIter->pszValue, "LayerCreationOption"))
179 : {
180 5 : netCDFWriterConfiguration::SetNameValue(psIter,
181 5 : m_oLayerCreationOptions);
182 : }
183 9 : else if (EQUAL(psIter->pszValue, "Attribute"))
184 : {
185 10 : netCDFWriterConfigAttribute oAtt;
186 5 : if (oAtt.Parse(psIter))
187 1 : m_aoAttributes.push_back(oAtt);
188 : }
189 4 : else if (EQUAL(psIter->pszValue, "Field"))
190 : {
191 6 : netCDFWriterConfigField oField;
192 3 : if (oField.Parse(psIter))
193 4 : m_oFields[!oField.m_osName.empty()
194 3 : ? oField.m_osName
195 7 : : CPLString("__") + oField.m_osNetCDFName] =
196 2 : oField;
197 : }
198 : else
199 : {
200 1 : CPLDebug("GDAL_netCDF", "Ignoring %s", psIter->pszValue);
201 : }
202 : }
203 :
204 2 : return true;
205 : }
|