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