Object.hpp
Go to the documentation of this file.
1 /****
2  * Object.hpp - Definitions and macros common to all object types
3  *
4  * Copyright 2019 mikee47 <mike@sillyhouse.net>
5  *
6  * This file is part of the FlashString Library
7  *
8  * This library is free software: you can redistribute it and/or modify it under the terms of the
9  * GNU General Public License as published by the Free Software Foundation, version 3 or later.
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with this library.
16  * If not, see <https://www.gnu.org/licenses/>.
17  *
18  * @author: 2018 - Mikee47 <mike@sillyhouse.net>
19  *
20  ****/
21 
22 #pragma once
23 
24 #include "Utility.hpp"
25 #include "ObjectBase.hpp"
26 #include "ObjectIterator.hpp"
27 
41 #define DECLARE_FSTR_OBJECT(name, ObjectType) extern const ObjectType& name;
42 
49 #define DEFINE_FSTR_REF(name, ObjectType, object) const ObjectType& name PROGMEM = object.template as<ObjectType>();
50 
51 #define DEFINE_FSTR_REF_NAMED(name, ObjectType) DEFINE_FSTR_REF(name, ObjectType, FSTR_DATA_NAME(name).object);
52 
56 #define FSTR_DATA_NAME(name) __fstr__##name
57 
82 #define FSTR_PTR(objref) static_cast<std::remove_reference<decltype(objref)>::type*>(&FSTR_DATA_NAME(objref).object)
83 
87 #ifdef __clang__
88 #define FSTR_CHECK_STRUCT(name)
89 #else
90 #define FSTR_CHECK_STRUCT(name) \
91  static_assert(std::is_pod<decltype(name)>::value, "FSTR structure not POD"); \
92  static_assert(offsetof(decltype(name), data) == sizeof(uint32_t), "FSTR structure alignment error");
93 #endif
94 
103 #define IMPORT_FSTR_OBJECT(name, ObjectType, file) \
104  IMPORT_FSTR_DATA(FSTR_DATA_NAME(name), file) \
105  extern "C" __attribute__((visibility("hidden"))) const FSTR::ObjectBase FSTR_DATA_NAME(name); \
106  DEFINE_FSTR_REF(name, ObjectType, FSTR_DATA_NAME(name));
107 
111 #define IMPORT_FSTR_OBJECT_LOCAL(name, ObjectType, file) \
112  IMPORT_FSTR_DATA(FSTR_DATA_NAME(name), file) \
113  extern "C" __attribute__((visibility("hidden"))) const FSTR::ObjectBase FSTR_DATA_NAME(name); \
114  static FSTR_CONSTEXPR DEFINE_FSTR_REF(name, ObjectType, FSTR_DATA_NAME(name));
115 
116 namespace FSTR
117 {
124 template <class ObjectType, typename ElementType> class Object : public ObjectBase
125 {
126 public:
127  using DataPtrType = const ElementType*;
129 
134  {
135 #ifndef ARCH_HOST
136  // Illegal on real flash object
137  assert(!isFlashPtr(this));
138 #endif
139  }
140 
147  Object(const Object& obj) : ObjectBase{obj.isCopy() ? obj.flashLength_ : uint32_t(&obj) | copyBit}
148  {
149  }
150 
152  {
153  }
154 
155  Object(const Object&& obj) = delete;
156  Object& operator=(const Object& other) = delete;
157  Object& operator=(const Object&& other) = delete;
158 
159  Iterator begin() const
160  {
161  return Iterator(as<ObjectType>(), 0);
162  }
163 
164  Iterator end() const
165  {
166  return Iterator(as<ObjectType>(), length());
167  }
168 
172  static constexpr const ObjectType& empty()
173  {
174  return empty_.as<const ObjectType>();
175  }
176 
180  FSTR_INLINE constexpr const size_t length() const
181  {
182  return ObjectBase::length() / sizeof(ElementType);
183  }
184 
185  template <typename ValueType> int indexOf(const ValueType& value) const
186  {
187  auto& self = as<ObjectType>();
188  auto dataptr = self.data();
189  auto len = self.length();
190  for(unsigned i = 0; i < len; ++i) {
191  if(self.unsafeValueAt(dataptr, i) == value) {
192  return int(i);
193  }
194  }
195 
196  return -1;
197  }
198 
199  FSTR_INLINE ElementType valueAt(unsigned index) const
200  {
201  return (index < length()) ? unsafeValueAt(data(), index) : ElementType{};
202  }
203 
207  FSTR_INLINE ElementType operator[](unsigned index) const
208  {
209  return valueAt(index);
210  }
211 
212  FSTR_INLINE size_t elementSize() const
213  {
214  return sizeof(ElementType);
215  }
216 
218  {
219  // NOLINTNEXTLINE
220  return reinterpret_cast<DataPtrType>(ObjectBase::data());
221  }
222 
230  size_t read(size_t index, ElementType* buffer, size_t count) const
231  {
232  auto offset = index * sizeof(ElementType);
233  count *= sizeof(ElementType);
234  return ObjectBase::read(offset, buffer, count) / sizeof(ElementType);
235  }
236 
244  size_t readFlash(size_t index, ElementType* buffer, size_t count) const
245  {
246  auto offset = index * sizeof(ElementType);
247  count *= sizeof(ElementType);
248  return ObjectBase::readFlash(offset, buffer, count) / sizeof(ElementType);
249  }
250 
251  FSTR_INLINE ElementType unsafeValueAt(const DataPtrType dataptr, unsigned index) const
252  {
253  return readValue(dataptr + index);
254  }
255 };
256 
257 } // namespace FSTR
258 
#define isFlashPtr(ptr)
Simple check to determine if a pointer refers to flash memory.
Definition: Arch/Esp32/Components/libc/src/include/sys/pgmspace.h:24
Used when defining data structures.
Definition: ObjectBase.hpp:33
constexpr FSTR_NOINLINE const size_t length() const
Get the length of the object data in bytes.
Definition: ObjectBase.hpp:38
size_t read(size_t offset, void *buffer, size_t count) const
Read contents of a String into RAM.
const uint32_t flashLength_
Definition: ObjectBase.hpp:118
constexpr const ObjectType & as() const
Cast to a different object type.
Definition: ObjectBase.hpp:67
static constexpr uint32_t copyBit
Set to indicate copy.
Definition: ObjectBase.hpp:123
constexpr const bool isCopy() const
Definition: ObjectBase.hpp:102
const uint8_t * data() const
Get a pointer to the flash data.
static constexpr uint32_t lengthInvalid
Indicates null string in a copy.
Definition: ObjectBase.hpp:124
static const ObjectBase empty_
Definition: ObjectBase.hpp:122
size_t readFlash(size_t offset, void *buffer, size_t count) const
Read contents of a String into RAM, using flashread()
Definition: ObjectIterator.hpp:29
Base class template for all types.
Definition: Object.hpp:125
Iterator begin() const
Definition: Object.hpp:159
size_t readFlash(size_t index, ElementType *buffer, size_t count) const
Read content into RAM,using flashmem_read()
Definition: Object.hpp:244
const ElementType * DataPtrType
Definition: Object.hpp:127
constexpr const size_t length() const
Get the length of the content in elements.
Definition: Object.hpp:180
Object(const Object &&obj)=delete
size_t read(size_t index, ElementType *buffer, size_t count) const
Read content into RAM.
Definition: Object.hpp:230
~Object()
Definition: Object.hpp:151
size_t elementSize() const
Definition: Object.hpp:212
ElementType operator[](unsigned index) const
Array operator[].
Definition: Object.hpp:207
Object()
Creates a null object.
Definition: Object.hpp:133
ElementType valueAt(unsigned index) const
Definition: Object.hpp:199
Object & operator=(const Object &other)=delete
DataPtrType data() const
Definition: Object.hpp:217
Object(const Object &obj)
Copy constructor.
Definition: Object.hpp:147
ObjectIterator< ObjectType, ElementType > Iterator
Definition: Object.hpp:128
Iterator end() const
Definition: Object.hpp:164
ElementType unsafeValueAt(const DataPtrType dataptr, unsigned index) const
Definition: Object.hpp:251
Object & operator=(const Object &&other)=delete
int indexOf(const ValueType &value) const
Definition: Object.hpp:185
static constexpr const ObjectType & empty()
Return an empty object which evaluates to null.
Definition: Object.hpp:172
#define FSTR_INLINE
Definition: config.hpp:28
Definition: Array.hpp:108
std::enable_if< sizeof(T)==1, T >::type readValue(const T *ptr)
Read a typed value from flash memory ensuring correct alignment of access.
Definition: Utility.hpp:126
ObjectType
Definition: Libraries/jerryscript/src/include/Jerryscript/Types.h:34