Skip to content

Commit d975ed5

Browse files
Add USimpleString::toLong() (#84)
* Add USimpleString::toLong() * Add USimpleString::toLong() tests * Update test/USimpleStringTest.cpp Co-authored-by: Copilot <[email protected]> * Update test/USimpleStringTest.cpp Co-authored-by: Copilot <[email protected]> * Update test/USimpleStringTest.cpp Co-authored-by: Copilot <[email protected]> * Fix after review --------- Co-authored-by: Copilot <[email protected]>
1 parent 4b12381 commit d975ed5

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed

include/kf/USimpleString.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ namespace kf
106106

107107
bool matches(_In_ const USimpleString& expression) const;
108108
bool matchesIgnoreCase(_In_ const USimpleString& expression) const;
109+
LONG toLong(_In_ ULONG base) const;
109110

110111
NTSTATUS concat(_In_ const USimpleString& str)
111112
{
@@ -591,4 +592,12 @@ namespace kf
591592
{
592593
return strLeft.compareToIgnoreCase(strRight) < 0;
593594
}
595+
596+
inline LONG USimpleString::toLong(_In_ ULONG base) const
597+
{
598+
ULONG value = 0;
599+
::RtlUnicodeStringToInteger(&m_str, base, reinterpret_cast<PULONG>(&value));
600+
601+
return value;
602+
}
594603
}

test/USimpleStringTest.cpp

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,4 +842,159 @@ SCENARIO("USimpleString: all methods")
842842
}
843843
}
844844
}
845+
}
846+
847+
SCENARIO("USimpleString: toLong")
848+
{
849+
GIVEN("Empty string")
850+
{
851+
kf::USimpleString empty;
852+
853+
WHEN("toLong() is called with base 10")
854+
{
855+
THEN("it returns 0")
856+
{
857+
REQUIRE(empty.toLong(10) == 0);
858+
}
859+
}
860+
861+
WHEN("toLong() is called with base 0 (auto-detect)")
862+
{
863+
THEN("it returns 0")
864+
{
865+
REQUIRE(empty.toLong(0) == 0);
866+
}
867+
}
868+
}
869+
870+
GIVEN("Auto-detected base (base 0)")
871+
{
872+
THEN("parses hex with 0x prefix")
873+
{
874+
kf::USimpleString s(L"0xFF");
875+
REQUIRE(s.toLong(0) == 255);
876+
}
877+
878+
THEN("parses octal with 0o prefix")
879+
{
880+
kf::USimpleString s(L"0o77");
881+
REQUIRE(s.toLong(0) == 63);
882+
}
883+
884+
THEN("parses binary with 0b prefix")
885+
{
886+
kf::USimpleString s(L"0b1011");
887+
REQUIRE(s.toLong(0) == 11);
888+
}
889+
890+
THEN("parses decimal with no prefix")
891+
{
892+
kf::USimpleString s(L"123");
893+
REQUIRE(s.toLong(0) == 123);
894+
}
895+
}
896+
897+
GIVEN("Explicit base")
898+
{
899+
THEN("parses binary when base is 2")
900+
{
901+
kf::USimpleString s(L"1010");
902+
REQUIRE(s.toLong(2) == 10);
903+
}
904+
905+
THEN("parses octal when base is 8")
906+
{
907+
kf::USimpleString s(L"77");
908+
REQUIRE(s.toLong(8) == 63);
909+
}
910+
911+
THEN("parses decimal when base is 10")
912+
{
913+
kf::USimpleString s(L"42");
914+
REQUIRE(s.toLong(10) == 42);
915+
}
916+
917+
THEN("parses hex when base is 16")
918+
{
919+
kf::USimpleString s(L"FF");
920+
REQUIRE(s.toLong(16) == 255);
921+
}
922+
}
923+
924+
GIVEN("Signs and whitespace")
925+
{
926+
THEN("skips leading whitespace")
927+
{
928+
kf::USimpleString s(L" 17");
929+
REQUIRE(s.toLong(10) == 17);
930+
}
931+
932+
THEN("parses plus sign")
933+
{
934+
kf::USimpleString s(L"+7");
935+
REQUIRE(s.toLong(10) == 7);
936+
}
937+
938+
THEN("parses minus sign and returns negative value")
939+
{
940+
kf::USimpleString s(L"-42");
941+
REQUIRE(s.toLong(10) == -42);
942+
}
943+
}
944+
945+
GIVEN("Invalid or partial input")
946+
{
947+
THEN("non-numeric returns 0")
948+
{
949+
kf::USimpleString s(L"abc");
950+
REQUIRE(s.toLong(10) == 0);
951+
}
952+
953+
THEN("only sign returns 0")
954+
{
955+
kf::USimpleString s1(L"+");
956+
kf::USimpleString s2(L"-");
957+
REQUIRE(s1.toLong(10) == 0);
958+
REQUIRE(s2.toLong(10) == 0);
959+
}
960+
961+
THEN("parses numeric prefix before trailing junk")
962+
{
963+
kf::USimpleString s(L"123abc");
964+
REQUIRE(s.toLong(10) == 123);
965+
}
966+
}
967+
968+
GIVEN("Overflow boundaries")
969+
{
970+
THEN("LONG_MAX parses correctly")
971+
{
972+
kf::USimpleString s(L"2147483647");
973+
REQUIRE(s.toLong(10) == LONG_MAX);
974+
}
975+
976+
THEN("LONG_MIN parses correctly")
977+
{
978+
kf::USimpleString s(L"-2147483648");
979+
REQUIRE(s.toLong(10) == LONG_MIN);
980+
}
981+
982+
THEN("positive overflow LONG_MAX + 1 returns LONG_MIN")
983+
{
984+
kf::USimpleString s(L"2147483648");
985+
REQUIRE(s.toLong(10) == LONG_MIN);
986+
}
987+
988+
THEN("negative overflow LONG_MIN - 1 returns LONG_MAX")
989+
{
990+
kf::USimpleString s(L"-2147483649");
991+
REQUIRE(s.toLong(10) == LONG_MAX);
992+
}
993+
994+
THEN("hex overflow 0x80000000 returns 0x80000000")
995+
{
996+
kf::USimpleString s(L"0x80000000"); // 2^31, which is LONG_MIN but unsigned
997+
REQUIRE(s.toLong(0) == 0x80000000);
998+
}
999+
}
8451000
}

0 commit comments

Comments
 (0)