-
Notifications
You must be signed in to change notification settings - Fork 47
/
EbmlUInteger.cpp
106 lines (86 loc) · 2.64 KB
/
EbmlUInteger.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright © 2002-2010 Steve Lhomme.
// SPDX-License-Identifier: LGPL-2.1-or-later
/*!
\file
\author Steve Lhomme <robux4 @ users.sf.net>
\author Moritz Bunkus <moritz @ bunkus.org>
*/
#include <array>
#include "ebml/EbmlUInteger.h"
namespace libebml {
EbmlUInteger::EbmlUInteger(const EbmlCallbacksDefault<std::uint64_t> & classInfo)
:EbmlElementDefaultSameStorage(classInfo, DEFAULT_UINT_SIZE)
{
if (classInfo.HasDefault())
{
const auto& def = static_cast<const EbmlCallbacksWithDefault<std::uint64_t> &>(classInfo);
SetValue(def.DefaultValue());
}
}
EbmlUInteger::operator std::uint8_t() const {return static_cast<std::uint8_t>(GetValue()); }
EbmlUInteger::operator std::uint16_t() const {return static_cast<std::uint16_t>(GetValue());}
EbmlUInteger::operator std::uint32_t() const {return static_cast<std::uint32_t>(GetValue());}
EbmlUInteger::operator std::uint64_t() const {return GetValue();}
/*!
\todo handle exception on errors
*/
filepos_t EbmlUInteger::RenderData(IOCallback & output, bool /* bForceRender */, const ShouldWrite & /* writeFilter */)
{
std::array<binary, 8> FinalData; // we don't handle more than 64 bits integers
if (GetSizeLength() > 8)
return 0; // integer bigger coded on more than 64 bits are not supported
std::uint64_t TempValue = GetValue();
for (unsigned int i=0; i<GetSize();i++) {
FinalData.at(GetSize()-i-1) = TempValue & 0xFF;
TempValue >>= 8;
}
output.writeFully(FinalData.data(),GetSize());
return GetSize();
}
filepos_t EbmlUInteger::UpdateSize(const ShouldWrite & writeFilter, bool /* bForceRender */)
{
if (!CanWrite(writeFilter))
return 0;
const auto val = GetValue();
if (val <= 0xFF) {
SetSize_(1);
} else if (val <= 0xFFFF) {
SetSize_(2);
} else if (val <= 0xFFFFFF) {
SetSize_(3);
} else if (val <= 0xFFFFFFFF) {
SetSize_(4);
} else if (val <= 0xFFFFFFFFFFLL) {
SetSize_(5);
} else if (val <= 0xFFFFFFFFFFFFLL) {
SetSize_(6);
} else if (val <= 0xFFFFFFFFFFFFFFLL) {
SetSize_(7);
} else {
SetSize_(8);
}
if (GetDefaultSize() > GetSize()) {
SetSize_(GetDefaultSize());
}
return GetSize();
}
filepos_t EbmlUInteger::ReadData(IOCallback & input, ScopeMode ReadFully)
{
if (ReadFully == SCOPE_NO_DATA)
return GetSize();
if (GetSize() > 8) {
// impossible to read, skip it
input.setFilePointer(GetSize(), seek_current);
return GetSize();
}
std::array<binary, 8> Buffer;
input.readFully(Buffer.data(), GetSize());
std::uint64_t val = 0;
for (unsigned int i=0; i<GetSize(); i++) {
val <<= 8;
val |= Buffer.at(i);
}
SetValue(val);
return GetSize();
}
} // namespace libebml