fix base64 test failed.
Some checks failed
linux-arm-gcc / linux-gcc-armhf (push) Failing after 3m21s
linux-mips64-gcc / linux-gcc-mips64el (Debug) (push) Successful in 2m11s
linux-mips64-gcc / linux-gcc-mips64el (Release) (push) Successful in 1m58s
linux-arm-gcc / linux-gcc-arm (push) Failing after 4m41s
linux-x64-gcc / linux-gcc (Debug) (push) Successful in 1m53s
linux-x64-gcc / linux-gcc (Release) (push) Successful in 1m42s

This commit is contained in:
tqcq 2024-04-01 10:47:59 +08:00
parent 8af0855224
commit 21e6fd80f7
4 changed files with 80 additions and 81 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
out/ out/
build/ build/
compile_commands.json compile_commands.json
build-*/

View File

@ -19,12 +19,12 @@ template<typename T, typename U>
struct BufferCompat { struct BufferCompat {
using RawU = typename std::remove_const<U>::type; using RawU = typename std::remove_const<U>::type;
static constexpr bool value = !std::is_volatile<U>::value static constexpr bool value
&& ((std::is_integral<T>::value && sizeof(T) == 1) = !std::is_volatile<U>::value
? (std::is_integral<U>::value && sizeof(U) == 1) && ((std::is_integral<T>::value && sizeof(T) == 1) ? (std::is_integral<U>::value && sizeof(U) == 1)
: (std::is_same<T, RawU>::value) : (std::is_same<T, RawU>::value)
); );
}; };
}// namespace internal }// namespace internal
@ -34,18 +34,15 @@ class BufferT {
static_assert(!std::is_const<T>::value, "T may not be const"); static_assert(!std::is_const<T>::value, "T may not be const");
public: public:
using value_type = T; using value_type = T;
using const_iterator = const T *; using const_iterator = const T *;
BufferT() : size_(0), capacity_(0), data_(nullptr) { IsConsistent(); } BufferT() : size_(0), capacity_(0), data_(nullptr) { IsConsistent(); }
BufferT(const BufferT &) = delete; BufferT(const BufferT &) = delete;
BufferT &operator=(const BufferT &) = delete; BufferT &operator=(const BufferT &) = delete;
BufferT(BufferT &&buf) BufferT(BufferT &&buf) : size_(buf.size()), capacity_(buf.capacity()), data_(std::move(buf.data_))
: size_(buf.size()),
capacity_(buf.capacity()),
data_(std::move(buf.data_))
{ {
IsConsistent(); IsConsistent();
} }
@ -60,41 +57,30 @@ public:
IsConsistent(); IsConsistent();
} }
template<typename U, template<typename U, typename std::enable_if<internal::BufferCompat<T, U>::value>::type * = nullptr>
typename std::enable_if<internal::BufferCompat<T, U>::value>::type
* = nullptr>
BufferT(const U *data, size_t size) : BufferT(data, size, size) BufferT(const U *data, size_t size) : BufferT(data, size, size)
{} {}
template<typename U, template<typename U, typename std::enable_if<internal::BufferCompat<T, U>::value>::type * = nullptr>
typename std::enable_if<internal::BufferCompat<T, U>::value>::type
* = nullptr>
BufferT(U *data, size_t size, size_t capacity) : BufferT(size, capacity) BufferT(U *data, size_t size, size_t capacity) : BufferT(size, capacity)
{ {
static_assert(sizeof(T) == sizeof(U), ""); static_assert(sizeof(T) == sizeof(U), "");
if (size > 0) { std::memcpy(data_.get(), data, size * sizeof(U)); } if (size > 0) { std::memcpy(data_.get(), data, size * sizeof(U)); }
} }
template<typename U, template<typename U, size_t N, typename std::enable_if<internal::BufferCompat<T, U>::value>::type * = nullptr>
size_t N,
typename std::enable_if<internal::BufferCompat<T, U>::value>::type
* = nullptr>
BufferT(U (&array)[N]) : BufferT(array, N) BufferT(U (&array)[N]) : BufferT(array, N)
{} {}
~BufferT() {} ~BufferT() {}
template<typename U, template<typename U = T, typename std::enable_if<internal::BufferCompat<T, U>::value>::type * = nullptr>
typename std::enable_if<internal::BufferCompat<T, U>::value>::type
* = nullptr>
const U *data() const const U *data() const
{ {
return reinterpret_cast<const U *>(data_.get()); return reinterpret_cast<const U *>(data_.get());
} }
template<typename U, template<typename U = T, typename std::enable_if<internal::BufferCompat<T, U>::value>::type * = nullptr>
typename std::enable_if<internal::BufferCompat<T, U>::value>::type
* = nullptr>
U *data() U *data()
{ {
return reinterpret_cast<U *>(data_.get()); return reinterpret_cast<U *>(data_.get());
@ -108,7 +94,7 @@ public:
BufferT &operator=(BufferT &&buf) BufferT &operator=(BufferT &&buf)
{ {
size_ = buf.size_; size_ = buf.size_;
capacity_ = buf.capacity_; capacity_ = buf.capacity_;
using std::swap; using std::swap;
swap(data_, buf.data_); swap(data_, buf.data_);
@ -120,10 +106,7 @@ public:
bool operator==(const BufferT &buf) const bool operator==(const BufferT &buf) const
{ {
if (size_ != buf.size_) { return false; } if (size_ != buf.size_) { return false; }
if (std::is_integral<T>::value) { if (std::is_integral<T>::value) { return std::memcmp(data_.get(), buf.data_.get(), size_ * sizeof(T)) == 0; }
return std::memcmp(data_.get(), buf.data_.get(), size_ * sizeof(T))
== 0;
}
for (size_t i = 0; i < size_; i++) { for (size_t i = 0; i < size_; i++) {
if (data_[i] != buf.data_[i]) { return false; } if (data_[i] != buf.data_[i]) { return false; }
} }
@ -148,32 +131,23 @@ public:
const T *cend() const { return data() + size(); } const T *cend() const { return data() + size(); }
template<typename U, template<typename U, typename std::enable_if<internal::BufferCompat<T, U>::value>::type * = nullptr>
typename std::enable_if<internal::BufferCompat<T, U>::value>::type
* = nullptr>
void SetData(const U *data, size_t size) void SetData(const U *data, size_t size)
{ {
const size_t old_size = size_; const size_t old_size = size_;
size_ = 0; size_ = 0;
AppentData(data, size); AppentData(data, size);
if (ZeroOnFree && size_ < old_size) { if (ZeroOnFree && size_ < old_size) { ZeroTrailingData(old_size - size_); }
ZeroTrailingData(old_size - size_);
}
} }
template<typename U, template<typename U, size_t N, typename std::enable_if<internal::BufferCompat<T, U>::value>::type * = nullptr>
size_t N,
typename std::enable_if<internal::BufferCompat<T, U>::value>::type
* = nullptr>
void SetData(const U (&array)[N]) void SetData(const U (&array)[N])
{ {
SetData(array, N); SetData(array, N);
} }
template<typename U, template<typename U, typename std::enable_if<internal::BufferCompat<T, U>::value>::type * = nullptr>
typename std::enable_if<internal::BufferCompat<T, U>::value>::type void AppendData(const U *data, size_t size)
* = nullptr>
void AppentData(const U *data, size_t size)
{ {
if (size == 0) { return; } if (size == 0) { return; }
@ -184,10 +158,7 @@ public:
size_ = new_size; size_ = new_size;
} }
template<typename U, template<typename U, size_t N, typename std::enable_if<internal::BufferCompat<T, U>::value>::type * = nullptr>
size_t N,
typename std::enable_if<internal::BufferCompat<T, U>::value>::type
* = nullptr>
void AppendData(const U (&array)[N]) void AppendData(const U (&array)[N])
{ {
AppendData(array, N); AppendData(array, N);
@ -201,9 +172,7 @@ public:
// AppendData(w.data(), w.size()); // AppendData(w.data(), w.size());
// } // }
template<typename U, template<typename U, typename std::enable_if<internal::BufferCompat<T, U>::value>::type * = nullptr>
typename std::enable_if<internal::BufferCompat<T, U>::value>::type
* = nullptr>
void AppendData(const U &item) void AppendData(const U &item)
{ {
AppendData(&item, 1); AppendData(&item, 1);
@ -214,15 +183,10 @@ public:
const size_t old_size = size_; const size_t old_size = size_;
EnsureCapacityWithHeadroom(size, true); EnsureCapacityWithHeadroom(size, true);
size_ = size; size_ = size;
if (ZeroOnFree && size_ < old_size) { if (ZeroOnFree && size_ < old_size) { ZeroTrailingData(old_size - size_); }
ZeroTrailingData(old_size - size_);
}
} }
void EnsureCapacity(size_t capacity) void EnsureCapacity(size_t capacity) { EnsureCapacityWithHeadroom(capacity, false); }
{
EnsureCapacityWithHeadroom(capacity, false);
}
void Clear() { size_ = 0; } void Clear() { size_ = 0; }
@ -239,28 +203,21 @@ private:
{ {
if (capacity <= capacity_) { return; } if (capacity <= capacity_) { return; }
const size_t new_capacity = extra_headroom const size_t new_capacity = extra_headroom ? std::max(capacity, capacity_ + capacity_ / 2) : capacity;
? std::max(capacity, capacity_ + capacity_ / 2)
: capacity;
std::unique_ptr<T[]> new_data(new T[new_capacity]); std::unique_ptr<T[]> new_data(new T[new_capacity]);
if (data_ != nullptr) { if (data_ != nullptr) { std::memcpy(new_data.get(), data_.get(), size_ * sizeof(T)); }
std::memcpy(new_data.get(), data_.get(), size_ * sizeof(T));
}
data_ = std::move(new_data); data_ = std::move(new_data);
capacity_ = new_capacity; capacity_ = new_capacity;
} }
void ZeroTrailingData(size_t count) {} void ZeroTrailingData(size_t count) {}
bool IsConsistent() const bool IsConsistent() const { return (data_ || capacity_ == 0) && capacity_ >= size_; }
{
return (data_ || capacity_ == 0) && capacity_ >= size_;
}
void OnMovedFrom() void OnMovedFrom()
{ {
size_ = 0; size_ = 0;
capacity_ = 0; capacity_ = 0;
} }

View File

@ -1,4 +1,5 @@
#include "sled/strings/base64.h" #include "sled/strings/base64.h"
#include "sled/buffer.h"
#include "sled/log/log.h" #include "sled/log/log.h"
#include "sled/synchronization/call_once.h" #include "sled/synchronization/call_once.h"
#include <array> #include <array>
@ -108,24 +109,36 @@ Base64::Decode(const uint8_t *ptr, size_t len)
{ {
if (len == 0) { return std::string(); } if (len == 0) { return std::string(); }
// FIXME: 修复快速解码在arm平台错误问题
/*
base64_decodestate state; base64_decodestate state;
base64_init_decodestate(&state); base64_init_decodestate(&state);
std::stringstream ss; sled::BufferT<char> buffer;
char plaintext[kBufferSize]; char plaintext[kBufferSize];
int codelength = 0; int codelength = 0;
int plainlength = 0; int plainlength = 0;
do { do {
codelength = std::min(kBufferSize, static_cast<int>(len)); codelength = std::min(kBufferSize, static_cast<int>(len));
plainlength = base64_decode_block(reinterpret_cast<const char *>(ptr), codelength, plaintext, &state); // 如果长度不足4需要填充=
ss.write(plaintext, plainlength); if (codelength < 4) {
sled::BufferT<char> temp(reinterpret_cast<const char *>(ptr), codelength);
while (temp.size() % 4) { temp.AppendData('='); }
plainlength = base64_decode_block(temp.data(), temp.size(), plaintext, &state);
} else {
// 如果长度不足4则将这部分留到下一次处理
codelength -= codelength % 4;
plainlength = base64_decode_block(reinterpret_cast<const char *>(ptr), codelength, plaintext, &state);
}
buffer.AppendData(static_cast<const char *>(plaintext), plainlength);
ptr += codelength; ptr += codelength;
len -= codelength; len -= codelength;
} while (len > 0 && codelength > 0); } while (len > 0 && codelength > 0);
return ss.str(); return std::string(buffer.data(), buffer.data() + buffer.size());
/* */
CallOnce(once_flag, [&] { CallOnce(once_flag, [&] {
std::fill(kInvBase64Chars.begin(), kInvBase64Chars.end(), -1); std::fill(kInvBase64Chars.begin(), kInvBase64Chars.end(), -1);
@ -161,8 +174,7 @@ Base64::Decode(const uint8_t *ptr, size_t len)
} }
while (write_idx < data.size()) data.pop_back(); while (write_idx < data.size()) data.pop_back();
return make_status_or<std::string>(data); return MakeStatusOr<std::string>(data);
*/
} }
}// namespace sled }// namespace sled

View File

@ -0,0 +1,29 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER "aarch64-linux-gnu-gcc")
set(CMAKE_CXX_COMPILER "aarch64-linux-gnu-g++")
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
endif()
set(CMAKE_C_FLAGS "-march=armv8-a")
set(CMAKE_CXX_FLAGS "-march=armv8-a")
# cache flags
set(CMAKE_C_FLAGS
"${CMAKE_C_FLAGS}"
CACHE STRING "c flags")
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS}"
CACHE STRING "c++ flags")