improved conversion utilities

This commit is contained in:
Martchus 2015-07-18 01:11:12 +02:00
parent 62d2be3340
commit c62e25ee2a
8 changed files with 87 additions and 58 deletions

View File

@ -41,11 +41,8 @@
* \namespace ConversionUtilities * \namespace ConversionUtilities
* \brief Contains several functions providing conversions between different data types. * \brief Contains several functions providing conversions between different data types.
* *
* binaryconversion.h declares functions which convert base data types to an array of bytes, * binaryconversion.h declares functions which convert base data types to an array of bytes and vice versa.
* and an array of bytes to base data types. * stringconversion.h declares different functions around string conversion such as converting a number to a string and vice versa.
*
* stringconversion.h declares different functions around string conversion such as converting a
* number to a string and vice versa.
*/ */
namespace ConversionUtilities namespace ConversionUtilities
{ {
@ -116,9 +113,7 @@ LIB_EXPORT inline float32 toFloat32(uint32 fixed16value)
/*! /*!
* \brief Returns a 32-bit synchsafe integer converted from a normal 32-bit integer. * \brief Returns a 32-bit synchsafe integer converted from a normal 32-bit integer.
*
* \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file. * \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file.
*
* \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a> * \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a>
*/ */
LIB_EXPORT inline uint32 toSynchsafeInt(uint32 normalInt) LIB_EXPORT inline uint32 toSynchsafeInt(uint32 normalInt)
@ -131,9 +126,7 @@ LIB_EXPORT inline uint32 toSynchsafeInt(uint32 normalInt)
/*! /*!
* \brief Returns a normal 32-bit integer converted from a 32-bit synchsafe integer. * \brief Returns a normal 32-bit integer converted from a 32-bit synchsafe integer.
*
* \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file. * \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file.
*
* \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a> * \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a>
*/ */
LIB_EXPORT inline uint32 toNormalInt(uint32 synchsafeInt) LIB_EXPORT inline uint32 toNormalInt(uint32 synchsafeInt)
@ -146,5 +139,4 @@ LIB_EXPORT inline uint32 toNormalInt(uint32 synchsafeInt)
} }
#endif // CONVERSION_UTILITIES_CONVERT_H #endif // CONVERSION_UTILITIES_CONVERT_H

View File

@ -1,5 +1,9 @@
#ifdef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL #ifdef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL
#ifndef CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL
#error "Do not include binaryconversionprivate.h directly."
#endif
#include "types.h" #include "types.h"
#include "../application/global.h" #include "../application/global.h"
@ -143,12 +147,12 @@ LIB_EXPORT inline float32 toFloat32(const char *value)
{ {
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
int32 val = toInt64(value); int32 val = toInt64(value);
char *c = reinterpret_cast<char*>(&val); char *c = reinterpret_cast<char *>(&val);
return *reinterpret_cast<float32*>(c); return *reinterpret_cast<float32 *>(c);
#else #else
int32 val = toInt64(value); int32 val = toInt64(value);
char *c = reinterpret_cast<char*>(&val); char *c = reinterpret_cast<char *>(&val);
return *reinterpret_cast<float32*>(c); return *reinterpret_cast<float32 *>(c);
#endif #endif
} }
@ -159,12 +163,12 @@ LIB_EXPORT inline float64 toFloat64(const char *value)
{ {
#if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0 #if CONVERSION_UTILITIES_BINARY_CONVERSION_INTERNAL == 0
int64 val = toInt64(value); int64 val = toInt64(value);
char *c = reinterpret_cast<char*>(&val); char *c = reinterpret_cast<char *>(&val);
return *reinterpret_cast<float64*>(c); return *reinterpret_cast<float64*>(c);
#else #else
int64 val = toInt64(value); int64 val = toInt64(value);
char *c = reinterpret_cast<char*>(&val); char *c = reinterpret_cast<char *>(&val);
return *reinterpret_cast<float64*>(c); return *reinterpret_cast<float64 *>(c);
#endif #endif
} }
@ -289,8 +293,8 @@ LIB_EXPORT inline void getBytes(uint64 value, char *outputbuffer)
*/ */
LIB_EXPORT inline void getBytes(float32 value, char *outputbuffer) LIB_EXPORT inline void getBytes(float32 value, char *outputbuffer)
{ {
char *c = reinterpret_cast<char*>(&value); char *c = reinterpret_cast<char *>(&value);
int32 i = *reinterpret_cast<int32*>(c); int32 i = *reinterpret_cast<int32 *>(c);
getBytes(i, outputbuffer); getBytes(i, outputbuffer);
} }
@ -299,8 +303,8 @@ LIB_EXPORT inline void getBytes(float32 value, char *outputbuffer)
*/ */
LIB_EXPORT inline void getBytes(float64 value, char *outputbuffer) LIB_EXPORT inline void getBytes(float64 value, char *outputbuffer)
{ {
char *c = reinterpret_cast<char*>(&value); char *c = reinterpret_cast<char *>(&value);
int64 i = *reinterpret_cast<int64*>(c); int64 i = *reinterpret_cast<int64 *>(c);
getBytes(i, outputbuffer); getBytes(i, outputbuffer);
} }

