|
23 | 23 | #include "openPMD/Datatype.hpp" |
24 | 24 | #include "openPMD/DatatypeHelpers.hpp" |
25 | 25 | #include "openPMD/Error.hpp" |
| 26 | +#include "openPMD/IO/Access.hpp" |
| 27 | +#include "openPMD/ThrowError.hpp" |
26 | 28 | #include "openPMD/auxiliary/Filesystem.hpp" |
27 | 29 | #include "openPMD/auxiliary/Memory.hpp" |
28 | 30 | #include "openPMD/auxiliary/StringManip.hpp" |
@@ -165,13 +167,13 @@ void JSONIOHandlerImpl::createPath( |
165 | 167 | auto filepos = setAndGetFilePosition(writable, false); |
166 | 168 |
|
167 | 169 | jsonVal = &(*jsonVal)[filepos->id]; |
168 | | - ensurePath(jsonVal, path); |
| 170 | + ensurePath(jsonVal, path, m_handler->m_backendAccess); |
169 | 171 | path = filepos->id.to_string() + "/" + path; |
170 | 172 | } |
171 | 173 | else |
172 | 174 | { |
173 | 175 |
|
174 | | - ensurePath(jsonVal, path); |
| 176 | + ensurePath(jsonVal, path, m_handler->m_backendAccess); |
175 | 177 | } |
176 | 178 |
|
177 | 179 | m_dirty.emplace(file); |
@@ -570,7 +572,10 @@ void JSONIOHandlerImpl::openPath( |
570 | 572 | std::make_shared<JSONFilePosition>(json::json_pointer(path)); |
571 | 573 | } |
572 | 574 |
|
573 | | - ensurePath(j, removeSlashes(parameters.path)); |
| 575 | + ensurePath( |
| 576 | + j, |
| 577 | + removeSlashes(parameters.path), |
| 578 | + /* Must not modify j */ Access::READ_ONLY); |
574 | 579 |
|
575 | 580 | writable->written = true; |
576 | 581 | } |
@@ -1110,18 +1115,46 @@ bool JSONIOHandlerImpl::hasKey(nlohmann::json &j, KeyT &&key) |
1110 | 1115 | return j.find(std::forward<KeyT>(key)) != j.end(); |
1111 | 1116 | } |
1112 | 1117 |
|
1113 | | -void JSONIOHandlerImpl::ensurePath(nlohmann::json *jsonp, std::string path) |
| 1118 | +void JSONIOHandlerImpl::ensurePath( |
| 1119 | + nlohmann::json *jsonp, std::string path, Access access) |
1114 | 1120 | { |
1115 | 1121 | auto groups = auxiliary::split(path, "/"); |
1116 | | - for (std::string &group : groups) |
| 1122 | + if (access::readOnly(access)) |
1117 | 1123 | { |
1118 | | - // Enforce a JSON object |
1119 | | - // the library will automatically create a list if the first |
1120 | | - // key added to it is parseable as an int |
1121 | | - jsonp = &(*jsonp)[group]; |
1122 | | - if (jsonp->is_null()) |
| 1124 | + for (std::string const &group : groups) |
1123 | 1125 | { |
1124 | | - *jsonp = nlohmann::json::object(); |
| 1126 | + if (!jsonp->contains(group)) |
| 1127 | + { |
| 1128 | + throw error::ReadError( |
| 1129 | + error::AffectedObject::Group, |
| 1130 | + error::Reason::NotFound, |
| 1131 | + "JSON", |
| 1132 | + "Required group '" + path + "' not present."); |
| 1133 | + } |
| 1134 | + jsonp = &(*jsonp).at(group); |
| 1135 | + if (!jsonp->is_object()) |
| 1136 | + { |
| 1137 | + throw error::ReadError( |
| 1138 | + error::AffectedObject::Group, |
| 1139 | + error::Reason::UnexpectedContent, |
| 1140 | + "JSON", |
| 1141 | + "Required group '" + path + |
| 1142 | + "' is present, but not a JSON object."); |
| 1143 | + } |
| 1144 | + } |
| 1145 | + } |
| 1146 | + else |
| 1147 | + { |
| 1148 | + for (std::string const &group : groups) |
| 1149 | + { |
| 1150 | + // Enforce a JSON object |
| 1151 | + // the library will automatically create a list if the first |
| 1152 | + // key added to it is parseable as an int |
| 1153 | + jsonp = &(*jsonp)[group]; |
| 1154 | + if (jsonp->is_null()) |
| 1155 | + { |
| 1156 | + *jsonp = nlohmann::json::object(); |
| 1157 | + } |
1125 | 1158 | } |
1126 | 1159 | } |
1127 | 1160 | } |
|
0 commit comments