Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: SAP HANA Spatial Driver
4 : * Purpose: OGRHanaFeatureWriter class implementation
5 : * Author: Maxim Rylov
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2020, SAP SE
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 "ogrhanafeaturewriter.h"
30 : #include <limits>
31 :
32 : namespace OGRHANA
33 : {
34 : namespace
35 : {
36 :
37 : enum DataLengthIndicator
38 : {
39 : MAX_ONE_BYTE = 245,
40 : TWO_BYTE = 246,
41 : FOUR_BYTE = 247,
42 : DEFAULT_VALUE = 254,
43 : NULL_VALUE = 255
44 : };
45 :
46 : } // anonymous namespace
47 :
48 543 : OGRHanaFeatureWriter::OGRHanaFeatureWriter(OGRFeature &feature)
49 543 : : feature_(feature)
50 : {
51 543 : }
52 :
53 533 : void OGRHanaFeatureWriter::SetFieldValue(int fieldIndex,
54 : const odbc::Long &value)
55 : {
56 533 : if (value.isNull())
57 12 : feature_.SetFieldNull(fieldIndex);
58 : else
59 521 : feature_.SetField(fieldIndex, static_cast<GIntBig>(*value));
60 533 : }
61 :
62 1 : void OGRHanaFeatureWriter::SetFieldValue(int fieldIndex,
63 : const odbc::Float &value)
64 : {
65 1 : if (value.isNull())
66 0 : feature_.SetFieldNull(fieldIndex);
67 : else
68 1 : feature_.SetField(fieldIndex, static_cast<double>(*value));
69 1 : }
70 :
71 1 : void OGRHanaFeatureWriter::SetFieldValue(int fieldIndex,
72 : const odbc::Decimal &value)
73 : {
74 1 : if (value.isNull())
75 0 : feature_.SetFieldNull(fieldIndex);
76 : else
77 1 : feature_.SetField(fieldIndex, value->toString().c_str());
78 1 : }
79 :
80 0 : void OGRHanaFeatureWriter::SetFieldValue(int fieldIndex,
81 : const odbc::String &value)
82 : {
83 0 : if (value.isNull())
84 0 : feature_.SetFieldNull(fieldIndex);
85 : else
86 0 : feature_.SetField(fieldIndex, value->c_str());
87 0 : }
88 :
89 1 : void OGRHanaFeatureWriter::SetFieldValue(int fieldIndex,
90 : const odbc::Date &value)
91 : {
92 1 : if (value.isNull())
93 0 : feature_.SetFieldNull(fieldIndex);
94 : else
95 1 : feature_.SetField(fieldIndex, value->year(), value->month(),
96 : value->day(), 0, 0, 0, 0);
97 1 : }
98 :
99 1 : void OGRHanaFeatureWriter::SetFieldValue(int fieldIndex,
100 : const odbc::Time &value)
101 : {
102 1 : if (value.isNull())
103 0 : feature_.SetFieldNull(fieldIndex);
104 : else
105 1 : feature_.SetField(fieldIndex, 0, 0, 0, value->hour(), value->minute(),
106 1 : static_cast<float>(value->second()), 0);
107 1 : }
108 :
109 4 : void OGRHanaFeatureWriter::SetFieldValue(int fieldIndex,
110 : const odbc::Timestamp &value)
111 : {
112 4 : if (value.isNull())
113 0 : feature_.SetFieldNull(fieldIndex);
114 : else
115 12 : feature_.SetField(fieldIndex, value->year(), value->month(),
116 8 : value->day(), value->hour(), value->minute(),
117 4 : static_cast<float>(value->second() +
118 4 : value->milliseconds() / 1000.0),
119 : 0);
120 4 : }
121 :
122 0 : void OGRHanaFeatureWriter::SetFieldValue(int fieldIndex,
123 : const odbc::Binary &value)
124 : {
125 0 : if (value.isNull())
126 0 : feature_.SetFieldNull(fieldIndex);
127 : else
128 0 : SetFieldValue(fieldIndex, value->data(), value->size());
129 0 : }
130 :
131 521 : void OGRHanaFeatureWriter::SetFieldValue(int fieldIndex, const char *value)
132 : {
133 521 : if (value == nullptr)
134 0 : feature_.SetFieldNull(fieldIndex);
135 : else
136 521 : feature_.SetField(fieldIndex, value);
137 521 : }
138 :
139 1 : void OGRHanaFeatureWriter::SetFieldValue(int fieldIndex, const void *value,
140 : std::size_t size)
141 : {
142 1 : if (size > static_cast<std::size_t>(std::numeric_limits<int>::max()))
143 : {
144 0 : CPLError(CE_Failure, CPLE_AppDefined,
145 : "Data size is larger than maximum integer value");
146 0 : return;
147 : }
148 :
149 1 : if (value == nullptr)
150 0 : feature_.SetFieldNull(fieldIndex);
151 : else
152 1 : feature_.SetField(fieldIndex, static_cast<int>(size), value);
153 : }
154 :
155 3 : void OGRHanaFeatureWriter::SetFieldValueAsStringArray(int fieldIndex,
156 : const odbc::Binary &value)
157 : {
158 3 : if (value.isNull() || value->size() == 0)
159 : {
160 0 : feature_.SetFieldNull(fieldIndex);
161 0 : return;
162 : }
163 :
164 3 : const char *ptr = value->data();
165 3 : const uint32_t numElements = *reinterpret_cast<const uint32_t *>(ptr);
166 3 : ptr += sizeof(uint32_t);
167 :
168 3 : char **values = nullptr;
169 :
170 9 : for (uint32_t i = 0; i < numElements; ++i)
171 : {
172 6 : uint8_t indicator = *ptr;
173 6 : ++ptr;
174 :
175 6 : int32_t len = 0;
176 6 : if (indicator <= DataLengthIndicator::MAX_ONE_BYTE)
177 : {
178 6 : len = indicator;
179 : }
180 0 : else if (indicator == DataLengthIndicator::TWO_BYTE)
181 : {
182 0 : len = *reinterpret_cast<const int16_t *>(ptr);
183 0 : ptr += sizeof(int16_t);
184 : }
185 : else
186 : {
187 0 : len = *reinterpret_cast<const int32_t *>(ptr);
188 0 : ptr += sizeof(int32_t);
189 : }
190 :
191 6 : if (len == 0)
192 : {
193 2 : values = CSLAddString(values, "");
194 : }
195 : else
196 : {
197 4 : if (ptr[0] == '\0')
198 : {
199 0 : values = CSLAddString(values, ptr);
200 : }
201 : else
202 : {
203 4 : char *val = static_cast<char *>(CPLMalloc(len + 1));
204 4 : memcpy(val, ptr, len);
205 4 : val[len] = '\0';
206 4 : values = CSLAddString(values, val);
207 4 : CPLFree(val);
208 : }
209 : }
210 :
211 6 : ptr += len;
212 : }
213 :
214 3 : feature_.SetField(fieldIndex, values);
215 3 : CSLDestroy(values);
216 : }
217 :
218 : } // namespace OGRHANA
|