mirror of
https://github.com/thunderbrewhq/squall.git
synced 2025-12-12 02:22:30 +00:00
feat(big): add SBigFromUnsigned, SBigNew, and SBigToBinaryBuffer
This commit is contained in:
parent
630e6dbb1f
commit
7d5a157162
10 changed files with 211 additions and 0 deletions
25
storm/Big.cpp
Normal file
25
storm/Big.cpp
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include "storm/Big.hpp"
|
||||||
|
#include "storm/big/Ops.hpp"
|
||||||
|
#include "storm/Memory.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
void SBigFromUnsigned(BigData* num, uint32_t val) {
|
||||||
|
FromUnsigned(num->Primary(), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBigNew(BigData** num) {
|
||||||
|
auto m = SMemAlloc(sizeof(BigData), __FILE__, __LINE__, 0x0);
|
||||||
|
*num = new (m) BigData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBigToBinaryBuffer(BigData* num, uint8_t* data, uint32_t maxBytes, uint32_t* bytes) {
|
||||||
|
auto& output = num->Output();
|
||||||
|
ToBinary(output, num->Primary());
|
||||||
|
|
||||||
|
uint32_t n = output.Count() < maxBytes ? output.Count() : maxBytes;
|
||||||
|
memcpy(data, output.Ptr(), n);
|
||||||
|
|
||||||
|
if (bytes) {
|
||||||
|
*bytes = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
13
storm/Big.hpp
Normal file
13
storm/Big.hpp
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef STORM_BIG_HPP
|
||||||
|
#define STORM_BIG_HPP
|
||||||
|
|
||||||
|
#include "storm/big/BigData.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
void SBigFromUnsigned(BigData* num, uint32_t val);
|
||||||
|
|
||||||
|
void SBigNew(BigData** num);
|
||||||
|
|
||||||
|
void SBigToBinaryBuffer(BigData* num, uint8_t* data, uint32_t maxBytes, uint32_t* bytes);
|
||||||
|
|
||||||
|
#endif
|
||||||
30
storm/big/BigBuffer.cpp
Normal file
30
storm/big/BigBuffer.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include "storm/big/BigBuffer.hpp"
|
||||||
|
|
||||||
|
uint32_t& BigBuffer::operator[](uint32_t index) {
|
||||||
|
this->GrowToFit(index);
|
||||||
|
return this->m_data[this->m_offset + index];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t BigBuffer::operator[](uint32_t index) const {
|
||||||
|
if (this->IsUsed(index)) {
|
||||||
|
return const_cast<TSGrowableArray<uint32_t>&>(this->m_data)[this->m_offset + index];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t BigBuffer::Count() const {
|
||||||
|
return this->m_data.Count() - this->m_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BigBuffer::GrowToFit(uint32_t index) {
|
||||||
|
this->m_data.GrowToFit(this->m_offset + index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t BigBuffer::IsUsed(uint32_t index) const {
|
||||||
|
return index + this->m_offset < this->m_data.Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BigBuffer::SetCount(uint32_t count) {
|
||||||
|
this->m_data.SetCount(this->m_offset + count);
|
||||||
|
}
|
||||||
22
storm/big/BigBuffer.hpp
Normal file
22
storm/big/BigBuffer.hpp
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef STORM_BIG_BIG_BUFFER_HPP
|
||||||
|
#define STORM_BIG_BIG_BUFFER_HPP
|
||||||
|
|
||||||
|
#include "storm/Array.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class BigBuffer {
|
||||||
|
public:
|
||||||
|
// Member variables
|
||||||
|
TSGrowableArray<uint32_t> m_data;
|
||||||
|
uint32_t m_offset = 0;
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
uint32_t& operator[](uint32_t index);
|
||||||
|
uint32_t operator[](uint32_t index) const;
|
||||||
|
uint32_t Count() const;
|
||||||
|
void GrowToFit(uint32_t index);
|
||||||
|
int32_t IsUsed(uint32_t index) const;
|
||||||
|
void SetCount(uint32_t count);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
9
storm/big/BigData.cpp
Normal file
9
storm/big/BigData.cpp
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "storm/big/BigData.hpp"
|
||||||
|
|
||||||
|
TSGrowableArray<uint8_t>& BigData::Output() const {
|
||||||
|
return const_cast<TSGrowableArray<uint8_t>&>(this->m_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
BigBuffer& BigData::Primary() {
|
||||||
|
return this->m_primary;
|
||||||
|
}
|
||||||
20
storm/big/BigData.hpp
Normal file
20
storm/big/BigData.hpp
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef STORM_BIG_BIG_DATA_HPP
|
||||||
|
#define STORM_BIG_BIG_DATA_HPP
|
||||||
|
|
||||||
|
#include "storm/big/BigBuffer.hpp"
|
||||||
|
#include "storm/big/BigStack.hpp"
|
||||||
|
#include "storm/Array.hpp"
|
||||||
|
|
||||||
|
class BigData {
|
||||||
|
public:
|
||||||
|
// Member variables
|
||||||
|
BigBuffer m_primary;
|
||||||
|
BigStack m_stack;
|
||||||
|
TSGrowableArray<uint8_t> m_output;
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
TSGrowableArray<uint8_t>& Output() const;
|
||||||
|
BigBuffer& Primary();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
19
storm/big/BigStack.hpp
Normal file
19
storm/big/BigStack.hpp
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef STORM_BIG_BIG_STACK_HPP
|
||||||
|
#define STORM_BIG_BIG_STACK_HPP
|
||||||
|
|
||||||
|
#include "storm/big/BigBuffer.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class BigStack {
|
||||||
|
public:
|
||||||
|
// Static variables
|
||||||
|
const static uint32_t SIZE = 16;
|
||||||
|
|
||||||
|
// Member variables
|
||||||
|
BigBuffer m_buffer[SIZE];
|
||||||
|
uint32_t m_used = 0;
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -19,6 +19,26 @@ uint32_t ExtractLowPartSx(uint64_t& value) {
|
||||||
return low;
|
return low;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FromUnsigned(BigBuffer& buffer, uint32_t value) {
|
||||||
|
buffer[0] = value;
|
||||||
|
buffer.SetCount(1);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t MakeLarge(uint32_t low, uint32_t high) {
|
uint64_t MakeLarge(uint32_t low, uint32_t high) {
|
||||||
return low + (static_cast<uint64_t>(high) << 32);
|
return low + (static_cast<uint64_t>(high) << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ToBinaryAppend(TSGrowableArray<uint8_t>& output, const BigBuffer& buffer) {
|
||||||
|
for (uint32_t i = 0; i < buffer.Count() * 4; i++) {
|
||||||
|
auto byte = buffer[i / 4] >> (8 * (i & 3));
|
||||||
|
|
||||||
|
if (byte || (i / 4) + 1 < buffer.Count()) {
|
||||||
|
*output.New() = byte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToBinary(TSGrowableArray<uint8_t>& output, const BigBuffer& buffer) {
|
||||||
|
output.SetCount(0);
|
||||||
|
ToBinaryAppend(output, buffer);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,17 @@
|
||||||
#ifndef STORM_BIG_OPS_HPP
|
#ifndef STORM_BIG_OPS_HPP
|
||||||
#define STORM_BIG_OPS_HPP
|
#define STORM_BIG_OPS_HPP
|
||||||
|
|
||||||
|
#include "storm/big/BigBuffer.hpp"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
uint32_t ExtractLowPart(uint64_t& value);
|
uint32_t ExtractLowPart(uint64_t& value);
|
||||||
|
|
||||||
uint32_t ExtractLowPartSx(uint64_t& value);
|
uint32_t ExtractLowPartSx(uint64_t& value);
|
||||||
|
|
||||||
|
void FromUnsigned(BigBuffer& buffer, uint32_t value);
|
||||||
|
|
||||||
uint64_t MakeLarge(uint32_t low, uint32_t high);
|
uint64_t MakeLarge(uint32_t low, uint32_t high);
|
||||||
|
|
||||||
|
void ToBinary(TSGrowableArray<uint8_t>& output, const BigBuffer& buffer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
48
test/Big.cpp
48
test/Big.cpp
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "storm/Big.hpp"
|
||||||
#include "storm/big/Ops.hpp"
|
#include "storm/big/Ops.hpp"
|
||||||
#include "test/Test.hpp"
|
#include "test/Test.hpp"
|
||||||
|
|
||||||
|
|
@ -66,3 +67,50 @@ TEST_CASE("MakeLarge", "[big]") {
|
||||||
REQUIRE(value == 0x1122334400000000);
|
REQUIRE(value == 0x1122334400000000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("SBigFromUnsigned", "[big]") {
|
||||||
|
SECTION("creates bigdata from 0") {
|
||||||
|
BigData* num;
|
||||||
|
SBigNew(&num);
|
||||||
|
SBigFromUnsigned(num, 0);
|
||||||
|
|
||||||
|
CHECK(num->Primary().Count() == 1);
|
||||||
|
CHECK(num->Primary()[0] == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("creates bigdata from 0x12345678") {
|
||||||
|
BigData* num;
|
||||||
|
SBigNew(&num);
|
||||||
|
SBigFromUnsigned(num, 0x12345678);
|
||||||
|
|
||||||
|
CHECK(num->Primary().Count() == 1);
|
||||||
|
CHECK(num->Primary()[0] == 0x12345678);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("SBigToBinaryBuffer", "[big]") {
|
||||||
|
SECTION("returns expected buffer for bigdata representing 0") {
|
||||||
|
BigData* num;
|
||||||
|
SBigNew(&num);
|
||||||
|
SBigFromUnsigned(num, 0);
|
||||||
|
|
||||||
|
uint8_t buffer[4];
|
||||||
|
uint32_t bytes;
|
||||||
|
SBigToBinaryBuffer(num, buffer, sizeof(buffer), &bytes);
|
||||||
|
|
||||||
|
REQUIRE(bytes == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("returns expected buffer for bigdata representing 0x12345678") {
|
||||||
|
BigData* num;
|
||||||
|
SBigNew(&num);
|
||||||
|
SBigFromUnsigned(num, 0x12345678);
|
||||||
|
|
||||||
|
uint8_t buffer[4];
|
||||||
|
uint32_t bytes;
|
||||||
|
SBigToBinaryBuffer(num, buffer, sizeof(buffer), &bytes);
|
||||||
|
|
||||||
|
CHECK(bytes == 4);
|
||||||
|
CHECK(*reinterpret_cast<uint32_t*>(buffer) == 0x12345678);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue