| 249 | } |
| 250 | |
| 251 | std::optional<char const *> getString(void * obj, std::string const & name, bool raw, bool throwError) const |
| 252 | { |
| 253 | auto prop = Properties.find(name); |
| 254 | if (prop == Properties.end()) { |
| 255 | if (Parent != nullptr) { |
| 256 | return Parent->getString(toParent(obj), name, raw, throwError); |
| 257 | } else { |
| 258 | if (throwError) { |
| 259 | OsiError("Failed to get string '" << name << "': Property does not exist"); |
| 260 | } |
| 261 | return {}; |
| 262 | } |
| 263 | } |
| 264 | |
| 265 | if (!raw && prop->second.GetString) { |
| 266 | return prop->second.GetString(obj); |
| 267 | } |
| 268 | |
| 269 | if (!raw && !(prop->second.Flags & kPropRead)) { |
| 270 | OsiError("Failed to get string '" << name << "': Property not readable"); |
| 271 | return {}; |
| 272 | } |
| 273 | |
| 274 | auto ptr = reinterpret_cast<std::uintptr_t>(obj) + prop->second.Offset; |
| 275 | if (prop->second.Type == PropertyType::kFixedString) { |
| 276 | return reinterpret_cast<FixedString *>(ptr)->Str; |
| 277 | } else { |
| 278 | OsiError("Failed to get property '" << name << "': Property is not a string"); |
| 279 | return {}; |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | bool setString(void * obj, std::string const & name, char const * value, bool raw, bool throwError) const |
| 284 | { |
no test coverage detected