View File

@ -4,7 +4,8 @@ namespace ConversionUtilities {
/*! /*!
* \class ConversionUtilities::ConversionException * \class ConversionUtilities::ConversionException
* \brief The exception that is thrown when an conversion error occurs. * \brief The ConversionException class is thrown by the various conversion
* functions of this library when a conversion error occurs.
*/ */
/*! /*!

View File

@ -23,9 +23,9 @@ void truncateString(string &str, char terminationChar)
/*! /*!
* \brief Converts the specified data size in byte to its equivalent std::string representation. * \brief Converts the specified data size in byte to its equivalent std::string representation.
* *
* An unit with appropriate binary prefix will be appended. * The unit with appropriate binary prefix will be appended.
*/ */
string dataSizeToString(int64 sizeInByte) string dataSizeToString(uint64 sizeInByte)
{ {
stringstream res(stringstream::in | stringstream::out); stringstream res(stringstream::in | stringstream::out);
res.setf(ios::fixed, ios::floatfield); res.setf(ios::fixed, ios::floatfield);
@ -33,13 +33,13 @@ string dataSizeToString(int64 sizeInByte)
if (sizeInByte < 1024LL) { if (sizeInByte < 1024LL) {
res << sizeInByte << " bytes"; res << sizeInByte << " bytes";
} else if (sizeInByte < 1048576LL) { } else if (sizeInByte < 1048576LL) {
res << ((double)sizeInByte / 1024.0) << " KiB"; res << (static_cast<double>(sizeInByte) / 1024.0) << " KiB";
} else if (sizeInByte < 1073741824LL) { } else if (sizeInByte < 1073741824LL) {
res << ((double)sizeInByte / 1048576.0) << " MiB"; res << (static_cast<double>(sizeInByte) / 1048576.0) << " MiB";
} else if (sizeInByte < 1099511627776LL) { } else if (sizeInByte < 1099511627776LL) {
res << ((double)sizeInByte / 1073741824.0) << " GiB"; res << (static_cast<double>(sizeInByte) / 1073741824.0) << " GiB";
} else { } else {
res << ((double)sizeInByte / 1099511627776.0) << " TiB"; res << (static_cast<double>(sizeInByte) / 1099511627776.0) << " TiB";
} }
return res.str(); return res.str();
} }
@ -47,10 +47,10 @@ string dataSizeToString(int64 sizeInByte)
/*! /*!
* \brief Converts the specified bitrate in kbit/s to its equivalent std::string representation. * \brief Converts the specified bitrate in kbit/s to its equivalent std::string representation.
* *
* An unit with appropriate binary prefix will be appended. * The unit with appropriate binary prefix will be appended.
* *
* \param bitrateInKbitsPerSecond Specifies The bitrate to be converted in kbit/s. * \param bitrateInKbitsPerSecond Specifies the bitrate in kbit/s.
* \param useIecBinaryPrefixes Indicates whether IEC binary prefixes should be used (eg. Kib/s). * \param useIecBinaryPrefixes Indicates whether IEC binary prefixes should be used (eg. KiB/s).
* *
* \sa <a href="http://en.wikipedia.org/wiki/Binary_prefix">Binary prefix - Wikipedia</a> * \sa <a href="http://en.wikipedia.org/wiki/Binary_prefix">Binary prefix - Wikipedia</a>
*/ */
@ -82,8 +82,8 @@ string bitrateToString(double bitrateInKbitsPerSecond, bool useIecBinaryPrefixes
return res.str(); return res.str();
} }
static const char *base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; const char *base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char base64Pad = '='; const char base64Pad = '=';
/*! /*!
* \brief Encodes the specified data to a base64 string. * \brief Encodes the specified data to a base64 string.

View File

@ -36,8 +36,7 @@ typename Container::value_type joinStrings(const Container &strings, const typen
{ {
typename Container::value_type res; typename Container::value_type res;
if(strings.size()) { if(strings.size()) {
size_t entries = 0; size_t entries = 0, size = 0;
size_t size = 0;
for(const auto &str : strings) { for(const auto &str : strings) {
if(!omitEmpty || !str.empty()) { if(!omitEmpty || !str.empty()) {
size += str.size(); size += str.size();
@ -149,13 +148,9 @@ template <typename StringType> LIB_EXPORT void findAndReplace(StringType &str, c
/*! /*!
* \brief Converts the given \a number to its equivalent std::string representation using the specified \a base. * \brief Converts the given \a number to its equivalent std::string representation using the specified \a base.
*
* \tparam NumberType The data type of the given number. * \tparam NumberType The data type of the given number.
* \tparam StringType The string type (should be an instantiation of the basic_string class template). * \tparam StringType The string type (should be an instantiation of the basic_string class template).
*
* \sa numberToWString()
* \sa stringToNumber() * \sa stringToNumber()
* \sa wstringToNumber()
*/ */
template <typename NumberType, typename StringType = std::string> LIB_EXPORT StringType numberToString(NumberType number, int base = 10) template <typename NumberType, typename StringType = std::string> LIB_EXPORT StringType numberToString(NumberType number, int base = 10)
{ {
@ -166,15 +161,10 @@ template <typename NumberType, typename StringType = std::string> LIB_EXPORT Str
/*! /*!
* \brief Converts the given \a string to a numeric value using the specified \a base. * \brief Converts the given \a string to a numeric value using the specified \a base.
*
* \tparam NumberType The data type used to store the converted value. * \tparam NumberType The data type used to store the converted value.
* \tparam StringType The string type (should be an instantiation of the basic_string class template). * \tparam StringType The string type (should be an instantiation of the basic_string class template).
*
* \throws A ConversionException will be thrown if the provided string is not a valid number. * \throws A ConversionException will be thrown if the provided string is not a valid number.
*
* \sa numberToString() * \sa numberToString()
* \sa numberToWString()
* \sa wstringToNumber()
*/ */
template <typename NumberType, typename StringType> LIB_EXPORT NumberType stringToNumber(const StringType &string, int base = 10) template <typename NumberType, typename StringType> LIB_EXPORT NumberType stringToNumber(const StringType &string, int base = 10)
{ {
@ -204,7 +194,7 @@ template <typename T> LIB_EXPORT std::string interpretIntegerAsString(T integer,
return std::string(buffer + startOffset, sizeof(T) - startOffset); return std::string(buffer + startOffset, sizeof(T) - startOffset);
} }
LIB_EXPORT std::string dataSizeToString(int64 sizeInByte); LIB_EXPORT std::string dataSizeToString(uint64 sizeInByte);
LIB_EXPORT std::string bitrateToString(double speedInKbitsPerSecond, bool useByteInsteadOfBits = false); LIB_EXPORT std::string bitrateToString(double speedInKbitsPerSecond, bool useByteInsteadOfBits = false);
LIB_EXPORT std::string encodeBase64(const std::vector<char> &bytes); LIB_EXPORT std::string encodeBase64(const std::vector<char> &bytes);
LIB_EXPORT std::vector<char> decodeBase64(const std::string &encoded); LIB_EXPORT std::vector<char> decodeBase64(const std::string &encoded);

View File

@ -125,6 +125,12 @@ string BinaryReader::readLengthPrefixedString()
*/ */
string BinaryReader::readString(size_t length) string BinaryReader::readString(size_t length)
{ {
//string res;
//res.reserve(length);
//for(; length; --length) {
// res.push_back(static_cast<string::value_type>(m_stream->get()));
//}
//return res;
unique_ptr<char []> buff = make_unique<char []>(length); unique_ptr<char []> buff = make_unique<char []>(length);
m_stream->read(buff.get(), length); m_stream->read(buff.get(), length);
return string(buff.get(), length); return string(buff.get(), length);

View File

@ -39,6 +39,8 @@ public:
uint32 readUInt24BE(); uint32 readUInt24BE();
int32 readInt32BE(); int32 readInt32BE();
uint32 readUInt32BE(); uint32 readUInt32BE();
uint64 readUInt40BE();
uint64 readUInt56BE();
int64 readInt64BE(); int64 readInt64BE();
uint64 readUInt64BE(); uint64 readUInt64BE();
float32 readFloat32BE(); float32 readFloat32BE();
@ -49,6 +51,8 @@ public:
uint32 readUInt24LE(); uint32 readUInt24LE();
int32 readInt32LE(); int32 readInt32LE();
uint32 readUInt32LE(); uint32 readUInt32LE();
uint64 readUInt40LE();
uint64 readUInt56LE();
int64 readInt64LE(); int64 readInt64LE();
uint64 readUInt64LE(); uint64 readUInt64LE();
float32 readFloat32LE(); float32 readFloat32LE();
@ -211,7 +215,7 @@ inline uint16 BinaryReader::readUInt16BE()
*/ */
inline int32 BinaryReader::readInt24BE() inline int32 BinaryReader::readInt24BE()
{ {
m_buffer[0] = 0; *m_buffer = 0;
m_stream->read(m_buffer + 1, 3); m_stream->read(m_buffer + 1, 3);
int32 val = ConversionUtilities::BE::toInt32(m_buffer); int32 val = ConversionUtilities::BE::toInt32(m_buffer);
if(val >= 0x800000) { if(val >= 0x800000) {
@ -225,7 +229,7 @@ inline int32 BinaryReader::readInt24BE()
*/ */
inline uint32 BinaryReader::readUInt24BE() inline uint32 BinaryReader::readUInt24BE()
{ {
m_buffer[0] = 0; *m_buffer = 0;
m_stream->read(m_buffer + 1, 3); m_stream->read(m_buffer + 1, 3);
return ConversionUtilities::BE::toUInt32(m_buffer); return ConversionUtilities::BE::toUInt32(m_buffer);
} }
@ -248,6 +252,26 @@ inline uint32 BinaryReader::readUInt32BE()
return ConversionUtilities::BE::toUInt32(m_buffer); return ConversionUtilities::BE::toUInt32(m_buffer);
} }
/*!
* \brief Reads a 40-bit big endian unsigned integer from the current stream and advances the current position of the stream by five bytes.
*/
inline uint64 BinaryReader::readUInt40BE()
{
*reinterpret_cast<uint32 *>(m_buffer) = 0;
m_stream->read(m_buffer + 3, 5);
return ConversionUtilities::BE::toUInt64(m_buffer);
}
/*!
* \brief Reads a 56-bit big endian unsigned integer from the current stream and advances the current position of the stream by seven bytes.
*/
inline uint64 BinaryReader::readUInt56BE()
{
*m_buffer = 0;
m_stream->read(m_buffer + 1, 5);
return ConversionUtilities::BE::toUInt64(m_buffer);
}
/*! /*!
* \brief Reads a 64-bit big endian signed integer from the current stream and advances the current position of the stream by eight bytes. * \brief Reads a 64-bit big endian signed integer from the current stream and advances the current position of the stream by eight bytes.
*/ */
@ -307,7 +331,7 @@ inline uint16 BinaryReader::readUInt16LE()
*/ */
inline int32 BinaryReader::readInt24LE() inline int32 BinaryReader::readInt24LE()
{ {
m_buffer[3] = 0; *(m_buffer + 3) = 0;
m_stream->read(m_buffer, 3); m_stream->read(m_buffer, 3);
int32 val = ConversionUtilities::LE::toInt32(m_buffer); int32 val = ConversionUtilities::LE::toInt32(m_buffer);
if(val >= 0x800000) { if(val >= 0x800000) {
@ -321,7 +345,7 @@ inline int32 BinaryReader::readInt24LE()
*/ */
inline uint32 BinaryReader::readUInt24LE() inline uint32 BinaryReader::readUInt24LE()
{ {
m_buffer[3] = 0; *(m_buffer + 3) = 0;
m_stream->read(m_buffer, 3); m_stream->read(m_buffer, 3);
return ConversionUtilities::LE::toUInt32(m_buffer); return ConversionUtilities::LE::toUInt32(m_buffer);
} }
@ -344,6 +368,26 @@ inline uint32 BinaryReader::readUInt32LE()
return ConversionUtilities::LE::toUInt32(m_buffer); return ConversionUtilities::LE::toUInt32(m_buffer);
} }
/*!
* \brief Reads a 40-bit little endian unsigned integer from the current stream and advances the current position of the stream by five bytes.
*/
inline uint64 BinaryReader::readUInt40LE()
{
*reinterpret_cast<uint32 *>(m_buffer + 3) = 0;
m_stream->read(m_buffer, 5);
return ConversionUtilities::LE::toUInt64(m_buffer);
}
/*!
* \brief Reads a 56-bit little endian unsigned integer from the current stream and advances the current position of the stream by seven bytes.
*/
inline uint64 BinaryReader::readUInt56LE()
{
*(m_buffer + 7) = 0;
m_stream->read(m_buffer, 7);
return ConversionUtilities::LE::toUInt64(m_buffer);
}
/*! /*!
* \brief Reads a 64-bit little endian signed integer from the current stream and advances the current position of the stream by eight bytes. * \brief Reads a 64-bit little endian signed integer from the current stream and advances the current position of the stream by eight bytes.
*/ */
@ -400,6 +444,7 @@ inline byte BinaryReader::readByte()
/*! /*!
* \brief Reads a boolean value from the current stream and advances the current position of the stream by one byte. * \brief Reads a boolean value from the current stream and advances the current position of the stream by one byte.
* \sa IoUtilities::BitReader
*/ */
inline bool BinaryReader::readBool() inline bool BinaryReader::readBool()
{ {
@ -408,9 +453,7 @@ inline bool BinaryReader::readBool()
/*! /*!
* \brief Reads a 32-bit big endian synchsafe integer from the current stream and advances the current position of the stream by four bytes. * \brief Reads a 32-bit big endian synchsafe integer from the current stream and advances the current position of the stream by four bytes.
*
* \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file. * \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file.
*
* \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a> * \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a>
*/ */
inline uint32 BinaryReader::readSynchsafeUInt32BE() inline uint32 BinaryReader::readSynchsafeUInt32BE()
@ -436,9 +479,7 @@ inline float32 BinaryReader::readFixed16BE()
/*! /*!
* \brief Reads a 32-bit little endian synchsafe integer from the current stream and advances the current position of the stream by four bytes. * \brief Reads a 32-bit little endian synchsafe integer from the current stream and advances the current position of the stream by four bytes.
*
* \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file. * \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file.
*
* \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a> * \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a>
*/ */
inline uint32 BinaryReader::readSynchsafeUInt32LE() inline uint32 BinaryReader::readSynchsafeUInt32LE()

View File

@ -210,7 +210,6 @@ inline void BinaryWriter::writeUInt16BE(uint16 value)
*/ */
inline void BinaryWriter::writeInt24BE(int32 value) inline void BinaryWriter::writeInt24BE(int32 value)
{ {
// discard most significant byte
ConversionUtilities::BE::getBytes(value, m_buffer); ConversionUtilities::BE::getBytes(value, m_buffer);
m_stream->write(m_buffer + 1, 3); m_stream->write(m_buffer + 1, 3);
} }
@ -392,9 +391,7 @@ inline void BinaryWriter::writeTerminatedString(const std::string &value)
/*! /*!
* \brief Writes a 32-bit big endian synchsafe integer to the current stream and advances the current position of the stream by four bytes. * \brief Writes a 32-bit big endian synchsafe integer to the current stream and advances the current position of the stream by four bytes.
*
* \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file. * \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file.
*
* \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a> * \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a>
*/ */
inline void BinaryWriter::writeSynchsafeUInt32BE(uint32 valueToConvertAndWrite) inline void BinaryWriter::writeSynchsafeUInt32BE(uint32 valueToConvertAndWrite)
@ -420,9 +417,7 @@ inline void BinaryWriter::writeFixed16BE(float32 valueToConvertAndWrite)
/*! /*!
* \brief Writes a 32-bit little endian synchsafe integer to the current stream and advances the current position of the stream by four bytes. * \brief Writes a 32-bit little endian synchsafe integer to the current stream and advances the current position of the stream by four bytes.
*
* \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file. * \remarks Synchsafe integers appear in ID3 tags that are attached to an MP3 file.
*
* \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a> * \sa <a href="http://id3.org/id3v2.4.0-structure">ID3 tag version 2.4.0 - Main Structure</a>
*/ */
inline void BinaryWriter::writeSynchsafeUInt32LE(uint32 valueToConvertAndWrite) inline void BinaryWriter::writeSynchsafeUInt32LE(uint32 valueToConvertAndWrite)