mirror of
https://github.com/vczh-libraries/Release.git
synced 2026-08-18 09:48:10 +08:00
Update import
This commit is contained in:
+8
-2
@@ -660,7 +660,7 @@ String Conversions (buffer walkthrough)
|
||||
if (d == nullptr)
|
||||
{
|
||||
while (reader.Read()) size++;
|
||||
return reader.HasIllegalChar() ? -1 : size + 1;
|
||||
return size + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -673,7 +673,7 @@ String Conversions (buffer walkthrough)
|
||||
chars--;
|
||||
if (!c) break;
|
||||
}
|
||||
return reader.HasIllegalChar() ? -1 : size;
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -926,6 +926,12 @@ Licensed under https://github.com/vczh-libraries/License
|
||||
|
||||
namespace vl
|
||||
{
|
||||
template class ObjectString<char>;
|
||||
template class ObjectString<wchar_t>;
|
||||
template class ObjectString<char8_t>;
|
||||
template class ObjectString<char16_t>;
|
||||
template class ObjectString<char32_t>;
|
||||
|
||||
#if defined VCZH_GCC
|
||||
void _itoa_s(vint32_t value, char* buffer, size_t size, vint radix)
|
||||
{
|
||||
|
||||
+39
-46
@@ -7090,6 +7090,12 @@ namespace vl
|
||||
template<typename T>
|
||||
const T ObjectString<T>::zero=0;
|
||||
|
||||
extern template class ObjectString<char>;
|
||||
extern template class ObjectString<wchar_t>;
|
||||
extern template class ObjectString<char8_t>;
|
||||
extern template class ObjectString<char16_t>;
|
||||
extern template class ObjectString<char32_t>;
|
||||
|
||||
/// <summary>Ansi string in local code page.</summary>
|
||||
typedef ObjectString<char> AString;
|
||||
/// <summary>Unicode string, UTF-16 on Windows, UTF-32 on Linux and macOS.</summary>
|
||||
@@ -8690,8 +8696,17 @@ UtfConversion<T>
|
||||
UtfReaderConsumer<TReader>
|
||||
***********************************************************************/
|
||||
|
||||
template<typename TReader>
|
||||
class UtfReaderConsumer : public Object
|
||||
template<typename TInternalConsumer>
|
||||
class UtfEmptyConsumerRedirection : public Object
|
||||
{
|
||||
public:
|
||||
UtfEmptyConsumerRedirection(TInternalConsumer&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TReader, template<typename> class TConsumerRedirection>
|
||||
class UtfReaderConsumer : public TConsumerRedirection<typename TReader::ConsumerType>
|
||||
{
|
||||
protected:
|
||||
TReader internalReader;
|
||||
@@ -8704,13 +8719,9 @@ UtfReaderConsumer<TReader>
|
||||
template<typename ...TArguments>
|
||||
UtfReaderConsumer(TArguments&& ...arguments)
|
||||
: internalReader(std::forward<TArguments&&>(arguments)...)
|
||||
, TConsumerRedirection<typename TReader::ConsumerType>(internalReader)
|
||||
{
|
||||
}
|
||||
|
||||
bool HasIllegalChar() const
|
||||
{
|
||||
return internalReader.HasIllegalChar();
|
||||
}
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
@@ -8727,9 +8738,10 @@ UtfFrom32ReaderBase<T, TConsumer>
|
||||
|
||||
UtfCharCluster sourceCluster = { 0,0 };
|
||||
vint readCounter = -1;
|
||||
bool error = false;
|
||||
|
||||
public:
|
||||
using ConsumerType = TConsumer;
|
||||
|
||||
template<typename ...TArguments>
|
||||
UtfFrom32ReaderBase(TArguments&& ...arguments)
|
||||
: TConsumer(std::forward<TArguments&&>(arguments)...)
|
||||
@@ -8772,11 +8784,6 @@ UtfFrom32ReaderBase<T, TConsumer>
|
||||
{
|
||||
return sourceCluster;
|
||||
}
|
||||
|
||||
bool HasIllegalChar() const
|
||||
{
|
||||
return error || TConsumer::HasIllegalChar();
|
||||
}
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
@@ -8792,9 +8799,10 @@ UtfTo32ReaderBase<T, TConsumer>
|
||||
|
||||
UtfCharCluster sourceCluster = { 0,0 };
|
||||
vint readCounter = -1;
|
||||
bool error = false;
|
||||
|
||||
public:
|
||||
using ConsumerType = TConsumer;
|
||||
|
||||
template<typename ...TArguments>
|
||||
UtfTo32ReaderBase(TArguments&& ...arguments)
|
||||
: TConsumer(std::forward<TArguments&&>(arguments)...)
|
||||
@@ -8852,11 +8860,6 @@ UtfTo32ReaderBase<T, TConsumer>
|
||||
{
|
||||
return sourceCluster;
|
||||
}
|
||||
|
||||
bool HasIllegalChar() const
|
||||
{
|
||||
return error || TConsumer::HasIllegalChar();
|
||||
}
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
@@ -8866,10 +8869,12 @@ Utf32DirectReaderBase<TConsumer>
|
||||
template<typename TConsumer>
|
||||
class Utf32DirectReaderBase : public TConsumer
|
||||
{
|
||||
UtfCharCluster sourceCluster = { -1,1 };
|
||||
vint readCounter = -1;
|
||||
bool ended = false;
|
||||
|
||||
public:
|
||||
using ConsumerType = TConsumer;
|
||||
|
||||
template<typename ...TArguments>
|
||||
Utf32DirectReaderBase(TArguments&& ...arguments)
|
||||
: TConsumer(std::forward<TArguments&&>(arguments)...)
|
||||
@@ -8882,24 +8887,22 @@ Utf32DirectReaderBase<TConsumer>
|
||||
static_assert(sizeof(dest) == sizeof(char32_t));
|
||||
if (dest || !ended)
|
||||
{
|
||||
sourceCluster.index += 1;
|
||||
if (!dest)
|
||||
{
|
||||
ended = true;
|
||||
sourceCluster.size = 0;
|
||||
}
|
||||
readCounter++;
|
||||
}
|
||||
ended = !dest;
|
||||
return static_cast<char32_t>(dest);
|
||||
}
|
||||
|
||||
vint ReadingIndex() const
|
||||
{
|
||||
return sourceCluster.index;
|
||||
return readCounter;
|
||||
}
|
||||
|
||||
UtfCharCluster SourceCluster() const
|
||||
{
|
||||
return sourceCluster;
|
||||
if (readCounter == -1) return { 0,0 };
|
||||
if (ended) return { readCounter,0 };
|
||||
return { readCounter,1 };
|
||||
}
|
||||
};
|
||||
|
||||
@@ -8910,10 +8913,10 @@ UtfToUtfReaderBase<TFrom, TTo, TConsumer>
|
||||
template<typename TFrom, typename TTo>
|
||||
struct UtfToUtfReaderSelector
|
||||
{
|
||||
template<typename TConsumer>
|
||||
class Reader : public UtfFrom32ReaderBase<TTo, UtfReaderConsumer<UtfTo32ReaderBase<TFrom, TConsumer>>>
|
||||
template<typename TConsumer, template<typename> class TConsumerRedirection>
|
||||
class Reader : public UtfFrom32ReaderBase<TTo, UtfReaderConsumer<UtfTo32ReaderBase<TFrom, TConsumer>, TConsumerRedirection>>
|
||||
{
|
||||
using TBase = UtfFrom32ReaderBase<TTo, UtfReaderConsumer<UtfTo32ReaderBase<TFrom, TConsumer>>>;
|
||||
using TBase = UtfFrom32ReaderBase<TTo, UtfReaderConsumer<UtfTo32ReaderBase<TFrom, TConsumer>, TConsumerRedirection>>;
|
||||
public:
|
||||
template<typename ...TArguments>
|
||||
Reader(TArguments&& ...arguments)
|
||||
@@ -8931,14 +8934,14 @@ UtfToUtfReaderBase<TFrom, TTo, TConsumer>
|
||||
template<typename TTo>
|
||||
struct UtfToUtfReaderSelector<char32_t, TTo>
|
||||
{
|
||||
template<typename TConsumer>
|
||||
template<typename TConsumer, template<typename> class>
|
||||
using Reader = UtfFrom32ReaderBase<TTo, TConsumer>;
|
||||
};
|
||||
|
||||
template<typename TFrom>
|
||||
struct UtfToUtfReaderSelector<TFrom, char32_t>
|
||||
{
|
||||
template<typename TConsumer>
|
||||
template<typename TConsumer, template<typename> class>
|
||||
using Reader = UtfTo32ReaderBase<TFrom, TConsumer>;
|
||||
};
|
||||
|
||||
@@ -8946,7 +8949,7 @@ UtfToUtfReaderBase<TFrom, TTo, TConsumer>
|
||||
template<>\
|
||||
struct UtfToUtfReaderSelector<TFROM, TTO>\
|
||||
{\
|
||||
template<typename TConsumer>\
|
||||
template<typename TConsumer, template<typename> class>\
|
||||
using Reader = Utf32DirectReaderBase<TConsumer>;\
|
||||
}\
|
||||
|
||||
@@ -8960,8 +8963,8 @@ UtfToUtfReaderBase<TFrom, TTo, TConsumer>
|
||||
|
||||
#undef DEFINE_UTF32_DIRECT_READER
|
||||
|
||||
template<typename TFrom, typename TTo, typename TConsumer>
|
||||
using UtfToUtfReaderBase = typename UtfToUtfReaderSelector<TFrom, TTo>::template Reader<TConsumer>;
|
||||
template<typename TFrom, typename TTo, typename TConsumer, template<typename> class TConsumerRedirection = UtfEmptyConsumerRedirection>
|
||||
using UtfToUtfReaderBase = typename UtfToUtfReaderSelector<TFrom, TTo>::template Reader<TConsumer, TConsumerRedirection>;
|
||||
|
||||
/***********************************************************************
|
||||
UtfStringConsumer<T>
|
||||
@@ -8986,11 +8989,6 @@ UtfStringConsumer<T>
|
||||
, consuming(_starting)
|
||||
{
|
||||
}
|
||||
|
||||
bool HasIllegalChar() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TFrom, typename TTo>
|
||||
@@ -9035,11 +9033,6 @@ UtfStringRangeConsumer<T>
|
||||
, consuming(_starting)
|
||||
{
|
||||
}
|
||||
|
||||
bool HasIllegalChar() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TFrom, typename TTo>
|
||||
|
||||
+261
-62
@@ -591,6 +591,265 @@ ThreadLocalStorage
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\ENCODING\BASE64ENCODING.CPP
|
||||
***********************************************************************/
|
||||
/***********************************************************************
|
||||
Author: Zihan Chen (vczh)
|
||||
Licensed under https://github.com/vczh-libraries/License
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
namespace vl
|
||||
{
|
||||
namespace stream
|
||||
{
|
||||
const char8_t Utf8Base64Codes[] = u8"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/***********************************************************************
|
||||
Utf8Base64Encoder
|
||||
***********************************************************************/
|
||||
|
||||
void Utf8Base64Encoder::WriteBytesToCharArray(uint8_t* fromBytes, char8_t(&toChars)[Base64CycleChars], vint bytes)
|
||||
{
|
||||
switch (bytes)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
toChars[0] = Utf8Base64Codes[fromBytes[0] >> 2];
|
||||
toChars[1] = Utf8Base64Codes[(fromBytes[0] % (1 << 2)) << 4];
|
||||
toChars[2] = u8'=';
|
||||
toChars[3] = u8'=';
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
toChars[0] = Utf8Base64Codes[fromBytes[0] >> 2];
|
||||
toChars[1] = Utf8Base64Codes[((fromBytes[0] % (1 << 2)) << 4) | (fromBytes[1] >> 4)];
|
||||
toChars[2] = Utf8Base64Codes[(fromBytes[1] % (1 << 4)) << 2];
|
||||
toChars[3] = u8'=';
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
toChars[0] = Utf8Base64Codes[fromBytes[0] >> 2];
|
||||
toChars[1] = Utf8Base64Codes[((fromBytes[0] % (1 << 2)) << 4) | (fromBytes[1] >> 4)];
|
||||
toChars[2] = Utf8Base64Codes[((fromBytes[1] % (1 << 4)) << 2) | (fromBytes[2] >> 6)];
|
||||
toChars[3] = Utf8Base64Codes[fromBytes[2] % (1 << 6)];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CHECK_FAIL(L"vl::stream::Utf8Base64Encoder::WriteBytesToCharArray(uint8_t*, char8_t(&)[Base64CycleChars], vint)#Parameter bytes should be 1, 2 or 3.");
|
||||
}
|
||||
}
|
||||
|
||||
bool Utf8Base64Encoder::WriteCycle(uint8_t*& reading, vint& _size)
|
||||
{
|
||||
if (_size <= 0) return false;
|
||||
vint bytes = _size < Base64CycleBytes ? _size : Base64CycleBytes;
|
||||
|
||||
char8_t chars[Base64CycleChars];
|
||||
WriteBytesToCharArray(reading, chars, bytes);
|
||||
vint writtenBytes = stream->Write(chars, Base64CycleChars);
|
||||
CHECK_ERROR(writtenBytes == Base64CycleChars, L"vl::stream::Utf8Base64Encoder::WriteCycle(uint8_t*&, vint&)#The underlying stream failed to accept enough base64 characters.");
|
||||
|
||||
reading += bytes;
|
||||
_size -= bytes;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Utf8Base64Encoder::WriteCache(uint8_t*& reading, vint& _size)
|
||||
{
|
||||
if (cacheSize > 0 || _size < Base64CycleBytes)
|
||||
{
|
||||
vint copiedBytes = Base64CycleBytes - cacheSize;
|
||||
if (copiedBytes > _size) copiedBytes = _size;
|
||||
if (copiedBytes > 0)
|
||||
{
|
||||
memcpy(cache + cacheSize, reading, copiedBytes);
|
||||
reading += copiedBytes;
|
||||
_size -= copiedBytes;
|
||||
cacheSize += copiedBytes;
|
||||
}
|
||||
}
|
||||
|
||||
if (cacheSize == 0) return _size > 0;
|
||||
if (cacheSize == Base64CycleBytes)
|
||||
{
|
||||
uint8_t* cacheReading = cache;
|
||||
return WriteCycle(cacheReading, cacheSize);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
vint Utf8Base64Encoder::Write(void* _buffer, vint _size)
|
||||
{
|
||||
uint8_t* reading = (uint8_t*)_buffer;
|
||||
|
||||
// flush cache if any
|
||||
if (!WriteCache(reading, _size)) goto FINISHED_WRITING;
|
||||
|
||||
// run Base64 encoding
|
||||
while (_size >= Base64CycleBytes)
|
||||
{
|
||||
if (!WriteCycle(reading, _size)) goto FINISHED_WRITING;
|
||||
}
|
||||
|
||||
// run the last Base64 encoding cycle and wrote a postfix to cache
|
||||
WriteCache(reading, _size);
|
||||
|
||||
FINISHED_WRITING:
|
||||
return reading - (uint8_t*)_buffer;
|
||||
}
|
||||
|
||||
void Utf8Base64Encoder::Close()
|
||||
{
|
||||
if (cacheSize > 0)
|
||||
{
|
||||
char8_t chars[Base64CycleChars];
|
||||
WriteBytesToCharArray(cache, chars, cacheSize);
|
||||
vint writtenBytes = stream->Write(chars, Base64CycleChars);
|
||||
CHECK_ERROR(writtenBytes == Base64CycleChars, L"vl::stream::Utf8Base64Encoder::Close()#The underlying stream failed to accept enough base64 characters.");
|
||||
|
||||
cacheSize = 0;
|
||||
}
|
||||
EncoderBase::Close();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Utf8Base64Decoder
|
||||
***********************************************************************/
|
||||
|
||||
vint Utf8Base64Decoder::ReadBytesFromCharArray(char8_t(&fromChars)[Base64CycleChars], uint8_t* toBytes)
|
||||
{
|
||||
uint8_t nums[Base64CycleChars];
|
||||
for (vint i = 0; i < Base64CycleChars; i++)
|
||||
{
|
||||
char8_t c = fromChars[i];
|
||||
if (u8'A' <= c && c <= u8'Z') nums[i] = c - u8'A';
|
||||
else if (u8'a' <= c && c <= u8'z') nums[i] = c - u8'a' + 26;
|
||||
else if (u8'0' <= c && c <= u8'9') nums[i] = c - u8'0' + 52;
|
||||
else switch (c)
|
||||
{
|
||||
case '+':nums[i] = 62; break;
|
||||
case '/':nums[i] = 63; break;
|
||||
case '=':nums[i] = 0; break;
|
||||
default:
|
||||
CHECK_FAIL(L"vl::stream::Utf8Base64Decoder::ReadBytesFromCharArray(char(&)[Base64CycleChars], uint8_t*)#Illegal Base64 character.");
|
||||
}
|
||||
}
|
||||
|
||||
toBytes[0] = (nums[0] << 2) | (nums[1] >> 4);
|
||||
if (fromChars[2] == u8'=') return 1;
|
||||
toBytes[1] = ((nums[1] % (1 << 4)) << 4) | (nums[2] >> 2);
|
||||
if (fromChars[3] == u8'=') return 2;
|
||||
toBytes[2] = ((nums[2] % (1 << 2)) << 6) | nums[3];
|
||||
return 3;
|
||||
}
|
||||
|
||||
vint Utf8Base64Decoder::ReadCycle(uint8_t*& writing, vint& _size)
|
||||
{
|
||||
char8_t chars[Base64CycleChars];
|
||||
vint readChars = stream->Read((void*)chars, Base64CycleChars);
|
||||
if (readChars == 0) return 0;
|
||||
CHECK_ERROR(readChars == Base64CycleChars, L"vl::stream::Utf8Base64Decoder::ReadCycle(uint8_t*&, vint&)#The underlying stream failed to provide enough base64 characters.");
|
||||
|
||||
vint readBytes = ReadBytesFromCharArray(chars, writing);
|
||||
writing += readBytes;
|
||||
_size -= readBytes;
|
||||
return readBytes;
|
||||
}
|
||||
|
||||
void Utf8Base64Decoder::ReadCache(uint8_t*& writing, vint& _size)
|
||||
{
|
||||
if (cacheSize > 0)
|
||||
{
|
||||
vint copiedBytes = cacheSize;
|
||||
if (copiedBytes > _size) copiedBytes = _size;
|
||||
if (copiedBytes > 0)
|
||||
{
|
||||
memcpy(writing, cache, copiedBytes);
|
||||
writing += copiedBytes;
|
||||
_size -= copiedBytes;
|
||||
cacheSize -= copiedBytes;
|
||||
if (cacheSize > 0)
|
||||
{
|
||||
memmove(cache, cache + copiedBytes, cacheSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vint Utf8Base64Decoder::Read(void* _buffer, vint _size)
|
||||
{
|
||||
uint8_t* writing = (uint8_t*)_buffer;
|
||||
|
||||
// write cache to buffer if any
|
||||
ReadCache(writing, _size);
|
||||
|
||||
// run Base64 decoding
|
||||
while (_size >= Base64CycleBytes)
|
||||
{
|
||||
if (ReadCycle(writing, _size) == 0) goto FINISHED_READING;
|
||||
}
|
||||
|
||||
// run the last Base64 decoding cycle and write a prefix to buffer
|
||||
if (_size > 0)
|
||||
{
|
||||
uint8_t* cacheWriting = cache;
|
||||
vint temp = 0;
|
||||
if ((cacheSize = ReadCycle(cacheWriting, temp)) == 0) goto FINISHED_READING;
|
||||
ReadCache(writing, _size);
|
||||
}
|
||||
FINISHED_READING:
|
||||
return writing - (uint8_t*)_buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\ENCODING\ENCODING.CPP
|
||||
***********************************************************************/
|
||||
/***********************************************************************
|
||||
Author: Zihan Chen (vczh)
|
||||
Licensed under https://github.com/vczh-libraries/License
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
namespace vl
|
||||
{
|
||||
namespace stream
|
||||
{
|
||||
/***********************************************************************
|
||||
EncoderBase
|
||||
***********************************************************************/
|
||||
|
||||
void EncoderBase::Setup(IStream* _stream)
|
||||
{
|
||||
stream = _stream;
|
||||
}
|
||||
|
||||
void EncoderBase::Close()
|
||||
{
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
DecoderBase
|
||||
***********************************************************************/
|
||||
|
||||
void DecoderBase::Setup(IStream* _stream)
|
||||
{
|
||||
stream = _stream;
|
||||
}
|
||||
|
||||
void DecoderBase::Close()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\ENCODING\LZWENCODING.CPP
|
||||
***********************************************************************/
|
||||
@@ -745,11 +1004,6 @@ LzwEncoder
|
||||
{
|
||||
}
|
||||
|
||||
void LzwEncoder::Setup(IStream* _stream)
|
||||
{
|
||||
stream = _stream;
|
||||
}
|
||||
|
||||
void LzwEncoder::Close()
|
||||
{
|
||||
if (prefix != root)
|
||||
@@ -765,6 +1019,7 @@ LzwEncoder
|
||||
WriteNumber(eofIndex, indexBits);
|
||||
}
|
||||
Flush();
|
||||
EncoderBase::Close();
|
||||
}
|
||||
|
||||
vint LzwEncoder::Write(void* _buffer, vint _size)
|
||||
@@ -890,15 +1145,6 @@ LzwDecoder
|
||||
{
|
||||
}
|
||||
|
||||
void LzwDecoder::Setup(IStream* _stream)
|
||||
{
|
||||
stream = _stream;
|
||||
}
|
||||
|
||||
void LzwDecoder::Close()
|
||||
{
|
||||
}
|
||||
|
||||
vint LzwDecoder::Read(void* _buffer, vint _size)
|
||||
{
|
||||
vint written = 0;
|
||||
@@ -1273,48 +1519,6 @@ BomDecoder
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\ENCODING\CHARFORMAT\CHARENCODINGBASE.CPP
|
||||
***********************************************************************/
|
||||
/***********************************************************************
|
||||
Author: Zihan Chen (vczh)
|
||||
Licensed under https://github.com/vczh-libraries/License
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
namespace vl
|
||||
{
|
||||
namespace stream
|
||||
{
|
||||
/***********************************************************************
|
||||
CharEncoderBase
|
||||
***********************************************************************/
|
||||
|
||||
void CharEncoderBase::Setup(IStream* _stream)
|
||||
{
|
||||
stream = _stream;
|
||||
}
|
||||
|
||||
void CharEncoderBase::Close()
|
||||
{
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
CharDecoderBase
|
||||
***********************************************************************/
|
||||
|
||||
void CharDecoderBase::Setup(IStream* _stream)
|
||||
{
|
||||
stream = _stream;
|
||||
}
|
||||
|
||||
void CharDecoderBase::Close()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\ENCODING\CHARFORMAT\CHARFORMAT.CPP
|
||||
***********************************************************************/
|
||||
@@ -1743,11 +1947,6 @@ UtfGeneralEncoder
|
||||
CHECK_FAIL(L"UtfGeneralEncoder<T>::Write(void*, vint)#Failed to write a complete string.");
|
||||
}
|
||||
}
|
||||
if (reader.HasIllegalChar())
|
||||
{
|
||||
Close();
|
||||
CHECK_FAIL(L"UtfGeneralEncoder<T>::Write(void*, vint)#Failed to write a complete string.");
|
||||
}
|
||||
availableChars = reader.SourceCluster().index;
|
||||
availableBytes = availableChars * sizeof(TExpect);
|
||||
}
|
||||
@@ -1771,7 +1970,7 @@ UtfGeneralDecoder
|
||||
template<typename TNative, typename TExpect>
|
||||
void UtfGeneralDecoder<TNative, TExpect>::Setup(IStream* _stream)
|
||||
{
|
||||
CharDecoderBase::Setup(_stream);
|
||||
DecoderBase::Setup(_stream);
|
||||
reader.Setup(_stream);
|
||||
}
|
||||
|
||||
|
||||
+129
-88
@@ -1254,14 +1254,18 @@ Author: Zihan Chen (vczh)
|
||||
Licensed under https://github.com/vczh-libraries/License
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef VCZH_STREAM_ENCODING
|
||||
#define VCZH_STREAM_ENCODING
|
||||
#ifndef VCZH_STREAM_ENCODING_ENCODING
|
||||
#define VCZH_STREAM_ENCODING_ENCODING
|
||||
|
||||
|
||||
namespace vl
|
||||
{
|
||||
namespace stream
|
||||
{
|
||||
/***********************************************************************
|
||||
IEncoder and IDecoder
|
||||
***********************************************************************/
|
||||
|
||||
/// <summary>Encoder interface. This interface defines a writable transformation from one stream to another stream. You can create a [T:vl.stream.EncoderStream] after you have an encoder.</summary>
|
||||
class IEncoder : public Interface
|
||||
{
|
||||
@@ -1303,11 +1307,98 @@ namespace vl
|
||||
/// <param name="_size">The expected size of the content in bytes in "_buffer" to receive.</param>
|
||||
virtual vint Read(void* _buffer, vint _size)=0;
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
EncoderBase and DecoderBase
|
||||
***********************************************************************/
|
||||
|
||||
/// <summary>Basic implementation of IEncoder.</summary>
|
||||
class EncoderBase : public Object, public IEncoder
|
||||
{
|
||||
protected:
|
||||
IStream* stream = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
void Setup(IStream* _stream) override;
|
||||
void Close() override;
|
||||
};
|
||||
|
||||
/// <summary>Basic implementation of IDecoder.</summary>
|
||||
class DecoderBase : public Object, public IDecoder
|
||||
{
|
||||
protected:
|
||||
IStream* stream = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
void Setup(IStream* _stream) override;
|
||||
void Close() override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
.\ENCODING\BASE64ENCODING.H
|
||||
***********************************************************************/
|
||||
/***********************************************************************
|
||||
Author: Zihan Chen (vczh)
|
||||
Licensed under https://github.com/vczh-libraries/License
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef VCZH_STREAM_ENCODING_BASE64ENCODING
|
||||
#define VCZH_STREAM_ENCODING_BASE64ENCODING
|
||||
|
||||
|
||||
namespace vl
|
||||
{
|
||||
namespace stream
|
||||
{
|
||||
constexpr const vint Base64CycleBytes = 3;
|
||||
constexpr const vint Base64CycleChars = 4;
|
||||
|
||||
/***********************************************************************
|
||||
Utf8Base64Encoder
|
||||
***********************************************************************/
|
||||
|
||||
class Utf8Base64Encoder : public EncoderBase
|
||||
{
|
||||
protected:
|
||||
uint8_t cache[Base64CycleBytes];
|
||||
vint cacheSize = 0;
|
||||
|
||||
void WriteBytesToCharArray(uint8_t* fromBytes, char8_t(&toChars)[Base64CycleChars], vint bytes);
|
||||
bool WriteCycle(uint8_t*& reading, vint& _size);
|
||||
bool WriteCache(uint8_t*& reading, vint& _size);
|
||||
public:
|
||||
vint Write(void* _buffer, vint _size) override;
|
||||
void Close() override;
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
Utf8Base64Decoder
|
||||
***********************************************************************/
|
||||
|
||||
class Utf8Base64Decoder : public DecoderBase
|
||||
{
|
||||
protected:
|
||||
uint8_t cache[Base64CycleBytes];
|
||||
vint cacheSize = 0;
|
||||
|
||||
vint ReadBytesFromCharArray(char8_t(&fromChars)[Base64CycleChars], uint8_t* toBytes);
|
||||
vint ReadCycle(uint8_t*& writing, vint& _size);
|
||||
void ReadCache(uint8_t*& writing, vint& _size);
|
||||
public:
|
||||
vint Read(void* _buffer, vint _size) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\ENCODING\CHARFORMAT\BOMENCODING.H
|
||||
***********************************************************************/
|
||||
@@ -1407,55 +1498,6 @@ Bom
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\ENCODING\CHARFORMAT\CHARENCODINGBASE.H
|
||||
***********************************************************************/
|
||||
/***********************************************************************
|
||||
Author: Zihan Chen (vczh)
|
||||
Licensed under https://github.com/vczh-libraries/License
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef VCZH_STREAM_ENCODING_CHARFORMAT_CHARENCODINGBASE
|
||||
#define VCZH_STREAM_ENCODING_CHARFORMAT_CHARENCODINGBASE
|
||||
|
||||
|
||||
namespace vl
|
||||
{
|
||||
namespace stream
|
||||
{
|
||||
/***********************************************************************
|
||||
CharEncoderBase and CharDecoderBase
|
||||
***********************************************************************/
|
||||
|
||||
/// <summary>Base type of all character encoder.</summary>
|
||||
class CharEncoderBase : public Object, public IEncoder
|
||||
{
|
||||
protected:
|
||||
IStream* stream = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
void Setup(IStream* _stream) override;
|
||||
void Close() override;
|
||||
};
|
||||
|
||||
/// <summary>Base type of all character decoder.</summary>
|
||||
class CharDecoderBase : public Object, public IDecoder
|
||||
{
|
||||
protected:
|
||||
IStream* stream = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
void Setup(IStream* _stream) override;
|
||||
void Close() override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
.\ENCODING\CHARFORMAT\MBCSENCODING.H
|
||||
***********************************************************************/
|
||||
@@ -1477,7 +1519,7 @@ MbcsEncoder
|
||||
***********************************************************************/
|
||||
|
||||
/// <summary>Encoder to write text in the local code page.</summary>
|
||||
class MbcsEncoder : public CharEncoderBase
|
||||
class MbcsEncoder : public EncoderBase
|
||||
{
|
||||
protected:
|
||||
vuint8_t cacheBuffer[sizeof(char32_t)];
|
||||
@@ -1494,7 +1536,7 @@ MbcsDecoder
|
||||
***********************************************************************/
|
||||
|
||||
/// <summary>Decoder to read text in the local code page.</summary>
|
||||
class MbcsDecoder : public CharDecoderBase
|
||||
class MbcsDecoder : public DecoderBase
|
||||
{
|
||||
protected:
|
||||
vuint8_t cacheBuffer[sizeof(wchar_t)];
|
||||
@@ -1557,30 +1599,35 @@ UtfStreamConsumer<T>
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class UtfStreamConsumerApiRedirection : public Object
|
||||
{
|
||||
private:
|
||||
T& internalConsumer;
|
||||
|
||||
public:
|
||||
UtfStreamConsumerApiRedirection(T& _internalConsumer)
|
||||
: internalConsumer(_internalConsumer)
|
||||
{
|
||||
}
|
||||
|
||||
void Setup(IStream* _stream)
|
||||
{
|
||||
internalConsumer.Setup(_stream);
|
||||
}
|
||||
|
||||
encoding::UtfCharCluster SourceCluster() const
|
||||
{
|
||||
return internalConsumer.SourceCluster();
|
||||
}
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
UtfStreamToStreamReader<TFrom, TTo>
|
||||
***********************************************************************/
|
||||
|
||||
template<typename TFrom, typename TTo>
|
||||
class UtfStreamToStreamReader : public encoding::UtfToUtfReaderBase<TFrom, TTo, UtfStreamConsumer<TFrom>>
|
||||
{
|
||||
public:
|
||||
void Setup(IStream* _stream)
|
||||
{
|
||||
this->internalReader.Setup(_stream);
|
||||
}
|
||||
|
||||
encoding::UtfCharCluster SourceCluster() const
|
||||
{
|
||||
return this->internalReader.SourceCluster();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TFrom, typename TTo>
|
||||
requires(std::is_same_v<TFrom, char32_t> || std::is_same_v<TTo, char32_t>)
|
||||
class UtfStreamToStreamReader<TFrom, TTo> : public encoding::UtfToUtfReaderBase<TFrom, TTo, UtfStreamConsumer<TFrom>>
|
||||
{
|
||||
};
|
||||
using UtfStreamToStreamReader = encoding::UtfToUtfReaderBase<TFrom, TTo, UtfStreamConsumer<TFrom>, UtfStreamConsumerApiRedirection>;
|
||||
|
||||
/***********************************************************************
|
||||
Unicode General
|
||||
@@ -1599,7 +1646,7 @@ Unicode General
|
||||
};
|
||||
|
||||
template<typename TNative, typename TExpect>
|
||||
class UtfGeneralEncoder : public CharEncoderBase
|
||||
class UtfGeneralEncoder : public EncoderBase
|
||||
{
|
||||
using TStringRangeReader = encoding::UtfStringRangeToStringRangeReader<TExpect, TNative>;
|
||||
protected:
|
||||
@@ -1612,7 +1659,7 @@ Unicode General
|
||||
};
|
||||
|
||||
template<typename TNative, typename TExpect>
|
||||
class UtfGeneralDecoder : public CharDecoderBase
|
||||
class UtfGeneralDecoder : public DecoderBase
|
||||
{
|
||||
using TStreamReader = UtfStreamToStreamReader<TNative, TExpect>;
|
||||
protected:
|
||||
@@ -1631,14 +1678,14 @@ Unicode General (without conversion)
|
||||
***********************************************************************/
|
||||
|
||||
template<typename T>
|
||||
class UtfGeneralEncoder<T, T> : public CharEncoderBase
|
||||
class UtfGeneralEncoder<T, T> : public EncoderBase
|
||||
{
|
||||
public:
|
||||
vint Write(void* _buffer, vint _size) override;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class UtfGeneralDecoder<T, T> : public CharDecoderBase
|
||||
class UtfGeneralDecoder<T, T> : public DecoderBase
|
||||
{
|
||||
public:
|
||||
vint Read(void* _buffer, vint _size) override;
|
||||
@@ -1807,8 +1854,8 @@ Author: Zihan Chen (vczh)
|
||||
Licensed under https://github.com/vczh-libraries/License
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef VCZH_STREAM_COMPRESSIONSTREAM
|
||||
#define VCZH_STREAM_COMPRESSIONSTREAM
|
||||
#ifndef VCZH_STREAM_ENCODING_LZWENCODING
|
||||
#define VCZH_STREAM_ENCODING_LZWENCODING
|
||||
|
||||
|
||||
namespace vl
|
||||
@@ -1861,11 +1908,9 @@ Compression
|
||||
/// You are not recommended to compress data more than 1 mega bytes at once using the encoder directly.
|
||||
/// <see cref="CompressStream"/> and <see cref="DecompressStream"/> is recommended.
|
||||
/// </remarks>
|
||||
class LzwEncoder : public LzwBase, public IEncoder
|
||||
class LzwEncoder : public LzwBase, public EncoderBase
|
||||
{
|
||||
protected:
|
||||
IStream* stream = 0;
|
||||
|
||||
vuint8_t buffer[lzw::BufferSize];
|
||||
vint bufferUsedBits = 0;
|
||||
lzw::Code* prefix;
|
||||
@@ -1887,7 +1932,6 @@ Compression
|
||||
LzwEncoder(bool (&existingBytes)[256]);
|
||||
~LzwEncoder();
|
||||
|
||||
void Setup(IStream* _stream)override;
|
||||
void Close()override;
|
||||
vint Write(void* _buffer, vint _size)override;
|
||||
};
|
||||
@@ -1897,10 +1941,9 @@ Compression
|
||||
/// You are not recommended to compress data more than 1 mega bytes at once using the encoder directly.
|
||||
/// <see cref="CompressStream"/> and <see cref="DecompressStream"/> is recommended.
|
||||
/// </remarks>
|
||||
class LzwDecoder :public LzwBase, public IDecoder
|
||||
class LzwDecoder :public LzwBase, public DecoderBase
|
||||
{
|
||||
protected:
|
||||
IStream* stream = 0;
|
||||
collections::List<lzw::Code*> dictionary;
|
||||
lzw::Code* lastCode = 0;
|
||||
|
||||
@@ -1930,8 +1973,6 @@ Compression
|
||||
LzwDecoder(bool (&existingBytes)[256]);
|
||||
~LzwDecoder();
|
||||
|
||||
void Setup(IStream* _stream)override;
|
||||
void Close()override;
|
||||
vint Read(void* _buffer, vint _size)override;
|
||||
};
|
||||
|
||||
@@ -2693,7 +2734,7 @@ Text Related
|
||||
/// <typeparam name="T">The character type.</typeparam>
|
||||
/// <remarks>
|
||||
/// To specify the encoding in the input stream,
|
||||
/// you are recommended to create a <see cref="DecoderStream"/> with a <see cref="CharDecoder"/>,
|
||||
/// you are recommended to create a <see cref="DecoderStream"/> with a <see cref="UtfGeneralDecoder"/> implementation,
|
||||
/// like <see cref="BomDecoder"/>, <see cref="MbcsDecoder"/>, <see cref="Utf16Decoder"/>, <see cref="Utf16BEDecoder"/> or <see cref="Utf8Decoder"/>.
|
||||
/// </remarks>
|
||||
/// <example output="false"><![CDATA[
|
||||
@@ -2726,7 +2767,7 @@ Text Related
|
||||
/// <typeparam name="T">The character type.</typeparam>
|
||||
/// <remarks>
|
||||
/// To specify the encoding in the input stream,
|
||||
/// you are recommended to create a <see cref="EncoderStream"/> with a <see cref="CharEncoder"/>,
|
||||
/// you are recommended to create a <see cref="EncoderStream"/> with a <see cref="UtfGeneralEncoder"/> implementation,
|
||||
/// like <see cref="BomEncoder"/>, <see cref="MbcsEncoder"/>, <see cref="Utf16Encoder"/>, <see cref="Utf16BEEncoder"/> or <see cref="Utf8Encoder"/>.
|
||||
/// </remarks>
|
||||
/// <example output="false"><![CDATA[
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user