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