VRS
A file format for sensor data.
Loading...
Searching...
No Matches
DataLayout.h
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <array>
20
21#include <functional>
22#include <memory>
23#include <ostream>
24#include <string>
25#include <vector>
26
27#include <vrs/ForwardDefinitions.h>
28
29namespace vrs {
30
31using std::ostream;
32using std::string;
33using std::unique_ptr;
34using std::vector;
35
36class DataPiece;
37class AutoDataLayoutEnd;
38
39template <typename T>
40class DataPieceValue;
41template <typename T>
42class DataPieceArray;
43template <typename T>
44class DataPieceVector;
45template <typename T>
46class DataPieceStringMap;
47class DataPieceString;
48
49namespace internal {
50class DataLayouter;
51struct DataPieceFactory;
52} // namespace internal
53
55struct JsonWrapper;
56
58enum class DataPieceType : uint8_t {
59 Undefined = 0,
60 Value = 1,
61 Array = 2,
62 Vector = 3,
63 String = 4,
64 StringMap = 5,
65
66 COUNT
67};
68
76
86 bool publicNames = false;
87 bool prettyJson = false;
88 bool value = false;
89 bool name = true;
90 bool type = true;
91 bool shortType = false;
92 bool index = true;
93 bool defaults = true;
94 bool tags = true;
95 bool properties = true;
96 bool required = true;
97
98 // Default format
99 JsonFormatProfileSpec() = default;
101};
102
211 protected:
212 DataLayout() = default;
213
214 public:
215 DataLayout(const DataLayout&) = delete;
216 DataLayout(const DataLayout&&) = delete;
217
218 virtual ~DataLayout(); // for derived classes
219
220 DataLayout& operator=(const DataLayout&) = delete;
221 DataLayout& operator=(const DataLayout&&) = delete;
222
224 static const size_t kNotFound;
226 static const size_t kVariableSize;
227
228// Pack and use unit32_t because we're storing on disk, and size_t might be 32 or 64 bits
229#pragma pack(push, 1)
232 public:
233 void setOffset(size_t offset) {
234 offset_ = static_cast<uint32_t>(offset);
235 }
236 size_t getOffset() const {
237 return static_cast<uint32_t>(offset_);
238 }
239 void setLength(size_t length) {
240 length_ = static_cast<uint32_t>(length);
241 }
242 size_t getLength() const {
243 return static_cast<uint32_t>(length_);
244 }
245
246 private:
247 uint32_t offset_{};
248 uint32_t length_{};
249 };
250#pragma pack(pop)
251
254
257 vector<int8_t>& getFixedData() {
258 return fixedData_;
259 }
262 vector<int8_t>& getVarData() {
263 return varData_;
264 }
267 size_t getFixedDataSizeNeeded() const {
269 }
270
277
286 size_t getVarDataSizeFromIndex() const;
287
291 size_t getVarDataSizeNeeded() const;
292
300 void collectVariableDataAndUpdateIndex(void* destination);
304 void getRawData(vector<int8_t>& outRawData) const;
310 void stageCurrentValues();
316 bool copyClonedDataPieceValues(const DataLayout& originalLayout);
329 size_t copyDataPieceValuesFromMappedLayout(const DataLayout& mappedLayout);
330
348 bool mapLayout(DataLayout& targetLayout);
351 bool isMapped() const {
352 return mappedDataLayout_ != nullptr;
353 }
359 bool hasAllRequiredPieces() const {
360 return mappedDataLayout_ == nullptr || hasAllRequiredPieces_;
361 }
363 void requireAllPieces();
364
370 void printLayout(ostream& out, const string& indent = "") const;
374 void printLayoutCompact(ostream& out, const string& indent = "") const;
375
380 string asJson(JsonFormatProfile profile) const;
385 string asJson(const JsonFormatProfileSpec& profile = JsonFormatProfileSpec()) const;
386
388 string getListOfPiecesSpec() const;
389
395 bool isSame(const DataLayout& otherLayout) const;
396
401 static unique_ptr<DataLayout> makeFromJson(const string& json);
402
407 template <class T>
408 const DataPieceValue<T>* findDataPieceValue(const string& label) const;
409 template <class T>
410 DataPieceValue<T>* findDataPieceValue(const string& label);
415 template <class T>
416 const DataPieceArray<T>* findDataPieceArray(const string& label, size_t arraySize) const;
417 template <class T>
418 DataPieceArray<T>* findDataPieceArray(const string& label, size_t arraySize);
423 template <class T>
424 const DataPieceVector<T>* findDataPieceVector(const string& label) const;
425 template <class T>
426 DataPieceVector<T>* findDataPieceVector(const string& label);
431 template <class T>
432 const DataPieceStringMap<T>* findDataPieceStringMap(const string& label) const;
433 template <class T>
434 DataPieceStringMap<T>* findDataPieceStringMap(const string& label);
439 const DataPieceString* findDataPieceString(const string& label) const;
440 DataPieceString* findDataPieceString(const string& label);
445 const std::function<void(const DataPiece*)>&,
449 const std::function<void(DataPiece*)>&,
451
455 bool isVarDataIndexValid() const;
459 return fixedSizePieces_.size();
460 }
464 return varSizePieces_.size();
465 }
475 size_t getAvailableVarDataPiecesCount() const;
476
477 protected:
483 template <class T>
484 T* getFixedData(size_t offset, size_t size) {
485 if (mappedDataLayout_ != nullptr) {
486 return mappedDataLayout_->getFixedData<T>(offset, size);
487 }
488 if (offset != kNotFound && offset + size <= fixedData_.size()) {
489 return reinterpret_cast<T*>(fixedData_.data() + offset);
490 }
491 return nullptr;
492 }
496 const IndexEntry* getVarSizeIndex() const;
500 IndexEntry* getVarSizeIndex();
506 template <class T>
507 T* getVarData(size_t varPieceIndex, size_t& outCount) {
508 if (mappedDataLayout_ != nullptr) {
509 return mappedDataLayout_->getVarData<T>(varPieceIndex, outCount);
510 }
511 if (varPieceIndex < varSizePieces_.size()) {
512 const IndexEntry& indexEntry = getVarSizeIndex()[varPieceIndex];
513 if (indexEntry.getOffset() + indexEntry.getLength() <= varData_.size()) {
514 outCount = indexEntry.getLength() / sizeof(T);
515 return reinterpret_cast<T*>(varData_.data() + indexEntry.getOffset());
516 }
517 }
518 outCount = 0;
519 return nullptr;
520 }
522 DataPiece* getPieceByIndex(size_t pieceIndex);
524 template <class T>
525 T* getMappedPiece(size_t pieceIndex) const {
526 return mappedDataLayout_ != nullptr
527 ? static_cast<T*>(mappedDataLayout_->getPieceByIndex(pieceIndex))
528 : nullptr;
529 }
530
535 void initLayout();
536
540 void serialize(JsonWrapper& rj, const JsonFormatProfileSpec& profile) const;
541
542 static DataPiece* findMatch(DataPiece* piece, const vector<DataPiece*>& pieces, size_t& start);
543 static bool mapPieces(
544 const vector<DataPiece*>& searchPieces,
545 const vector<DataPiece*>& givenPieces);
546 static size_t copyMappedValues(
547 const vector<DataPiece*>& pieces,
548 const vector<DataPiece*>& mappedPieces);
549
550 friend class internal::DataLayouter;
551 friend class DataPiece;
552 template <class T>
553 friend class DataPieceValue;
554 template <class T>
555 friend class DataPieceArray;
556 template <class T>
557 friend class DataPieceVector;
558 template <class T>
559 friend class DataPieceStringMap;
560 friend class DataPieceString;
561
563 vector<DataPiece*> fixedSizePieces_;
565 vector<DataPiece*> varSizePieces_;
567 vector<int8_t> fixedData_;
571 vector<int8_t> varData_;
576};
577
580 public:
582 initLayout();
583 }
584};
585
605 public:
607};
608
611 public:
613};
614
620 public:
623 explicit ManualDataLayout(const string& json);
624
629 explicit ManualDataLayout(const DataLayout& layout);
630
631 ~ManualDataLayout() override;
632
638 DataPiece* add(unique_ptr<DataPiece> dataPiece);
639
641 void endLayout();
642
643 private:
644 vector<unique_ptr<DataPiece>> manualPieces;
645 bool layoutInProgress_;
646};
647
681 explicit DataLayoutStruct(const string& structName);
682 static void dataLayoutStructEnd(const string& structName);
683};
684
685#define DATA_LAYOUT_STRUCT(DATA_LAYOUT_STRUCT_TYPE) \
686 explicit DATA_LAYOUT_STRUCT_TYPE(const std::string& _structName_) \
687 : DataLayoutStruct(_structName_) { \
688 dataLayoutStructEnd(_structName_); \
689 }
690
691#define DATA_LAYOUT_STRUCT_WITH_INIT(DATA_LAYOUT_STRUCT_TYPE) \
692 explicit DATA_LAYOUT_STRUCT_TYPE(const std::string& _structName_) \
693 : DataLayoutStruct(_structName_) { \
694 dataLayoutStructEnd(_structName_); \
695 init(); \
696 }
697
726template <typename T, size_t Size>
728 DATA_LAYOUT_STRUCT(DataLayoutStructArray)
729 std::array<T, Size> array{createArrayHelper<T>(std::make_index_sequence<Size>())};
730
731 T& operator[](const size_t index) {
732 return array[index];
733 }
734
735 constexpr const T& operator[](const size_t index) const {
736 return array[index];
737 }
738
739 constexpr std::size_t size() const noexcept {
740 return array.size();
741 }
742
743 template <typename S, size_t... Indices>
744 static constexpr auto createArrayHelper(std::index_sequence<Indices...>) {
745 return std::array<S, sizeof...(Indices)>{S{std::to_string(Indices)}...};
746 }
747};
748
752template <class OptionalFields>
753class OptionalDataPieces : public std::unique_ptr<OptionalFields> {
754 public:
755 explicit OptionalDataPieces(bool allocateFields)
756 : std::unique_ptr<OptionalFields>(
757 allocateFields ? std::make_unique<OptionalFields>() : nullptr) {}
758};
759
760} // namespace vrs
For use within an AutoDataLayout class, to end the AutoDataLayout's construction.
Definition DataLayout.h:610
Specialized DataLayout class to declare a DataLayout in struct format.
Definition DataLayout.h:604
Specification of a VRS record content block.
Definition RecordFormat.h:510
Describes where the data of a variable size DataPiece is in the varData_ buffer.
Definition DataLayout.h:231
The DataLayout class describes the data stored inside a DataLayoutContentBlock.
Definition DataLayout.h:210
vector< DataPiece * > fixedSizePieces_
Ordered fixed-size DataPieces.
Definition DataLayout.h:563
T * getFixedData(size_t offset, size_t size)
Definition DataLayout.h:484
static unique_ptr< DataLayout > makeFromJson(const string &json)
Definition DataLayout.cpp:373
void initLayout()
Definition DataLayout.cpp:288
bool hasAllRequiredPieces() const
Definition DataLayout.h:359
const DataPieceValue< T > * findDataPieceValue(const string &label) const
Definition DataLayout.cpp:575
size_t getVarDataSizeFromIndex() const
Definition DataLayout.cpp:360
size_t fixedDataSizeNeeded_
Byte count for all the fixed size pieces + var size index.
Definition DataLayout.h:569
static const size_t kVariableSize
Special value used for a DataPiece size, telling that that DataPiece has a variable size.
Definition DataLayout.h:226
void forEachDataPiece(const std::function< void(const DataPiece *)> &, DataPieceType type=DataPieceType::Undefined) const
void requireAllPieces()
Mark all the fields of the layout as required.
Definition DataLayout.cpp:196
void printLayoutCompact(ostream &out, const string &indent="") const
Definition DataLayout.cpp:223
const DataPieceArray< T > * findDataPieceArray(const string &label, size_t arraySize) const
Definition DataLayout.cpp:593
void initDataPiecesToDefaultValue()
Definition DataLayout.cpp:165
T * getVarData(size_t varPieceIndex, size_t &outCount)
Definition DataLayout.h:507
void serialize(JsonWrapper &rj, const JsonFormatProfileSpec &profile) const
Definition DataLayout.cpp:250
size_t getAvailableFixedDataPiecesCount() const
Definition DataLayout.cpp:779
vector< int8_t > & getVarData()
Definition DataLayout.h:262
const IndexEntry * getVarSizeIndex() const
Definition DataLayout.cpp:709
size_t getAvailableVarDataPiecesCount() const
Definition DataLayout.cpp:789
bool copyClonedDataPieceValues(const DataLayout &originalLayout)
Definition DataLayout.cpp:330
ContentBlock getContentBlock() const
Definition DataLayout.cpp:282
vector< DataPiece * > varSizePieces_
Ordered variable-size DataPieces.
Definition DataLayout.h:565
bool isSame(const DataLayout &otherLayout) const
Definition DataLayout.cpp:377
bool hasAllRequiredPieces_
Tells all the required pieces have been mapped successfully.
Definition DataLayout.h:573
string getListOfPiecesSpec() const
Get a text list of fields, types & names, one per line. Useful for tests.
Definition DataLayout.cpp:270
void stageCurrentValues()
Definition DataLayout.cpp:323
bool isMapped() const
Definition DataLayout.h:351
size_t getFixedDataSizeNeeded() const
Definition DataLayout.h:267
void collectVariableDataAndUpdateIndex()
Definition DataLayout.cpp:62
bool isVarDataIndexValid() const
Definition DataLayout.cpp:725
static const size_t kNotFound
Special OffsetAndLength offset value marking that a piece of data isn't available.
Definition DataLayout.h:224
size_t copyDataPieceValuesFromMappedLayout(const DataLayout &mappedLayout)
Definition DataLayout.cpp:177
vector< int8_t > & getFixedData()
Definition DataLayout.h:257
const DataPieceString * findDataPieceString(const string &label) const
Definition DataLayout.cpp:657
const DataPieceVector< T > * findDataPieceVector(const string &label) const
Definition DataLayout.cpp:613
size_t getVarDataSizeNeeded() const
Definition DataLayout.cpp:54
T * getMappedPiece(size_t pieceIndex) const
Get a typed piece by index in the mapped datalayout, exclusively.
Definition DataLayout.h:525
bool mapLayout(DataLayout &targetLayout)
Definition DataLayout.cpp:130
const DataPieceStringMap< T > * findDataPieceStringMap(const string &label) const
Definition DataLayout.cpp:635
void printLayout(ostream &out, const string &indent="") const
Definition DataLayout.cpp:205
void getRawData(vector< int8_t > &outRawData) const
Definition DataLayout.cpp:309
size_t getDeclaredVarDataPiecesCount() const
Definition DataLayout.h:463
size_t getDeclaredFixedDataPiecesCount() const
Definition DataLayout.h:458
void forEachDataPiece(const std::function< void(DataPiece *)> &, DataPieceType type=DataPieceType::Undefined)
Same as above, but as a non-const version.
vector< int8_t > fixedData_
Buffer to hold fixed-size pieces, and the index of var size pieces (if any).
Definition DataLayout.h:567
DataLayout * mappedDataLayout_
DataLayout this layout has been mapped to, if any.
Definition DataLayout.h:575
string asJson(JsonFormatProfile profile) const
Definition DataLayout.cpp:237
vector< int8_t > varData_
Buffer holding variable-size pieces, after they've been collected, or read from disk.
Definition DataLayout.h:571
DataPiece * getPieceByIndex(size_t pieceIndex)
Get a piece by index, fixed size pieces first, then variable size pieces.
Definition DataLayout.cpp:187
Fixed size array of POD values.
Definition DataPieceArray.h:39
Abstract class representing a piece of information part of a DataLayout.
Definition DataPieces.h:40
DataPiece for variable length string.
Definition DataPieceString.h:36
DataPiece map container, with string keys and values of type T.
Definition DataPieceStringMap.h:36
DataPiece for a single value of type T. The value is stored in DataLayout's fixed size buffer.
Definition DataPieceValue.h:37
Vector of type T and variable size.
Definition DataPieceVector.h:37
When you just need a placeholder for a DataLayout.
Definition DataLayout.h:579
Specialized DataLayout for programmatic DataLayout generation.
Definition DataLayout.h:619
void endLayout()
End the construction of the DataLayout. Do not call add() after calling this method.
Definition DataLayout.cpp:1923
ManualDataLayout()
For manual construction using "add()": don't forget to call endLayout() when you're done.
Definition DataLayout.cpp:1853
DataPiece * add(unique_ptr< DataPiece > dataPiece)
Definition DataLayout.cpp:1915
Helper function to allocate optional fields only when it is enabled.
Definition DataLayout.h:753
Helper class to manage the registration of DataPiece objects within a single DataLayout.
Definition DataLayout.cpp:408
Definition Compressor.cpp:113
@ Undefined
when not set explicitly
JsonFormatProfile
Enum for a DataLayout printout json formatting profile.
Definition DataLayout.h:70
@ ExternalCompact
for external tools (VRStools in particular), but compact.
@ VrsFormat
for internal VRS usage. (default)
@ Public
for public use cases, avoiding VRS internal names
@ ExternalPretty
for external tools (VRStools in particular), formatted for readability.
DataPieceType
Specifier for a type of DataPiece.
Definition DataLayout.h:58
@ String
Variable size array of char, null terminated.
@ Array
Fixed size array.
@ Vector
Variable size array of T.
@ Value
Single value.
@ StringMap
Map with string keys, and T values.
@ Undefined
Undefined type.
Helper class to include DataLayout structs containing a sliced array of DataPieceXXX and DataLayoutSt...
Definition DataLayout.h:727
Helper class to include DataLayout structs containing a set of DataPieceXXX and DataLayoutStruct whil...
Definition DataLayout.h:680
When printing out a DataLayout as json, this class allows to specify what should be included in the g...
Definition DataLayout.h:85
bool tags
Include tags.
Definition DataLayout.h:94
bool shortType
Use the short version of the type names.
Definition DataLayout.h:91
bool required
Include the required flag.
Definition DataLayout.h:96
bool defaults
Include default values.
Definition DataLayout.h:93
bool value
Include the value of the data piece elements.
Definition DataLayout.h:88
bool publicNames
Use internal names, or public names. "data_layout" vs. "metadata".
Definition DataLayout.h:86
bool name
Include the label name.
Definition DataLayout.h:89
bool prettyJson
Format the text so that it is easier to read.
Definition DataLayout.h:87
bool type
Include the type name.
Definition DataLayout.h:90
bool properties
Includes properties.
Definition DataLayout.h:95
bool index
Include the index of the data pieces.
Definition DataLayout.h:92