From: <man...@us...> - 2013-06-01 19:28:28
|
Revision: 2269 http://sourceforge.net/p/modplug/code/2269 Author: manxorist Date: 2013-06-01 19:28:20 +0000 (Sat, 01 Jun 2013) Log Message: ----------- Merged revision(s) 2204, 2208, 2212, 2214, 2217, 2220, 2224, 2259, 2261-2262, 2264, 2267 from branches/manx/mptstring-stdstring-support: [Ref] Add support for std::string in addition to fixed size char arrays to mpt::String::Read, mpt::String::Write, mpt::String::Copy and related mpt::String functions. [Ref] Support std::String with FileReader::ReadString. ........ [Ref] Use the new std::string-enabled mpt::String::CopyN and mpt::String::Write. ........ [Fix] Correctly handle the case of zero length std::string in mpt::String::Write and mpt::String::Copy. [Ref] Add testcases for strings with \0 as the first character. ........ [Ref] Support mpt::String::Write writing to already allocated, but dynamically sized, std::vector<char>. ........ [Ref] More std::string support overloads for mpt::String::Write and mpt::String::Copy. [Ref] Add SanitizeFilename(std::string). ........ [Fix] StringFixer.h needs <string> and <vector>. ........ [Fix] GCC build fixes. ........ [Ref] Remove pointless mpt::String::CopyN(char &[], std::string, size_t). [Ref] Add SanitizeFilename(CString &). ........ [Var] Fixup comments. ........ [Ref] Add mpt::strnlen(const char *, std::size_t). [Fix] Fix mpt::String::CopyN(std::string &, const char *, size_t) to not overrun source buffer if it is not null-terminated. ........ [Ref] Base mpt::String::Copy(std::string &, const char &[]) on mpt::String::CopyN. [Ref] Cleanup StringFixer.h. ........ [Ref] Remove SetNullTerminator(std::string &). ........ Modified Paths: -------------- trunk/OpenMPT/common/StringFixer.h trunk/OpenMPT/common/misc_util.h trunk/OpenMPT/common/mptString.h trunk/OpenMPT/soundlib/FileReader.h trunk/OpenMPT/soundlib/Load_umx.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/test/test.cpp Property Changed: ---------------- trunk/OpenMPT/ Index: trunk/OpenMPT =================================================================== --- trunk/OpenMPT 2013-06-01 19:23:32 UTC (rev 2268) +++ trunk/OpenMPT 2013-06-01 19:28:20 UTC (rev 2269) Property changes on: trunk/OpenMPT ___________________________________________________________________ Modified: svn:mergeinfo ## -1,6 +1,7 ## /branches/manx/build-speedup:1586-1589 /branches/manx/gcc-fixes:2018-2022,2024-2048,2052-2071,2075-2077,2080,2087-2089 /branches/manx/header-dependencies-cleanups:1394-1397,1401-1402,1405-1406 +/branches/manx/mptstring-stdstring-support:2204,2208,2212,2214,2217,2220,2224,2259,2261-2262,2264,2267 /branches/manx/nonglobal-mixer:1715-1841 /branches/manx/profiler:1813 /branches/manx/project-files-cleanups:1378-1382 \ No newline at end of property Modified: trunk/OpenMPT/common/StringFixer.h =================================================================== --- trunk/OpenMPT/common/StringFixer.h 2013-06-01 19:23:32 UTC (rev 2268) +++ trunk/OpenMPT/common/StringFixer.h 2013-06-01 19:28:20 UTC (rev 2269) @@ -11,6 +11,9 @@ #pragma once +#include <string> +#include <vector> +#include <cstring> #include <string.h> namespace mpt { namespace String @@ -26,7 +29,14 @@ buffer[size - 1] = 0; } + inline void SetNullTerminator(char *buffer, size_t size) + //------------------------------------------------------ + { + ASSERT(size > 0); + buffer[size - 1] = 0; + } + // Remove any chars after the first null char template <size_t size> void FixNullString(char (&buffer)[size]) @@ -47,7 +57,21 @@ } } + inline void FixNullString(std::string & str) + //------------------------------------------ + { + for(std::size_t i = 0; i < str.length(); ++i) + { + if(str[i] == '\0') + { + // if we copied \0 in the middle of the buffer, terminate std::string here + str.resize(i); + break; + } + } + } + enum ReadWriteMode { // Reading / Writing: Standard null-terminated string handling. @@ -65,12 +89,78 @@ // Copy a string from srcBuffer to destBuffer using a given read mode. + // Used for reading strings from files. + // Only use this version of the function if the size of the source buffer is variable. + template <ReadWriteMode mode> + void Read(std::string &dest, const char *srcBuffer, const size_t srcSize) + //----------------------------------------------------------------------- + { + //ASSERT(srcSize > 0); + + dest.clear(); + + if(mode == nullTerminated || mode == maybeNullTerminated) + { + // Copy null-terminated string + // We cannot use std::string::assign(const char*, size_t) because that would not stop at \0s in the middle of the buffer. + for(const char *src = srcBuffer; src != srcBuffer + srcSize && *src; ++src) + { + dest.push_back(*src); + } + + if(mode == nullTerminated) + { + // We assume that the last character of the source buffer is null. + if(dest.length() == srcSize) + { + dest.resize(dest.length() - 1); + } + } + + } else if(mode == spacePadded || mode == spacePaddedNull) + { + // Copy string over, but convert null characters to spaces. + for(const char *src = srcBuffer; src != srcBuffer + srcSize; ++src) + { + char c = *src; + if(c == '\0') + { + c = ' '; + } + dest.push_back(c); + } + + if(mode == spacePaddedNull) + { + if(dest.length() == srcSize) + { + dest.resize(dest.length() - 1); + } + } + + // Trim trailing spaces. + dest = mpt::String::RTrim(dest); + + } + } + + // Used for reading strings from files. + // Preferrably use this version of the function, it is safer. + template <ReadWriteMode mode, size_t srcSize> + void Read(std::string &dest, const char (&srcBuffer)[srcSize]) + //------------------------------------------------------------ + { + STATIC_ASSERT(srcSize > 0); + Read<mode>(dest, srcBuffer, srcSize); + } + + // Copy a string from srcBuffer to destBuffer using a given read mode. // Used for reading strings from files. // Only use this version of the function if the size of the source buffer is variable. template <ReadWriteMode mode, size_t destSize> void Read(char (&destBuffer)[destSize], const char *srcBuffer, const size_t srcSize) - //---------------------------------------------------------------------------------------- + //---------------------------------------------------------------------------------- { STATIC_ASSERT(destSize > 0); //ASSERT(srcSize > 0); @@ -148,12 +238,11 @@ } } - // Used for reading strings from files. // Preferrably use this version of the function, it is safer. template <ReadWriteMode mode, size_t destSize, size_t srcSize> void Read(char (&destBuffer)[destSize], const char (&srcBuffer)[srcSize]) - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------- { STATIC_ASSERT(destSize > 0); STATIC_ASSERT(srcSize > 0); @@ -162,13 +251,13 @@ // Copy a string from srcBuffer to destBuffer using a given write mode. - // Used for writing strings to files. - // Only use this version of the function if the size of the source buffer is variable. - template <ReadWriteMode mode, size_t destSize> - void Write(char (&destBuffer)[destSize], const char *srcBuffer, const size_t srcSize) - //----------------------------------------------------------------------------------------- + // You should only use this function if src and dest are dynamically sized, + // otherwise use one of the safer overloads below. + template <ReadWriteMode mode> + void Write(char *destBuffer, const size_t destSize, const char *srcBuffer, const size_t srcSize) + //---------------------------------------------------------------------------------------------- { - STATIC_ASSERT(destSize > 0); + ASSERT(destSize > 0); ASSERT(srcSize > 0); const size_t maxSize = MIN(destSize, srcSize); @@ -201,33 +290,89 @@ if(mode == nullTerminated || mode == spacePaddedNull) { // Make sure that destination is really null-terminated. - SetNullTerminator(destBuffer); + SetNullTerminator(destBuffer, destSize); } } + // Copy a string from srcBuffer to a dynamically sized std::vector destBuffer using a given write mode. + // Used for writing strings to files. + // Only use this version of the function if the size of the source buffer is variable and the destination buffer also has variable size. + template <ReadWriteMode mode> + void Write(std::vector<char> &destBuffer, const char *srcBuffer, const size_t srcSize) + //------------------------------------------------------------------------------------ + { + ASSERT(destBuffer.size() > 0); + ASSERT(srcSize > 0); + Write<mode>(destBuffer.data(), destBuffer.size(), srcBuffer, srcSize); + } + // Copy a string from srcBuffer to destBuffer using a given write mode. // Used for writing strings to files. + // Only use this version of the function if the size of the source buffer is variable. + template <ReadWriteMode mode, size_t destSize> + void Write(char (&destBuffer)[destSize], const char *srcBuffer, const size_t srcSize) + //----------------------------------------------------------------------------------- + { + STATIC_ASSERT(destSize > 0); + ASSERT(srcSize > 0); + Write<mode>(destBuffer, destSize, srcBuffer, srcSize); + } + + // Copy a string from srcBuffer to destBuffer using a given write mode. + // Used for writing strings to files. // Preferrably use this version of the function, it is safer. template <ReadWriteMode mode, size_t destSize, size_t srcSize> void Write(char (&destBuffer)[destSize], const char (&srcBuffer)[srcSize]) - //------------------------------------------------------------------------------ + //------------------------------------------------------------------------ { STATIC_ASSERT(destSize > 0); STATIC_ASSERT(srcSize > 0); Write<mode, destSize>(destBuffer, srcBuffer, srcSize); } + template <ReadWriteMode mode> + void Write(char *destBuffer, const size_t destSize, const std::string &src) + //------------------------------------------------------------------------- + { + ASSERT(destSize > 0); + Write<mode>(destBuffer, destSize, src.c_str(), src.length()); + } + template <ReadWriteMode mode> + void Write(std::vector<char> &destBuffer, const std::string &src) + //--------------------------------------------------------------- + { + ASSERT(destBuffer.size() > 0); + Write<mode>(destBuffer, src.c_str(), src.length()); + } + + template <ReadWriteMode mode, size_t destSize> + void Write(char (&destBuffer)[destSize], const std::string &src) + //-------------------------------------------------------------- + { + STATIC_ASSERT(destSize > 0); + Write<mode, destSize>(destBuffer, src.c_str(), src.length()); + } + + // Copy from a char array to a fixed size char array. template <size_t destSize> void CopyN(char (&destBuffer)[destSize], const char *srcBuffer, const size_t srcSize = SIZE_MAX) //---------------------------------------------------------------------------------------------- { const size_t copySize = MIN(destSize - 1, srcSize); - strncpy(destBuffer, srcBuffer, copySize); + std::strncpy(destBuffer, srcBuffer, copySize); destBuffer[copySize] = '\0'; } + // Copy at most srcSize characters from srcBuffer to a std::string. + static inline void CopyN(std::string &dest, const char *srcBuffer, const size_t srcSize = SIZE_MAX) + //------------------------------------------------------------------------------------------------- + { + dest.assign(srcBuffer, srcBuffer + mpt::strnlen(srcBuffer, srcSize)); + } + + // Copy from one fixed size char array to another one. template <size_t destSize, size_t srcSize> void Copy(char (&destBuffer)[destSize], const char (&srcBuffer)[srcSize]) @@ -236,6 +381,29 @@ CopyN(destBuffer, srcBuffer, srcSize); } + // Copy from a std::string to a fixed size char array. + template <size_t destSize> + void Copy(char (&destBuffer)[destSize], const std::string &src) + //------------------------------------------------------------- + { + CopyN(destBuffer, src.c_str(), src.length()); + } + // Copy from a fixed size char array to a std::string. + template <size_t srcSize> + void Copy(std::string &dest, const char (&srcBuffer)[srcSize]) + //---------------------------------------------------------------------------- + { + CopyN(dest, srcBuffer, srcSize); + } + + // Copy from a std::string to a std::string. + static inline void Copy(std::string &dest, const std::string &src) + //---------------------------------------------------------------- + { + dest.assign(src); + } + + } } // namespace mpt::String Modified: trunk/OpenMPT/common/misc_util.h =================================================================== --- trunk/OpenMPT/common/misc_util.h 2013-06-01 19:23:32 UTC (rev 2268) +++ trunk/OpenMPT/common/misc_util.h 2013-06-01 19:28:20 UTC (rev 2269) @@ -184,6 +184,23 @@ #endif // MODPLUG_TRACKER +static inline char SanitizeFilenameChar(char c) +//--------------------------------------------- +{ + if( c == '\\' || + c == '\"' || + c == '/' || + c == ':' || + c == '?' || + c == '<' || + c == '>' || + c == '*') + { + c = '_'; + } + return c; +} + // Sanitize a filename (remove special chars) template <size_t size> void SanitizeFilename(char (&buffer)[size]) @@ -192,19 +209,26 @@ STATIC_ASSERT(size > 0); for(size_t i = 0; i < size; i++) { - if( buffer[i] == '\\' || - buffer[i] == '\"' || - buffer[i] == '/' || - buffer[i] == ':' || - buffer[i] == '?' || - buffer[i] == '<' || - buffer[i] == '>' || - buffer[i] == '*') - { - buffer[i] = '_'; - } + buffer[i] = SanitizeFilenameChar(buffer[i]); } } +static inline void SanitizeFilename(std::string &str) +//--------------------------------------------------- +{ + for(size_t i = 0; i < str.length(); i++) + { + str[i] = SanitizeFilenameChar(str[i]); + } +} +#ifdef MODPLUG_TRACKER +static inline void SanitizeFilename(CString &str) +//----------------------------------------------- +{ + std::string tmp = str; + SanitizeFilename(tmp); + str = tmp.c_str(); +} +#endif // Greatest Common Divisor. Modified: trunk/OpenMPT/common/mptString.h =================================================================== --- trunk/OpenMPT/common/mptString.h 2013-06-01 19:23:32 UTC (rev 2268) +++ trunk/OpenMPT/common/mptString.h 2013-06-01 19:28:20 UTC (rev 2269) @@ -12,6 +12,7 @@ #include <string> #include <cstdio> +#include <cstring> #include <stdio.h> #if MPT_COMPILER_GCC || MPT_COMPILER_CLANG #include <strings.h> // for strcasecmp @@ -105,6 +106,24 @@ } // namespace String +static inline std::size_t strnlen(const char *str, std::size_t n) +//--------------------------------------------------------------- +{ + if(n >= SIZE_MAX) + { + return std::strlen(str); + } + for(std::size_t i = 0; i < n; ++i) + { + if(str[i] == '\0') + { + return i; + } + } + return n; +} + + } // namespace mpt Modified: trunk/OpenMPT/soundlib/FileReader.h =================================================================== --- trunk/OpenMPT/soundlib/FileReader.h 2013-06-01 19:23:32 UTC (rev 2268) +++ trunk/OpenMPT/soundlib/FileReader.h 2013-06-01 19:28:20 UTC (rev 2269) @@ -772,6 +772,22 @@ } } + // Read a string of length srcSize into a std::string dest using a given read mode. + // The file cursor is advanced by "srcSize" bytes. + template<mpt::String::ReadWriteMode mode> + bool ReadString(std::string &dest, const off_t srcSize) + { + if(CanRead(srcSize)) + { + mpt::String::Read<mode>(dest, DataContainer().GetPartialRawData(streamPos, srcSize), srcSize); + streamPos += srcSize; + return true; + } else + { + return false; + } + } + // Read an array. // If successful, the file cursor is advanced by the size of the array. // Otherwise, the target is zeroed. Modified: trunk/OpenMPT/soundlib/Load_umx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_umx.cpp 2013-06-01 19:23:32 UTC (rev 2268) +++ trunk/OpenMPT/soundlib/Load_umx.cpp 2013-06-01 19:28:20 UTC (rev 2269) @@ -296,7 +296,7 @@ m_nSamples++; if(static_cast<size_t>(objName) < names.size()) { - mpt::String::CopyN(m_szNames[GetNumSamples()], names[objName].c_str()); + mpt::String::Copy(m_szNames[GetNumSamples()], names[objName]); } } } Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2013-06-01 19:23:32 UTC (rev 2268) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2013-06-01 19:28:20 UTC (rev 2269) @@ -654,7 +654,7 @@ mpt::String::Write<mpt::String::spacePadded>(fileHeader.songName, m_szNames[0]); fileHeader.eof = 0x1A; std::string openMptTrackerName = MptVersion::GetOpenMPTVersionStr(); - mpt::String::Write<mpt::String::spacePadded>(fileHeader.trackerName, openMptTrackerName.c_str(), openMptTrackerName.length()); + mpt::String::Write<mpt::String::spacePadded>(fileHeader.trackerName, openMptTrackerName); // Writing song header fileHeader.version = 0x0104; // XM Format v1.04 Modified: trunk/OpenMPT/test/test.cpp =================================================================== --- trunk/OpenMPT/test/test.cpp 2013-06-01 19:23:32 UTC (rev 2268) +++ trunk/OpenMPT/test/test.cpp 2013-06-01 19:28:20 UTC (rev 2269) @@ -429,6 +429,11 @@ VERIFY_EQUAL( mpt::String::RTrim(" "), "" ); VERIFY_EQUAL( mpt::String::Trim(" "), "" ); + // weird things with std::string containing \0 in the middle and trimming \0 + VERIFY_EQUAL( std::string("\0\ta\0b ",6).length(), 6 ); + VERIFY_EQUAL( mpt::String::RTrim(std::string("\0\ta\0b ",6)), std::string("\0\ta\0b",5) ); + VERIFY_EQUAL( mpt::String::Trim(std::string("\0\ta\0b\0",6),std::string("\0",1)), std::string("\ta\0b",4) ); + // These should fail to compile //Util::Round<std::string>(1.0); //Util::Round<int64>(1.0); @@ -1393,6 +1398,7 @@ void TestStringIO() //----------------- { + char src0[4] = { '\0', 'X', ' ', 'X' }; // Weird empty buffer char src1[4] = { 'X', ' ', '\0', 'X' }; // Weird buffer (hello Impulse Tracker) char src2[4] = { 'X', 'Y', 'Z', ' ' }; // Full buffer, last character space char src3[4] = { 'X', 'Y', 'Z', '!' }; // Full buffer, last character non-space @@ -1412,21 +1418,25 @@ VERIFY_EQUAL_NONCONT(dst[i], '\0'); /* Ensure that rest of the buffer is completely nulled */ // Check reading of null-terminated string into larger buffer + ReadTest(nullTerminated, dst1, src0, ""); ReadTest(nullTerminated, dst1, src1, "X "); ReadTest(nullTerminated, dst1, src2, "XYZ"); ReadTest(nullTerminated, dst1, src3, "XYZ"); // Check reading of string that should be null-terminated, but is maybe too long to still hold the null character. + ReadTest(maybeNullTerminated, dst1, src0, ""); ReadTest(maybeNullTerminated, dst1, src1, "X "); ReadTest(maybeNullTerminated, dst1, src2, "XYZ "); ReadTest(maybeNullTerminated, dst1, src3, "XYZ!"); // Check reading of space-padded strings with ignored last character + ReadTest(spacePaddedNull, dst1, src0, " X"); ReadTest(spacePaddedNull, dst1, src1, "X"); ReadTest(spacePaddedNull, dst1, src2, "XYZ"); ReadTest(spacePaddedNull, dst1, src3, "XYZ"); // Check reading of space-padded strings + ReadTest(spacePadded, dst1, src0, " X X"); ReadTest(spacePadded, dst1, src1, "X X"); ReadTest(spacePadded, dst1, src2, "XYZ"); ReadTest(spacePadded, dst1, src3, "XYZ!"); @@ -1434,21 +1444,25 @@ /////////////////////////////// // Check reading of null-terminated string into smaller buffer + ReadTest(nullTerminated, dst2, src0, ""); ReadTest(nullTerminated, dst2, src1, "X "); ReadTest(nullTerminated, dst2, src2, "XY"); ReadTest(nullTerminated, dst2, src3, "XY"); // Check reading of string that should be null-terminated, but is maybe too long to still hold the null character. + ReadTest(maybeNullTerminated, dst2, src0, ""); ReadTest(maybeNullTerminated, dst2, src1, "X "); ReadTest(maybeNullTerminated, dst2, src2, "XY"); ReadTest(maybeNullTerminated, dst2, src3, "XY"); // Check reading of space-padded strings with ignored last character + ReadTest(spacePaddedNull, dst2, src0, " X"); ReadTest(spacePaddedNull, dst2, src1, "X"); ReadTest(spacePaddedNull, dst2, src2, "XY"); ReadTest(spacePaddedNull, dst2, src3, "XY"); // Check reading of space-padded strings + ReadTest(spacePadded, dst2, src0, " X"); ReadTest(spacePadded, dst2, src1, "X"); ReadTest(spacePadded, dst2, src2, "XY"); ReadTest(spacePadded, dst2, src3, "XY"); @@ -1456,21 +1470,25 @@ /////////////////////////////// // Check writing of null-terminated string into larger buffer + WriteTest(nullTerminated, dst1, src0, ""); WriteTest(nullTerminated, dst1, src1, "X "); WriteTest(nullTerminated, dst1, src2, "XYZ "); WriteTest(nullTerminated, dst1, src3, "XYZ!"); // Check writing of string that should be null-terminated, but is maybe too long to still hold the null character. + WriteTest(maybeNullTerminated, dst1, src0, ""); WriteTest(maybeNullTerminated, dst1, src1, "X "); WriteTest(maybeNullTerminated, dst1, src2, "XYZ "); WriteTest(maybeNullTerminated, dst1, src3, "XYZ!"); // Check writing of space-padded strings with last character set to null + WriteTest(spacePaddedNull, dst1, src0, " "); WriteTest(spacePaddedNull, dst1, src1, "X "); WriteTest(spacePaddedNull, dst1, src2, "XYZ "); WriteTest(spacePaddedNull, dst1, src3, "XYZ! "); // Check writing of space-padded strings + WriteTest(spacePadded, dst1, src0, " "); WriteTest(spacePadded, dst1, src1, "X "); WriteTest(spacePadded, dst1, src2, "XYZ "); WriteTest(spacePadded, dst1, src3, "XYZ! "); @@ -1478,27 +1496,133 @@ /////////////////////////////// // Check writing of null-terminated string into smaller buffer + WriteTest(nullTerminated, dst2, src0, ""); WriteTest(nullTerminated, dst2, src1, "X "); WriteTest(nullTerminated, dst2, src2, "XY"); WriteTest(nullTerminated, dst2, src3, "XY"); // Check writing of string that should be null-terminated, but is maybe too long to still hold the null character. + WriteTest(maybeNullTerminated, dst2, src0, ""); WriteTest(maybeNullTerminated, dst2, src1, "X "); WriteTest(maybeNullTerminated, dst2, src2, "XYZ"); WriteTest(maybeNullTerminated, dst2, src3, "XYZ"); // Check writing of space-padded strings with last character set to null + WriteTest(spacePaddedNull, dst2, src0, " "); WriteTest(spacePaddedNull, dst2, src1, "X "); WriteTest(spacePaddedNull, dst2, src2, "XY"); WriteTest(spacePaddedNull, dst2, src3, "XY"); // Check writing of space-padded strings + WriteTest(spacePadded, dst2, src0, " "); WriteTest(spacePadded, dst2, src1, "X "); WriteTest(spacePadded, dst2, src2, "XYZ"); WriteTest(spacePadded, dst2, src3, "XYZ"); - /////////////////////////////// +#undef ReadTest +#undef WriteTest + { + + std::string dststring; + std::string src0string = std::string(src0, CountOf(src0)); + std::string src1string = std::string(src1, CountOf(src1)); + std::string src2string = std::string(src2, CountOf(src2)); + std::string src3string = std::string(src3, CountOf(src3)); + +#define ReadTest(mode, dst, src, expectedResult) \ + mpt::String::Read<mpt::String:: mode >(dst, src); \ + VERIFY_EQUAL_NONCONT(dst, expectedResult); /* Ensure that the strings are identical */ \ + +#define WriteTest(mode, dst, src, expectedResult) \ + mpt::String::Write<mpt::String:: mode >(dst, src); \ + VERIFY_EQUAL_NONCONT(strncmp(dst, expectedResult, CountOf(dst)), 0); /* Ensure that the strings are identical */ \ + for(size_t i = strlen(dst); i < CountOf(dst); i++) \ + VERIFY_EQUAL_NONCONT(dst[i], '\0'); /* Ensure that rest of the buffer is completely nulled */ + + // Check reading of null-terminated string into std::string + ReadTest(nullTerminated, dststring, src0, ""); + ReadTest(nullTerminated, dststring, src1, "X "); + ReadTest(nullTerminated, dststring, src2, "XYZ"); + ReadTest(nullTerminated, dststring, src3, "XYZ"); + + // Check reading of string that should be null-terminated, but is maybe too long to still hold the null character. + ReadTest(maybeNullTerminated, dststring, src0, ""); + ReadTest(maybeNullTerminated, dststring, src1, "X "); + ReadTest(maybeNullTerminated, dststring, src2, "XYZ "); + ReadTest(maybeNullTerminated, dststring, src3, "XYZ!"); + + // Check reading of space-padded strings with ignored last character + ReadTest(spacePaddedNull, dststring, src0, " X"); + ReadTest(spacePaddedNull, dststring, src1, "X"); + ReadTest(spacePaddedNull, dststring, src2, "XYZ"); + ReadTest(spacePaddedNull, dststring, src3, "XYZ"); + + // Check reading of space-padded strings + ReadTest(spacePadded, dststring, src0, " X X"); + ReadTest(spacePadded, dststring, src1, "X X"); + ReadTest(spacePadded, dststring, src2, "XYZ"); + ReadTest(spacePadded, dststring, src3, "XYZ!"); + + /////////////////////////////// + + // Check writing of null-terminated string into larger buffer + WriteTest(nullTerminated, dst1, src0string, ""); + WriteTest(nullTerminated, dst1, src1string, "X "); + WriteTest(nullTerminated, dst1, src2string, "XYZ "); + WriteTest(nullTerminated, dst1, src3string, "XYZ!"); + + // Check writing of string that should be null-terminated, but is maybe too long to still hold the null character. + WriteTest(maybeNullTerminated, dst1, src0string, ""); + WriteTest(maybeNullTerminated, dst1, src1string, "X "); + WriteTest(maybeNullTerminated, dst1, src2string, "XYZ "); + WriteTest(maybeNullTerminated, dst1, src3string, "XYZ!"); + + // Check writing of space-padded strings with last character set to null + WriteTest(spacePaddedNull, dst1, src0string, " "); + WriteTest(spacePaddedNull, dst1, src1string, "X "); + WriteTest(spacePaddedNull, dst1, src2string, "XYZ "); + WriteTest(spacePaddedNull, dst1, src3string, "XYZ! "); + + // Check writing of space-padded strings + WriteTest(spacePadded, dst1, src0string, " "); + WriteTest(spacePadded, dst1, src1string, "X "); + WriteTest(spacePadded, dst1, src2string, "XYZ "); + WriteTest(spacePadded, dst1, src3string, "XYZ! "); + + /////////////////////////////// + + // Check writing of null-terminated string into smaller buffer + WriteTest(nullTerminated, dst2, src0string, ""); + WriteTest(nullTerminated, dst2, src1string, "X "); + WriteTest(nullTerminated, dst2, src2string, "XY"); + WriteTest(nullTerminated, dst2, src3string, "XY"); + + // Check writing of string that should be null-terminated, but is maybe too long to still hold the null character. + WriteTest(maybeNullTerminated, dst2, src0string, ""); + WriteTest(maybeNullTerminated, dst2, src1string, "X "); + WriteTest(maybeNullTerminated, dst2, src2string, "XYZ"); + WriteTest(maybeNullTerminated, dst2, src3string, "XYZ"); + + // Check writing of space-padded strings with last character set to null + WriteTest(spacePaddedNull, dst2, src0string, " "); + WriteTest(spacePaddedNull, dst2, src1string, "X "); + WriteTest(spacePaddedNull, dst2, src2string, "XY"); + WriteTest(spacePaddedNull, dst2, src3string, "XY"); + + // Check writing of space-padded strings + WriteTest(spacePadded, dst2, src0string, " "); + WriteTest(spacePadded, dst2, src1string, "X "); + WriteTest(spacePadded, dst2, src2string, "XYZ"); + WriteTest(spacePadded, dst2, src3string, "XYZ"); + + /////////////////////////////// + +#undef ReadTest +#undef WriteTest + + } + // Test FixNullString() mpt::String::FixNullString(src1); mpt::String::FixNullString(src2); @@ -1507,9 +1631,6 @@ VERIFY_EQUAL_NONCONT(strncmp(src2, "XYZ", CountOf(src2)), 0); VERIFY_EQUAL_NONCONT(strncmp(src3, "XYZ", CountOf(src3)), 0); -#undef ReadTest -#undef WriteTest - } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |