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 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #include "netcdfdataset.h"
14 :
15 13 : bool netCDFWriterConfiguration::SetNameValue(
16 : CPLXMLNode *psNode, std::map<CPLString, CPLString> &oMap)
17 : {
18 13 : const char *pszName = CPLGetXMLValue(psNode, "name", nullptr);
19 13 : const char *pszValue = CPLGetXMLValue(psNode, "value", nullptr);
20 13 : if (pszName != nullptr && pszValue != nullptr)
21 : {
22 4 : oMap[pszName] = pszValue;
23 4 : return true;
24 : }
25 9 : CPLError(CE_Failure, CPLE_IllegalArg, "Missing name/value");
26 9 : return false;
27 : }
28 :
29 4 : bool netCDFWriterConfiguration::Parse(const char *pszFilename)
30 : {
31 4 : CPLXMLNode *psRoot = STARTS_WITH(pszFilename, "<Configuration")
32 4 : ? CPLParseXMLString(pszFilename)
33 1 : : CPLParseXMLFile(pszFilename);
34 4 : if (psRoot == nullptr)
35 2 : return false;
36 2 : CPLXMLTreeCloser oCloser(psRoot);
37 :
38 26 : for (CPLXMLNode *psIter = psRoot->psChild; psIter != nullptr;
39 24 : psIter = psIter->psNext)
40 : {
41 24 : if (psIter->eType != CXT_Element)
42 1 : continue;
43 23 : if (EQUAL(psIter->pszValue, "DatasetCreationOption"))
44 : {
45 4 : SetNameValue(psIter, m_oDatasetCreationOptions);
46 : }
47 19 : else if (EQUAL(psIter->pszValue, "LayerCreationOption"))
48 : {
49 4 : SetNameValue(psIter, m_oLayerCreationOptions);
50 : }
51 15 : else if (EQUAL(psIter->pszValue, "Attribute"))
52 : {
53 12 : netCDFWriterConfigAttribute oAtt;
54 6 : if (oAtt.Parse(psIter))
55 2 : m_aoAttributes.push_back(oAtt);
56 : }
57 9 : else if (EQUAL(psIter->pszValue, "Field"))
58 : {
59 10 : netCDFWriterConfigField oField;
60 5 : if (oField.Parse(psIter))
61 8 : m_oFields[!oField.m_osName.empty()
62 5 : ? oField.m_osName
63 13 : : CPLString("__") + oField.m_osNetCDFName] =
64 4 : oField;
65 : }
66 4 : else if (EQUAL(psIter->pszValue, "Layer"))
67 : {
68 6 : netCDFWriterConfigLayer oLayer;
69 3 : if (oLayer.Parse(psIter))
70 2 : m_oLayers[oLayer.m_osName] = oLayer;
71 : }
72 : else
73 : {
74 1 : CPLDebug("GDAL_netCDF", "Ignoring %s", psIter->pszValue);
75 : }
76 : }
77 :
78 2 : m_bIsValid = true;
79 :
80 2 : return true;
81 : }
82 :
83 15 : bool netCDFWriterConfigAttribute::Parse(CPLXMLNode *psNode)
84 : {
85 15 : const char *pszName = CPLGetXMLValue(psNode, "name", nullptr);
86 15 : const char *pszValue = CPLGetXMLValue(psNode, "value", nullptr);
87 15 : const char *pszType = CPLGetXMLValue(psNode, "type", "string");
88 15 : if (!EQUAL(pszType, "string") && !EQUAL(pszType, "integer") &&
89 3 : !EQUAL(pszType, "double"))
90 : {
91 2 : CPLError(CE_Failure, CPLE_NotSupported, "type='%s' unsupported",
92 : pszType);
93 2 : return false;
94 : }
95 13 : if (pszName == nullptr || pszValue == nullptr)
96 : {
97 6 : CPLError(CE_Failure, CPLE_IllegalArg, "Missing name/value");
98 6 : return false;
99 : }
100 7 : m_osName = pszName;
101 7 : m_osValue = pszValue;
102 7 : m_osType = pszType;
103 7 : return true;
104 : }
105 :
106 8 : bool netCDFWriterConfigField::Parse(CPLXMLNode *psNode)
107 : {
108 8 : const char *pszName = CPLGetXMLValue(psNode, "name", nullptr);
109 8 : const char *pszNetCDFName = CPLGetXMLValue(psNode, "netcdf_name", pszName);
110 8 : const char *pszMainDim = CPLGetXMLValue(psNode, "main_dim", nullptr);
111 8 : if (pszName == nullptr && pszNetCDFName == nullptr)
112 : {
113 2 : CPLError(CE_Failure, CPLE_IllegalArg,
114 : "Bot name and netcdf_name are missing");
115 2 : return false;
116 : }
117 6 : if (pszName != nullptr)
118 4 : m_osName = pszName;
119 6 : if (pszNetCDFName != nullptr)
120 6 : m_osNetCDFName = pszNetCDFName;
121 6 : if (pszMainDim != nullptr)
122 2 : m_osMainDim = pszMainDim;
123 :
124 24 : for (CPLXMLNode *psIter = psNode->psChild; psIter != nullptr;
125 18 : psIter = psIter->psNext)
126 : {
127 18 : if (psIter->eType != CXT_Element)
128 13 : continue;
129 5 : if (EQUAL(psIter->pszValue, "Attribute"))
130 : {
131 8 : netCDFWriterConfigAttribute oAtt;
132 4 : if (oAtt.Parse(psIter))
133 4 : m_aoAttributes.push_back(oAtt);
134 : }
135 : else
136 : {
137 1 : CPLDebug("GDAL_netCDF", "Ignoring %s", psIter->pszValue);
138 : }
139 : }
140 :
141 6 : return true;
142 : }
143 :
144 3 : bool netCDFWriterConfigLayer::Parse(CPLXMLNode *psNode)
145 : {
146 3 : const char *pszName = CPLGetXMLValue(psNode, "name", nullptr);
147 3 : const char *pszNetCDFName = CPLGetXMLValue(psNode, "netcdf_name", pszName);
148 3 : if (pszName == nullptr)
149 : {
150 1 : CPLError(CE_Failure, CPLE_IllegalArg, "Missing name");
151 1 : return false;
152 : }
153 2 : m_osName = pszName;
154 2 : if (pszNetCDFName != nullptr)
155 2 : m_osNetCDFName = pszNetCDFName;
156 :
157 21 : for (CPLXMLNode *psIter = psNode->psChild; psIter != nullptr;
158 19 : psIter = psIter->psNext)
159 : {
160 19 : if (psIter->eType != CXT_Element)
161 5 : continue;
162 14 : if (EQUAL(psIter->pszValue, "LayerCreationOption"))
163 : {
164 5 : netCDFWriterConfiguration::SetNameValue(psIter,
165 5 : m_oLayerCreationOptions);
166 : }
167 9 : else if (EQUAL(psIter->pszValue, "Attribute"))
168 : {
169 10 : netCDFWriterConfigAttribute oAtt;
170 5 : if (oAtt.Parse(psIter))
171 1 : m_aoAttributes.push_back(oAtt);
172 : }
173 4 : else if (EQUAL(psIter->pszValue, "Field"))
174 : {
175 6 : netCDFWriterConfigField oField;
176 3 : if (oField.Parse(psIter))
177 4 : m_oFields[!oField.m_osName.empty()
178 3 : ? oField.m_osName
179 7 : : CPLString("__") + oField.m_osNetCDFName] =
180 2 : oField;
181 : }
182 : else
183 : {
184 1 : CPLDebug("GDAL_netCDF", "Ignoring %s", psIter->pszValue);
185 : }
186 : }
187 :
188 2 : return true;
189 : }
|