Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL TileDB Driver
4 : * Purpose: Implement GDAL TileDB multidimensional support based on https://www.tiledb.io
5 : * Author: TileDB, Inc
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2023, TileDB, Inc
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 "tiledbmultidim.h"
30 : #include "memmultidim.h"
31 :
32 : /************************************************************************/
33 : /* TileDBAttribute::TileDBAttribute() */
34 : /************************************************************************/
35 :
36 73 : TileDBAttribute::TileDBAttribute(const std::string &osParentName,
37 73 : const std::string &osName)
38 : : GDALAbstractMDArray(osParentName, osName),
39 73 : GDALAttribute(osParentName, osName)
40 : {
41 73 : }
42 :
43 : /************************************************************************/
44 : /* TileDBAttribute::Create() */
45 : /************************************************************************/
46 :
47 : /*static*/ std::shared_ptr<GDALAttribute>
48 73 : TileDBAttribute::Create(const std::shared_ptr<TileDBAttributeHolder> &poParent,
49 : const std::string &osName,
50 : const std::vector<GUInt64> &anDimensions,
51 : const GDALExtendedDataType &oDataType)
52 : {
53 73 : if (anDimensions.size() > 1)
54 : {
55 0 : CPLError(CE_Failure, CPLE_NotSupported,
56 : "Only 0 or 1-dimensional attribute are supported");
57 0 : return nullptr;
58 : }
59 73 : if (oDataType.GetClass() == GEDTC_STRING)
60 : {
61 51 : if (anDimensions.size() == 1 && anDimensions[0] != 1)
62 : {
63 0 : CPLError(CE_Failure, CPLE_NotSupported,
64 : "Only single value string attribute are supported");
65 0 : return nullptr;
66 : }
67 : }
68 22 : else if (oDataType.GetClass() == GEDTC_COMPOUND)
69 : {
70 0 : CPLError(CE_Failure, CPLE_NotSupported,
71 : "Compound data type attribute are not supported");
72 0 : return nullptr;
73 : }
74 :
75 : auto poAttr = std::shared_ptr<TileDBAttribute>(
76 146 : new TileDBAttribute(poParent->IGetFullName(), osName));
77 146 : poAttr->m_poMemAttribute = MEMAttribute::Create(
78 146 : poParent->IGetFullName(), osName, anDimensions, oDataType);
79 73 : if (!poAttr->m_poMemAttribute)
80 0 : return nullptr;
81 73 : poAttr->m_poParent = poParent;
82 73 : return poAttr;
83 : }
84 :
85 : /************************************************************************/
86 : /* TileDBAttribute::IRead() */
87 : /************************************************************************/
88 :
89 33 : bool TileDBAttribute::IRead(const GUInt64 *arrayStartIdx, const size_t *count,
90 : const GInt64 *arrayStep,
91 : const GPtrDiff_t *bufferStride,
92 : const GDALExtendedDataType &bufferDataType,
93 : void *pDstBuffer) const
94 : {
95 33 : if (!CheckValidAndErrorOutIfNot())
96 1 : return false;
97 64 : auto poParent = m_poParent.lock();
98 32 : if (!poParent)
99 : {
100 0 : CPLError(CE_Failure, CPLE_AppDefined,
101 : "TileDBAttribute::IRead() failed because owing array object"
102 : "is no longer alive");
103 0 : return false;
104 : }
105 32 : if (GetDataType().GetClass() == GEDTC_STRING)
106 : {
107 : tiledb_datatype_t tiledb_dt;
108 22 : uint32_t nLen = 0;
109 22 : const void *ptr = nullptr;
110 22 : if (!poParent->GetMetadata(m_osName, &tiledb_dt, &nLen, &ptr))
111 0 : return false;
112 22 : if (tiledb_dt != TILEDB_STRING_UTF8 &&
113 2 : tiledb_dt != TILEDB_STRING_ASCII && tiledb_dt != TILEDB_UINT8)
114 0 : return false;
115 22 : std::string osStr;
116 22 : osStr.assign(static_cast<const char *>(ptr), nLen);
117 22 : if (!m_poMemAttribute->Write(osStr.c_str()))
118 0 : return false;
119 : }
120 : else
121 : {
122 10 : tiledb_datatype_t expected_tiledb_dt = TILEDB_ANY;
123 10 : if (!TileDBArray::GDALDataTypeToTileDB(
124 10 : GetDataType().GetNumericDataType(), expected_tiledb_dt))
125 0 : return false;
126 : tiledb_datatype_t tiledb_dt;
127 10 : uint32_t nLen = 0;
128 10 : const void *ptr = nullptr;
129 10 : if (!poParent->GetMetadata(m_osName, &tiledb_dt, &nLen, &ptr))
130 0 : return false;
131 10 : if (tiledb_dt != expected_tiledb_dt)
132 0 : return false;
133 10 : if (!m_poMemAttribute->Write(ptr, nLen * GetDataType().GetSize()))
134 0 : return false;
135 : }
136 64 : return m_poMemAttribute->Read(arrayStartIdx, count, arrayStep, bufferStride,
137 32 : bufferDataType, pDstBuffer);
138 : }
139 :
140 : /************************************************************************/
141 : /* TileDBAttribute::IWrite() */
142 : /************************************************************************/
143 :
144 15 : bool TileDBAttribute::IWrite(const GUInt64 *arrayStartIdx, const size_t *count,
145 : const GInt64 *arrayStep,
146 : const GPtrDiff_t *bufferStride,
147 : const GDALExtendedDataType &bufferDataType,
148 : const void *pSrcBuffer)
149 : {
150 15 : if (!CheckValidAndErrorOutIfNot())
151 1 : return false;
152 28 : auto poParent = m_poParent.lock();
153 14 : if (!poParent)
154 : {
155 0 : CPLError(CE_Failure, CPLE_AppDefined,
156 : "TileDBAttribute::IWrite() failed because owing array object"
157 : "is no longer alive");
158 0 : return false;
159 : }
160 14 : if (!poParent->IIsWritable())
161 : {
162 1 : CPLError(CE_Failure, CPLE_NotSupported,
163 : "Dataset not open in update mode");
164 1 : return false;
165 : }
166 :
167 13 : if (!m_poMemAttribute->Write(arrayStartIdx, count, arrayStep, bufferStride,
168 : bufferDataType, pSrcBuffer))
169 : {
170 0 : return false;
171 : }
172 :
173 13 : if (GetDataType().GetClass() == GEDTC_STRING)
174 : {
175 11 : const char *pszStr = m_poMemAttribute->ReadAsString();
176 11 : if (pszStr)
177 : {
178 11 : const auto tiledb_dt = CPLIsASCII(pszStr, -1) ? TILEDB_STRING_ASCII
179 11 : : TILEDB_STRING_UTF8;
180 11 : return poParent->PutMetadata(m_osName, tiledb_dt,
181 11 : static_cast<uint32_t>(strlen(pszStr)),
182 11 : pszStr);
183 : }
184 0 : return false;
185 : }
186 :
187 2 : tiledb_datatype_t tiledb_dt = TILEDB_ANY;
188 2 : if (!TileDBArray::GDALDataTypeToTileDB(GetDataType().GetNumericDataType(),
189 : tiledb_dt))
190 0 : return false;
191 :
192 4 : auto oRawResult = m_poMemAttribute->ReadAsRaw();
193 2 : if (!oRawResult.data())
194 0 : return false;
195 : const auto nValues =
196 2 : static_cast<uint32_t>(oRawResult.size() / GetDataType().GetSize());
197 4 : return poParent->PutMetadata(m_osName, tiledb_dt, nValues,
198 4 : oRawResult.data());
199 : }
|