jaffarCommon
Loading...
Searching...
No Matches
serializers/differential.hpp
Go to the documentation of this file.
1#pragma once
2
8#include "base.hpp"
9#include <limits>
10#include <string.h>
11#include <xdelta3/xdelta3.h>
12
13namespace jaffarCommon
14{
15
16namespace serializer
17{
18
27class Differential final : public serializer::Base
28{
29public:
39 Differential(void* __restrict outputDataBuffer = nullptr, const size_t outputDataBufferSize = std::numeric_limits<uint32_t>::max(),
40 const void* __restrict referenceDataBuffer = nullptr, const size_t referenceDataBufferSize = std::numeric_limits<uint32_t>::max(), const bool useZlib = false)
41 : serializer::Base(outputDataBuffer, outputDataBufferSize)
42 , _referenceDataBuffer((const uint8_t*)referenceDataBuffer)
43 , _referenceDataBufferSize(referenceDataBufferSize)
44 , _useZlib(useZlib)
45 {
46 }
47
48 ~Differential() = default;
49
50 __JAFFAR_COMMON__INLINE__ void pushContiguous(const void* const __restrict inputData = nullptr, const size_t inputDataSize = 0) override
51 {
52 // Only perform memcpy if the output block is not null
53 if (_outputDataBuffer != nullptr && inputData != nullptr) memcpy(&_outputDataBuffer[_outputDataBufferPos], inputData, inputDataSize);
54
55 // Making sure we do not exceed the maximum size estipulated
56 if (_outputDataBufferPos + inputDataSize > _outputDataBufferSize)
57 JAFFAR_THROW_RUNTIME("Maximum output data position reached before contiguous serialization (%lu + %lu > %lu)", _outputDataBufferPos, inputDataSize, _outputDataBufferSize);
58 if (_referenceDataBufferPos + inputDataSize > _referenceDataBufferSize)
59 JAFFAR_THROW_RUNTIME("[Error] Maximum reference data position exceeded on contiguous deserialization (%lu + %lu > %lu)", _referenceDataBufferPos, inputDataSize,
60 _referenceDataBufferSize);
61
62 // Moving output data pointer position
63 _outputDataBufferPos += inputDataSize;
64
65 // Moving reference data pointer position
66 _referenceDataBufferPos += inputDataSize;
67 }
68
69 __JAFFAR_COMMON__INLINE__ void push(const void* const __restrict inputData, const size_t inputDataSize) override
70 {
71 // If output data buffer is null, then we simply ignore differential data.
72 if (_outputDataBuffer == nullptr || inputData == nullptr) return;
73
74 // Check that we don't exceed reference data size
75 if (_referenceDataBufferPos + inputDataSize > _referenceDataBufferSize)
76 JAFFAR_THROW_RUNTIME("[Error] Differential compression size exceeds reference data buffer size (%lu + %lu > %lu)", _referenceDataBufferPos, inputDataSize,
77 _referenceDataBufferSize);
78
79 // Variable to store difference count
80 auto diffCount = (usize_t*)&_outputDataBuffer[_outputDataBufferPos];
81
82 // Size of differential buffer size
83 const size_t differentialBufferSize = sizeof(usize_t);
84
85 // If we reached maximum output, stop here
86 if (_outputDataBufferPos + differentialBufferSize >= _outputDataBufferSize)
87 JAFFAR_THROW_RUNTIME("[Error] Maximum output data position reached before differential encode (%lu + %lu > %lu)", _outputDataBufferPos, differentialBufferSize,
89
90 // Advancing position pointer to store the difference counter
91 _outputDataBufferPos += differentialBufferSize;
92
93 // Encoding differential
94 int ret = xd3_encode_memory((const uint8_t*)inputData, inputDataSize, &_referenceDataBuffer[_referenceDataBufferPos], inputDataSize, &_outputDataBuffer[_outputDataBufferPos],
95 diffCount, _outputDataBufferSize - _outputDataBufferPos, _useZlib ? 0 : XD3_NOCOMPRESS);
96
97 // If an error happened, print it here
98 if (ret != 0)
99 JAFFAR_THROW_RUNTIME("[Error] unexpected error while encoding differential compression. Probably maximum size increased: (%lu + %lu > %lu)", _outputDataBufferPos, *diffCount,
101
102 // Increasing output data position pointer
103 _outputDataBufferPos += *diffCount;
104
105 // Increasing the number of differential bytes processed
106 _differentialBytesCount += *diffCount;
107
108 // Finally, increasing reference data position pointer
109 _referenceDataBufferPos += inputDataSize;
110 }
111
117 size_t getReferenceDataBufferPos() const { return _referenceDataBufferPos; }
118
126 size_t getDifferentialBytesCount() const { return _differentialBytesCount; }
127
128private:
132 const uint8_t* __restrict const _referenceDataBuffer;
133
137 const size_t _referenceDataBufferSize;
138
142 size_t _referenceDataBufferPos = 0;
143
147 size_t _differentialBytesCount = 0;
148
152 const bool _useZlib;
153};
154
155} // namespace serializer
156
157} // namespace jaffarCommon
Definition serializers/base.hpp:24
size_t _outputDataBufferPos
Definition serializers/base.hpp:84
const size_t _outputDataBufferSize
Definition serializers/base.hpp:79
uint8_t *__restrict const _outputDataBuffer
Definition serializers/base.hpp:74
Definition serializers/differential.hpp:28
__JAFFAR_COMMON__INLINE__ void pushContiguous(const void *const __restrict inputData=nullptr, const size_t inputDataSize=0) override
Definition serializers/differential.hpp:50
size_t getReferenceDataBufferPos() const
Definition serializers/differential.hpp:117
__JAFFAR_COMMON__INLINE__ void push(const void *const __restrict inputData, const size_t inputDataSize) override
Definition serializers/differential.hpp:69
size_t getDifferentialBytesCount() const
Definition serializers/differential.hpp:126
Differential(void *__restrict outputDataBuffer=nullptr, const size_t outputDataBufferSize=std::numeric_limits< uint32_t >::max(), const void *__restrict referenceDataBuffer=nullptr, const size_t referenceDataBufferSize=std::numeric_limits< uint32_t >::max(), const bool useZlib=false)
Definition serializers/differential.hpp:39
#define JAFFAR_THROW_RUNTIME(...)
Definition exceptions.hpp:22
Contains the base class for the data serializers.