Index: gtest/gtest.xcodeproj/project.pbxproj =================================================================== --- gtest/gtest.xcodeproj/project.pbxproj +++ gtest/gtest.xcodeproj/project.pbxproj @@ -10,12 +10,15 @@ 236ED33319D49076008CA7D7 /* ThreadStateCoordinatorTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadStateCoordinatorTest.cpp; sourceTree = ""; }; 236ED33419D49081008CA7D7 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; 236ED33619D490B0008CA7D7 /* Makefile.rules */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.rules; sourceTree = ""; }; + 338C47F41A1E67B900B46077 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = Utility/Makefile; sourceTree = ""; }; + 338C47F51A1E67B900B46077 /* StringExtractorTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringExtractorTest.cpp; path = Utility/StringExtractorTest.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ 236ED32F19D4901D008CA7D7 /* unittest */ = { isa = PBXGroup; children = ( + 338C47F31A1E677900B46077 /* Utility */, 236ED33019D4903E008CA7D7 /* Plugins */, ); path = unittest; @@ -62,6 +65,15 @@ ); sourceTree = ""; }; + 338C47F31A1E677900B46077 /* Utility */ = { + isa = PBXGroup; + children = ( + 338C47F41A1E67B900B46077 /* Makefile */, + 338C47F51A1E67B900B46077 /* StringExtractorTest.cpp */, + ); + name = Utility; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXLegacyTarget section */ Index: gtest/unittest/Utility/Makefile =================================================================== --- /dev/null +++ gtest/unittest/Utility/Makefile @@ -0,0 +1,17 @@ +THIS_FILE_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))/ + +LEVEL := $(realpath $(THIS_FILE_DIR)../../make) + +CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS +ENABLE_THREADS := YES +CXX_SOURCES := $(wildcard *.cpp) \ + $(realpath $(LEVEL)/../../source/Utility/StringExtractor.cpp) +MAKE_DSYM := NO + +OS := $(shell uname -s) +# $(info OS $(OS)) +ifeq ($(OS),Linux) + LD_EXTRAS := -lncurses -ldl +endif + +include $(LEVEL)/Makefile.rules Index: gtest/unittest/Utility/StringExtractorTest.cpp =================================================================== --- /dev/null +++ gtest/unittest/Utility/StringExtractorTest.cpp @@ -0,0 +1,267 @@ +#include +#include "gtest/gtest.h" + +#include "Utility/StringExtractor.h" + +namespace +{ + class StringExtractorTest: public ::testing::Test + { + }; +} + +TEST_F (StringExtractorTest, InitEmpty) +{ + const char kEmptyString[] = ""; + StringExtractor ex (kEmptyString); + + ASSERT_EQ (true, ex.IsGood()); + ASSERT_EQ (0, ex.GetFilePos()); + ASSERT_STREQ (kEmptyString, ex.GetStringRef().c_str()); + ASSERT_EQ (true, ex.Empty()); + ASSERT_EQ (0, ex.GetBytesLeft()); + ASSERT_EQ (nullptr, ex.Peek()); + + ASSERT_EQ (nullptr, ex.Peek()); +} + +TEST_F (StringExtractorTest, InitMisc) +{ + const char kInitMiscString[] = "Hello, StringExtractor!"; + StringExtractor ex (kInitMiscString); + + ASSERT_EQ (true, ex.IsGood()); + ASSERT_EQ (0, ex.GetFilePos()); + ASSERT_STREQ (kInitMiscString, ex.GetStringRef().c_str()); + ASSERT_EQ (false, ex.Empty()); + ASSERT_EQ (sizeof(kInitMiscString)-1, ex.GetBytesLeft()); + ASSERT_EQ (kInitMiscString[0], *ex.Peek()); +} + +TEST_F (StringExtractorTest, GetHexU8_Underflow) +{ + const char kEmptyString[] = ""; + StringExtractor ex (kEmptyString); + + ASSERT_EQ (0xab, ex.GetHexU8(0xab)); + ASSERT_EQ (false, ex.IsGood()); + ASSERT_EQ (UINT64_MAX, ex.GetFilePos()); + ASSERT_STREQ (kEmptyString, ex.GetStringRef().c_str()); + ASSERT_EQ (true, ex.Empty()); + ASSERT_EQ (0, ex.GetBytesLeft()); + ASSERT_EQ (nullptr, ex.Peek()); +} + +TEST_F (StringExtractorTest, GetHexU8_Underflow2) +{ + const char kOneNibble[] = "1"; + StringExtractor ex (kOneNibble); + + ASSERT_EQ (0xbc, ex.GetHexU8(0xbc)); + ASSERT_EQ (false, ex.IsGood()); + ASSERT_EQ (UINT64_MAX, ex.GetFilePos()); + ASSERT_STREQ (kOneNibble, ex.GetStringRef().c_str()); + ASSERT_EQ (false, ex.Empty()); + ASSERT_EQ (0, ex.GetBytesLeft()); + ASSERT_EQ (nullptr, ex.Peek()); +} + +TEST_F (StringExtractorTest, GetHexU8_InvalidHex) +{ + const char kInvalidHex[] = "xx"; + StringExtractor ex (kInvalidHex); + + ASSERT_EQ (0xcd, ex.GetHexU8(0xcd)); + ASSERT_EQ (false, ex.IsGood()); + ASSERT_EQ (UINT64_MAX, ex.GetFilePos()); + ASSERT_STREQ (kInvalidHex, ex.GetStringRef().c_str()); + ASSERT_EQ (false, ex.Empty()); + ASSERT_EQ (0, ex.GetBytesLeft()); + ASSERT_EQ (nullptr, ex.Peek()); +} + +TEST_F (StringExtractorTest, GetHexU8_Exact) +{ + const char kValidHexPair[] = "12"; + StringExtractor ex (kValidHexPair); + + ASSERT_EQ (0x12, ex.GetHexU8(0x12)); + ASSERT_EQ (true, ex.IsGood()); + ASSERT_EQ (2, ex.GetFilePos()); + ASSERT_STREQ (kValidHexPair, ex.GetStringRef().c_str()); + ASSERT_EQ (false, ex.Empty()); + ASSERT_EQ (0, ex.GetBytesLeft()); + ASSERT_EQ (nullptr, ex.Peek()); +} + +TEST_F (StringExtractorTest, GetHexU8_Extra) +{ + const char kValidHexPair[] = "1234"; + StringExtractor ex (kValidHexPair); + + ASSERT_EQ (0x12, ex.GetHexU8(0x12)); + ASSERT_EQ (true, ex.IsGood()); + ASSERT_EQ (2, ex.GetFilePos()); + ASSERT_STREQ (kValidHexPair, ex.GetStringRef().c_str()); + ASSERT_EQ (false, ex.Empty()); + ASSERT_EQ (2, ex.GetBytesLeft()); + ASSERT_EQ ('3', *ex.Peek()); +} + +TEST_F (StringExtractorTest, GetHexU8_Underflow_NoEof) +{ + const char kEmptyString[] = ""; + StringExtractor ex (kEmptyString); + const bool kSetEofOnFail = false; + + ASSERT_EQ (0xab, ex.GetHexU8(0xab, kSetEofOnFail)); + ASSERT_EQ (false, ex.IsGood()); // this result seems inconsistent with kSetEofOnFail == false + ASSERT_EQ (UINT64_MAX, ex.GetFilePos()); + ASSERT_STREQ (kEmptyString, ex.GetStringRef().c_str()); + ASSERT_EQ (true, ex.Empty()); + ASSERT_EQ (0, ex.GetBytesLeft()); + ASSERT_EQ (nullptr, ex.Peek()); +} + +TEST_F (StringExtractorTest, GetHexU8_Underflow2_NoEof) +{ + const char kOneNibble[] = "1"; + StringExtractor ex (kOneNibble); + const bool kSetEofOnFail = false; + + ASSERT_EQ (0xbc, ex.GetHexU8(0xbc, kSetEofOnFail)); + ASSERT_EQ (true, ex.IsGood()); + ASSERT_EQ (0, ex.GetFilePos()); + ASSERT_STREQ (kOneNibble, ex.GetStringRef().c_str()); + ASSERT_EQ (false, ex.Empty()); + ASSERT_EQ (1, ex.GetBytesLeft()); + ASSERT_EQ ('1', *ex.Peek()); +} + +TEST_F (StringExtractorTest, GetHexU8_InvalidHex_NoEof) +{ + const char kInvalidHex[] = "xx"; + StringExtractor ex (kInvalidHex); + const bool kSetEofOnFail = false; + + ASSERT_EQ (0xcd, ex.GetHexU8(0xcd, kSetEofOnFail)); + ASSERT_EQ (true, ex.IsGood()); + ASSERT_EQ (0, ex.GetFilePos()); + ASSERT_STREQ (kInvalidHex, ex.GetStringRef().c_str()); + ASSERT_EQ (false, ex.Empty()); + ASSERT_EQ (2, ex.GetBytesLeft()); + ASSERT_EQ ('x', *ex.Peek()); +} + +TEST_F (StringExtractorTest, GetHexU8_Exact_NoEof) +{ + const char kValidHexPair[] = "12"; + StringExtractor ex (kValidHexPair); + const bool kSetEofOnFail = false; + + ASSERT_EQ (0x12, ex.GetHexU8(0x12, kSetEofOnFail)); + ASSERT_EQ (true, ex.IsGood()); + ASSERT_EQ (2, ex.GetFilePos()); + ASSERT_STREQ (kValidHexPair, ex.GetStringRef().c_str()); + ASSERT_EQ (false, ex.Empty()); + ASSERT_EQ (0, ex.GetBytesLeft()); + ASSERT_EQ (nullptr, ex.Peek()); +} + +TEST_F (StringExtractorTest, GetHexU8_Extra_NoEof) +{ + const char kValidHexPair[] = "1234"; + StringExtractor ex (kValidHexPair); + const bool kSetEofOnFail = false; + + ASSERT_EQ (0x12, ex.GetHexU8(0x12, kSetEofOnFail)); + ASSERT_EQ (true, ex.IsGood()); + ASSERT_EQ (2, ex.GetFilePos()); + ASSERT_STREQ (kValidHexPair, ex.GetStringRef().c_str()); + ASSERT_EQ (false, ex.Empty()); + ASSERT_EQ (2, ex.GetBytesLeft()); + ASSERT_EQ ('3', *ex.Peek()); +} + +TEST_F (StringExtractorTest, GetHexBytes) +{ + const char kHexEncodedBytes[] = "abcdef0123456789xyzw"; + const size_t kValidHexPairs = 8; + StringExtractor ex(kHexEncodedBytes); + + uint8_t dst[kValidHexPairs]; + ASSERT_EQ(kValidHexPairs, ex.GetHexBytes (dst, kValidHexPairs, 0xde)); + EXPECT_EQ(0xab,dst[0]); + EXPECT_EQ(0xcd,dst[1]); + EXPECT_EQ(0xef,dst[2]); + EXPECT_EQ(0x01,dst[3]); + EXPECT_EQ(0x23,dst[4]); + EXPECT_EQ(0x45,dst[5]); + EXPECT_EQ(0x67,dst[6]); + EXPECT_EQ(0x89,dst[7]); + + ASSERT_EQ(true, ex.IsGood()); + ASSERT_EQ(2*kValidHexPairs, ex.GetFilePos()); + ASSERT_EQ(false, ex.Empty()); + ASSERT_EQ(4, ex.GetBytesLeft()); + ASSERT_EQ('x', *ex.Peek()); +} + +TEST_F (StringExtractorTest, GetHexBytes_Underflow) +{ + const char kHexEncodedBytes[] = "abcdef0123456789xyzw"; + const size_t kValidHexPairs = 8; + StringExtractor ex(kHexEncodedBytes); + + uint8_t dst[12]; + ASSERT_EQ(kValidHexPairs, ex.GetHexBytes (dst, sizeof(dst), 0xde)); + EXPECT_EQ(0xab,dst[0]); + EXPECT_EQ(0xcd,dst[1]); + EXPECT_EQ(0xef,dst[2]); + EXPECT_EQ(0x01,dst[3]); + EXPECT_EQ(0x23,dst[4]); + EXPECT_EQ(0x45,dst[5]); + EXPECT_EQ(0x67,dst[6]); + EXPECT_EQ(0x89,dst[7]); + // these bytes should be filled with fail_fill_value 0xde + EXPECT_EQ(0xde,dst[8]); + EXPECT_EQ(0xde,dst[9]); + EXPECT_EQ(0xde,dst[10]); + EXPECT_EQ(0xde,dst[11]); + + ASSERT_EQ(false, ex.IsGood()); + ASSERT_EQ(UINT64_MAX, ex.GetFilePos()); + ASSERT_EQ(false, ex.Empty()); + ASSERT_EQ(0, ex.GetBytesLeft()); + ASSERT_EQ(0, ex.Peek()); +} + +TEST_F (StringExtractorTest, GetHexBytes_Partial) +{ + const char kHexEncodedBytes[] = "abcdef0123456789xyzw"; + const size_t kReadBytes = 4; + StringExtractor ex(kHexEncodedBytes); + + uint8_t dst[12]; + memset(dst, 0xab, sizeof(dst)); + ASSERT_EQ(kReadBytes, ex.GetHexBytes (dst, kReadBytes, 0xde)); + EXPECT_EQ(0xab,dst[0]); + EXPECT_EQ(0xcd,dst[1]); + EXPECT_EQ(0xef,dst[2]); + EXPECT_EQ(0x01,dst[3]); + // these bytes should be unchanged + EXPECT_EQ(0xab,dst[4]); + EXPECT_EQ(0xab,dst[5]); + EXPECT_EQ(0xab,dst[6]); + EXPECT_EQ(0xab,dst[7]); + EXPECT_EQ(0xab,dst[8]); + EXPECT_EQ(0xab,dst[9]); + EXPECT_EQ(0xab,dst[10]); + EXPECT_EQ(0xab,dst[11]); + + ASSERT_EQ(true, ex.IsGood()); + ASSERT_EQ(kReadBytes*2, ex.GetFilePos()); + ASSERT_EQ(false, ex.Empty()); + ASSERT_EQ(12, ex.GetBytesLeft()); + ASSERT_EQ('2', *ex.Peek()); +}