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 // Making sure we do not exceed the maximum size estipulated -- this must happen BEFORE the memcpy
53 // to actually prevent the overflow, not merely detect it after the buffer has been corrupted
54 if (_outputDataBufferPos + inputDataSize > _outputDataBufferSize)
55 JAFFAR_THROW_RUNTIME("Maximum output data position reached before contiguous serialization (%lu + %lu > %lu)", _outputDataBufferPos, inputDataSize, _outputDataBufferSize);
56 if (_referenceDataBufferPos + inputDataSize > _referenceDataBufferSize)
57 JAFFAR_THROW_RUNTIME("[Error] Maximum reference data position exceeded on contiguous deserialization (%lu + %lu > %lu)", _referenceDataBufferPos, inputDataSize,
58 _referenceDataBufferSize);
59
60 // Only perform memcpy if the output block is not null
61 if (_outputDataBuffer != nullptr && inputData != nullptr) memcpy(&_outputDataBuffer[_outputDataBufferPos], inputData, inputDataSize);
62
63 // Moving output data pointer position
64 _outputDataBufferPos += inputDataSize;
65
66 // Moving reference data pointer position
67 _referenceDataBufferPos += inputDataSize;
68 }
69
70 __JAFFAR_COMMON_INLINE__ void push(const void* const __restrict inputData, const size_t inputDataSize) override
71 {
72 // If output data buffer is null, then we simply ignore differential data.
73 if (_outputDataBuffer == nullptr || inputData == nullptr) return;
74
75 // Check that we don't exceed reference data size
76 if (_referenceDataBufferPos + inputDataSize > _referenceDataBufferSize)
77 JAFFAR_THROW_RUNTIME("[Error] Differential compression size exceeds reference data buffer size (%lu + %lu > %lu)", _referenceDataBufferPos, inputDataSize,
78 _referenceDataBufferSize);
79
80 // Variable to store difference count
81 auto diffCount = (usize_t*)&_outputDataBuffer[_outputDataBufferPos];
82
83 // Size of differential buffer size
84 const size_t differentialBufferSize = sizeof(usize_t);
85
86 // If we reached maximum output, stop here
87 if (_outputDataBufferPos + differentialBufferSize >= _outputDataBufferSize)
88 JAFFAR_THROW_RUNTIME("[Error] Maximum output data position reached before differential encode (%lu + %lu > %lu)", _outputDataBufferPos, differentialBufferSize,
90
91 // Advancing position pointer to store the difference counter
92 _outputDataBufferPos += differentialBufferSize;
93
94 // Encoding differential
95 int ret = xd3_encode_memory((const uint8_t*)inputData, inputDataSize, &_referenceDataBuffer[_referenceDataBufferPos], inputDataSize, &_outputDataBuffer[_outputDataBufferPos],
96 diffCount, _outputDataBufferSize - _outputDataBufferPos, _useZlib ? 0 : XD3_NOCOMPRESS);
97
98 // If an error happened, print it here
99 if (ret != 0)
100 JAFFAR_THROW_RUNTIME("[Error] unexpected error while encoding differential compression. Probably maximum size increased: (%lu + %lu > %lu)", _outputDataBufferPos, *diffCount,
102
103 // Increasing output data position pointer
104 _outputDataBufferPos += *diffCount;
105
106 // Increasing the number of differential bytes processed
107 _differentialBytesCount += *diffCount;
108
109 // Finally, increasing reference data position pointer
110 _referenceDataBufferPos += inputDataSize;
111 }
112
118 size_t getReferenceDataBufferPos() const { return _referenceDataBufferPos; }
119
127 size_t getDifferentialBytesCount() const { return _differentialBytesCount; }
128
129private:
133 const uint8_t* __restrict const _referenceDataBuffer;
134
138 const size_t _referenceDataBufferSize;
139
143 size_t _referenceDataBufferPos = 0;
144
148 size_t _differentialBytesCount = 0;
149
153 const bool _useZlib;
154};
155
156} // namespace serializer
157
158} // 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
size_t getReferenceDataBufferPos() const
Definition serializers/differential.hpp:118
__JAFFAR_COMMON_INLINE__ void push(const void *const __restrict inputData, const size_t inputDataSize) override
Definition serializers/differential.hpp:70
__JAFFAR_COMMON_INLINE__ void pushContiguous(const void *const __restrict inputData=nullptr, const size_t inputDataSize=0) override
Definition serializers/differential.hpp:50
size_t getDifferentialBytesCount() const
Definition serializers/differential.hpp:127
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.