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#include <vrs/VrsExport.h>
29
30namespace vrs {
31
32using std::ostream;
33using std::string;
34using std::unique_ptr;
35using std::vector;
36
37class DataPiece;
38class AutoDataLayoutEnd;
39
40template <typename T>
41class DataPieceValue;
42template <typename T>
43class DataPieceArray;
44template <typename T>
45class DataPieceVector;
46template <typename T>
47class DataPieceStringMap;
48class DataPieceString;
49
50namespace internal {
51class DataLayouter;
52struct DataPieceFactory;
53} // namespace internal
54
56struct JsonWrapper;
57
59enum class DataPieceType : uint8_t {
60 Undefined = 0,
61 Value = 1,
62 Array = 2,
63 Vector = 3,
64 String = 4,
65 StringMap = 5,
66
67 COUNT
68};
69
77
86struct VRS_API JsonFormatProfileSpec {
87 bool publicNames = false;
88 bool prettyJson = false;
89 bool value = false;
90 bool name = true;
91 bool type = true;
92 bool shortType = false;
93 bool index = true;
94 bool defaults = true;
95 bool tags = true;
96 bool properties = true;
97 bool required = true;
98
99 // Default format
100 JsonFormatProfileSpec() = default;
102};
103
211class VRS_API DataLayout {
212 protected:
213 DataLayout() = default;
214
215 public:
216 DataLayout(const DataLayout&) = delete;
217 DataLayout(const DataLayout&&) = delete;
218
219 virtual ~DataLayout(); // for derived classes
220
221 DataLayout& operator=(const DataLayout&) = delete;
222 DataLayout& operator=(const DataLayout&&) = delete;
223
225 static const size_t kNotFound;
227 static const size_t kVariableSize;
228
229// Pack and use unit32_t because we're storing on disk, and size_t might be 32 or 64 bits
230#pragma pack(push, 1)
233 public:
234 void setOffset(size_t offset) {
235 offset_ = static_cast<uint32_t>(offset);
236 }
237 size_t getOffset() const {
238 return static_cast<uint32_t>(offset_);
239 }
240 void setLength(size_t length) {
241 length_ = static_cast<uint32_t>(length);
242 }
243 size_t getLength() const {
244 return static_cast<uint32_t>(length_);
245 }
246
247 private:
248 uint32_t offset_{};
249 uint32_t length_{};
250 };
251#pragma pack(pop)
252
254 ContentBlock getContentBlock() const;
255
258 vector<int8_t>& getFixedData() {
259 return fixedData_;
260 }
263 vector<int8_t>& getVarData() {
264 return varData_;
265 }
268 size_t getFixedDataSizeNeeded() const {
269 return fixedDataSizeNeeded_;
270 }
271
277 void initDataPiecesToDefaultValue();
278
287 size_t getVarDataSizeFromIndex() const;
288
292 size_t getVarDataSizeNeeded() const;
293
296 void collectVariableDataAndUpdateIndex();
301 void collectVariableDataAndUpdateIndex(void* destination);
305 void getRawData(vector<int8_t>& outRawData) const;
311 void stageCurrentValues();
317 bool copyClonedDataPieceValues(const DataLayout& originalLayout);
330 size_t copyDataPieceValuesFromMappedLayout(const DataLayout& mappedLayout);
331
349 bool mapLayout(DataLayout& targetLayout);
352 bool isMapped() const {
353 return mappedDataLayout_ != nullptr;
354 }
360 bool hasAllRequiredPieces() const {
361 return mappedDataLayout_ == nullptr || hasAllRequiredPieces_;
362 }
364 void requireAllPieces();
365
371 void printLayout(ostream& out, const string& indent = "") const;
375 void printLayoutCompact(ostream& out, const string& indent = "") const;
376
381 string asJson(JsonFormatProfile profile) const;
386 string asJson(const JsonFormatProfileSpec& profile = JsonFormatProfileSpec()) const;
387
389 string getListOfPiecesSpec() const;
390
396 bool isSame(const DataLayout& otherLayout) const;
397
402 static unique_ptr<DataLayout> makeFromJson(const string& json);
403
408 template <class T>
409 const DataPieceValue<T>* findDataPieceValue(const string& label) const;
410 template <class T>
411 DataPieceValue<T>* findDataPieceValue(const string& label);
416 template <class T>
417 const DataPieceArray<T>* findDataPieceArray(const string& label, size_t arraySize) const;
418 template <class T>
419 DataPieceArray<T>* findDataPieceArray(const string& label, size_t arraySize);
424 template <class T>
425 const DataPieceVector<T>* findDataPieceVector(const string& label) const;
426 template <class T>
427 DataPieceVector<T>* findDataPieceVector(const string& label);
432 template <class T>
433 const DataPieceStringMap<T>* findDataPieceStringMap(const string& label) const;
434 template <class T>
435 DataPieceStringMap<T>* findDataPieceStringMap(const string& label);
440 const DataPieceString* findDataPieceString(const string& label) const;
441 DataPieceString* findDataPieceString(const string& label);
446 const std::function<void(const DataPiece*)>&,
447 DataPieceType type = DataPieceType::Undefined) const;
450 const std::function<void(DataPiece*)>&,
451 DataPieceType type = DataPieceType::Undefined);
452
456 bool isVarDataIndexValid() const;
460 return fixedSizePieces_.size();
461 }
465 return varSizePieces_.size();
466 }
471 size_t getAvailableFixedDataPiecesCount() const;
476 size_t getAvailableVarDataPiecesCount() const;
477
478 protected:
484 template <class T>
485 T* getFixedData(size_t offset, size_t size) {
486 if (mappedDataLayout_ != nullptr) {
487 return mappedDataLayout_->getFixedData<T>(offset, size);
488 }
489 if (offset != kNotFound && offset + size <= fixedData_.size()) {
490 return reinterpret_cast<T*>(fixedData_.data() + offset);
491 }
492 return nullptr;
493 }
497 const IndexEntry* getVarSizeIndex() const;
501 IndexEntry* getVarSizeIndex();
507 template <class T>
508 T* getVarData(size_t varPieceIndex, size_t& outCount) {
509 if (mappedDataLayout_ != nullptr) {
510 return mappedDataLayout_->getVarData<T>(varPieceIndex, outCount);
511 }
512 if (varPieceIndex < varSizePieces_.size()) {
513 const IndexEntry& indexEntry = getVarSizeIndex()[varPieceIndex];
514 if (indexEntry.getOffset() + indexEntry.getLength() <= varData_.size()) {
515 outCount = indexEntry.getLength() / sizeof(T);
516 return reinterpret_cast<T*>(varData_.data() + indexEntry.getOffset());
517 }
518 }
519 outCount = 0;
520 return nullptr;
521 }
523 DataPiece* getPieceByIndex(size_t pieceIndex);
525 template <class T>
526 T* getMappedPiece(size_t pieceIndex) const {
527 return mappedDataLayout_ != nullptr
528 ? static_cast<T*>(mappedDataLayout_->getPieceByIndex(pieceIndex))
529 : nullptr;
530 }
531
536 void initLayout();
537
541 void serialize(JsonWrapper& rj, const JsonFormatProfileSpec& profile) const;
542
543 static DataPiece* findMatch(DataPiece* piece, const vector<DataPiece*>& pieces, size_t& start);
544 static bool mapPieces(
545 const vector<DataPiece*>& searchPieces,
546 const vector<DataPiece*>& givenPieces);
547 static size_t copyMappedValues(
548 const vector<DataPiece*>& pieces,
549 const vector<DataPiece*>& mappedPieces);
550
551 friend class internal::DataLayouter;
552 friend class DataPiece;
553 template <class T>
554 friend class DataPieceValue;
555 template <class T>
556 friend class DataPieceArray;
557 template <class T>
558 friend class DataPieceVector;
559 template <class T>
560 friend class DataPieceStringMap;
561 friend class DataPieceString;
562
564 vector<DataPiece*> fixedSizePieces_;
566 vector<DataPiece*> varSizePieces_;
568 vector<int8_t> fixedData_;
570 size_t fixedDataSizeNeeded_{};
572 vector<int8_t> varData_;
574 bool hasAllRequiredPieces_{true};
576 DataLayout* mappedDataLayout_{};
577};
578
580class VRS_API EmptyDataLayout : public DataLayout {
581 public:
583 initLayout();
584 }
585};
586
605class VRS_API AutoDataLayout : public DataLayout {
606 public:
608};
609
611class VRS_API AutoDataLayoutEnd {
612 public:
614};
615
620class VRS_API ManualDataLayout : public DataLayout {
621 public:
624 explicit ManualDataLayout(const string& json);
625
630 explicit ManualDataLayout(const DataLayout& layout);
631
632 ~ManualDataLayout() override;
633
639 DataPiece* add(unique_ptr<DataPiece> dataPiece);
640
642 void endLayout();
643
644 private:
645 vector<unique_ptr<DataPiece>> manualPieces;
646 bool layoutInProgress_;
647};
648
681struct VRS_API DataLayoutStruct {
682 explicit DataLayoutStruct(const string& structName);
683 static void dataLayoutStructEnd(const string& structName);
684};
685
686#define DATA_LAYOUT_STRUCT(DATA_LAYOUT_STRUCT_TYPE) \
687 explicit DATA_LAYOUT_STRUCT_TYPE(const std::string& _structName_) \
688 : DataLayoutStruct(_structName_) { \
689 dataLayoutStructEnd(_structName_); \
690 }
691
692#define DATA_LAYOUT_STRUCT_WITH_INIT(DATA_LAYOUT_STRUCT_TYPE) \
693 explicit DATA_LAYOUT_STRUCT_TYPE(const std::string& _structName_) \
694 : DataLayoutStruct(_structName_) { \
695 dataLayoutStructEnd(_structName_); \
696 init(); \
697 }
698
727template <typename T, size_t Size>
729 DATA_LAYOUT_STRUCT(DataLayoutStructArray)
730 std::array<T, Size> array{createArrayHelper<T>(std::make_index_sequence<Size>())};
731
732 T& operator[](const size_t index) {
733 return array[index];
734 }
735
736 constexpr const T& operator[](const size_t index) const {
737 return array[index];
738 }
739
740 constexpr std::size_t size() const noexcept {
741 return array.size();
742 }
743
744 template <typename S, size_t... Indices>
745 static constexpr auto createArrayHelper(std::index_sequence<Indices...>) {
746 return std::array<S, sizeof...(Indices)>{S{std::to_string(Indices)}...};
747 }
748};
749
753template <class OptionalFields>
754class OptionalDataPieces : public std::unique_ptr<OptionalFields> {
755 public:
756 explicit OptionalDataPieces(bool allocateFields)
757 : std::unique_ptr<OptionalFields>(
758 allocateFields ? std::make_unique<OptionalFields>() : nullptr) {}
759};
760
761} // namespace vrs
For use within an AutoDataLayout class, to end the AutoDataLayout's construction.
Definition DataLayout.h:611
Specialized DataLayout class to declare a DataLayout in struct format.
Definition DataLayout.h:605
Specification of a VRS record content block.
Definition RecordFormat.h:512
Describes where the data of a variable size DataPiece is in the varData_ buffer.
Definition DataLayout.h:232
The DataLayout class describes the data stored inside a DataLayoutContentBlock.
Definition DataLayout.h:211
vector< DataPiece * > fixedSizePieces_
Ordered fixed-size DataPieces.
Definition DataLayout.h:564
T * getFixedData(size_t offset, size_t size)
Definition DataLayout.h:485
bool hasAllRequiredPieces() const
Definition DataLayout.h:360
static const size_t kVariableSize
Special value used for a DataPiece size, telling that that DataPiece has a variable size.
Definition DataLayout.h:227
void forEachDataPiece(const std::function< void(const DataPiece *)> &, DataPieceType type=DataPieceType::Undefined) const
T * getVarData(size_t varPieceIndex, size_t &outCount)
Definition DataLayout.h:508
vector< int8_t > & getVarData()
Definition DataLayout.h:263
vector< DataPiece * > varSizePieces_
Ordered variable-size DataPieces.
Definition DataLayout.h:566
bool isMapped() const
Definition DataLayout.h:352
size_t getFixedDataSizeNeeded() const
Definition DataLayout.h:268
static const size_t kNotFound
Special OffsetAndLength offset value marking that a piece of data isn't available.
Definition DataLayout.h:225
vector< int8_t > & getFixedData()
Definition DataLayout.h:258
T * getMappedPiece(size_t pieceIndex) const
Get a typed piece by index in the mapped datalayout, exclusively.
Definition DataLayout.h:526
size_t getDeclaredVarDataPiecesCount() const
Definition DataLayout.h:464
size_t getDeclaredFixedDataPiecesCount() const
Definition DataLayout.h:459
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:568
vector< int8_t > varData_
Buffer holding variable-size pieces, after they've been collected, or read from disk.
Definition DataLayout.h:572
Fixed size array of POD values.
Definition DataPieceArray.h:39
Abstract class representing a piece of information part of a DataLayout.
Definition DataPieces.h:42
DataPiece for variable length string.
Definition DataPieceString.h:38
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:580
Specialized DataLayout for programmatic DataLayout generation.
Definition DataLayout.h:620
Helper function to allocate optional fields only when it is enabled.
Definition DataLayout.h:754
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:71
@ 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:59
@ 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.
Helper class to include DataLayout structs containing a sliced array of DataPieceXXX and DataLayoutSt...
Definition DataLayout.h:728
Helper class to include DataLayout structs containing a set of DataPieceXXX and DataLayoutStruct whil...
Definition DataLayout.h:681
When printing out a DataLayout as json, this class allows to specify what should be included in the g...
Definition DataLayout.h:86