File indexing completed on 2024-05-12 05:25:58

0001 #pragma once
0002 
0003 #include "sink_export.h"
0004 #include <functional>
0005 #include <flatbuffers/flatbuffers.h>
0006 #include "metadata_generated.h"
0007 #include <QByteArray>
0008 
0009 namespace Sink {
0010 struct Entity;
0011 
0012 class SINK_EXPORT EntityBuffer
0013 {
0014 public:
0015     /**
0016      * Creates an entity buffer from @param dataValue.
0017      *
0018      * Note that @param dataValue will need to remain valid and the data is not copied.
0019      */
0020     EntityBuffer(const void *dataValue, int size);
0021 
0022     /**
0023      * Creates an entity buffer from @param data.
0024      *
0025      * Note that @param data will need to remain valid and the data is not copied.
0026      */
0027     EntityBuffer(const QByteArray &data);
0028     const uint8_t *resourceBuffer() const;
0029     const uint8_t *metadataBuffer() const;
0030     const uint8_t *localBuffer() const;
0031     const Entity &entity() const;
0032     bool isValid() const;
0033 
0034     Sink::Operation operation() const;
0035     qint64 revision() const;
0036 
0037     static void extractResourceBuffer(void *dataValue, int dataSize, const std::function<void(const uint8_t *, size_t size)> &handler);
0038     /*
0039      * TODO: Ideally we would be passing references to vectors in the same bufferbuilder, to avoid needlessly copying data.
0040      * Unfortunately I couldn't find a way to cast a table to a vector<uint8_t> reference.
0041      * We can't use union's either (which would allow to have a field that stores a selection of tables), as we don't want to modify
0042      * the entity schema for each resource's buffers.
0043      */
0044     static void assembleEntityBuffer(
0045         flatbuffers::FlatBufferBuilder &fbb, void const *metadataData, size_t metadataSize, void const *resourceData, size_t resourceSize, void const *localData, size_t localSize);
0046     static flatbuffers::Offset<flatbuffers::Vector<uint8_t>> appendAsVector(flatbuffers::FlatBufferBuilder &fbb, void const *data, size_t size);
0047     template <typename T>
0048     static const T *readBuffer(const uint8_t *data, int size)
0049     {
0050         flatbuffers::Verifier verifier(data, size);
0051         if (verifier.VerifyBuffer<T>(nullptr)) {
0052             return flatbuffers::GetRoot<T>(data);
0053         }
0054         return nullptr;
0055     }
0056 
0057     template <typename T>
0058     static const T *readBuffer(const flatbuffers::Vector<uint8_t> *data)
0059     {
0060         if (data) {
0061             return readBuffer<T>(data->Data(), data->size());
0062         }
0063         return nullptr;
0064     }
0065 
0066 
0067 private:
0068     const Entity *mEntity;
0069 };
0070 }