diff --git a/lib/src/bofuart.cpp b/lib/src/bofuart.cpp index e160d48..d08058a 100644 --- a/lib/src/bofuart.cpp +++ b/lib/src/bofuart.cpp @@ -711,7 +711,7 @@ BOFERR BofUart::V_GetStatus(BOF_COM_CHANNEL_STATUS &_rStatus_X) NbOut_U32 = 0; } _rStatus_X.NbIn_U32 = NbIn_U32; - Nb_U32 = mpTxData_O ? mpTxData_O->GetNbElement() : 0; + Nb_U32 = mpTxData_O ? mpTxData_O->GetNbElement(nullptr) : 0; _rStatus_X.NbOut_U32 = (Nb_U32 > NbOut_U32) ? Nb_U32 : NbOut_U32; Rts_E = BOF_ERR_NO_ERROR; diff --git a/lib/src/main.cpp b/lib/src/main.cpp new file mode 100755 index 0000000..9027217 --- /dev/null +++ b/lib/src/main.cpp @@ -0,0 +1,260 @@ +#include +#include + +#include "../include/gtestrunner.h" + +#include "fmt/format.h" +#include +#if defined(_WIN32) +// #define _CRTDBG_MAP_ALLOC +// #include +// #include +#if defined(NDEBUG) // We are in Release compil +#else +#if defined(_WIN32) +#include +#endif +#endif + +#else +#include +#endif + +#if 0 +//#include "asio.hpp" +#include +//Bof_GetNetworkInterfaceInfo +void f() +{ + BOFSTDPARAM StdParam_X; + BOF::Bof_Initialize(StdParam_X); + std::vector NetworkInterfaceCollection; + BOFERR e = BOF::Bof_GetListOfNetworkInterface(NetworkInterfaceCollection); + printf("Bof_GetListOfNetworkInterface found %zd Network board (%s)\n", NetworkInterfaceCollection.size(), BOF::Bof_ErrorCode(e)); + for (auto &rIt : NetworkInterfaceCollection) + { + printf("name %s ip %s msk %s brd %s %s\n", rIt.Name_S.c_str(), rIt.IpAddress_S.c_str(), rIt.IpMask_S.c_str(), rIt.IpBroadcast_S.c_str(), rIt.IpV6_B ? "IpV6":"IpV4"); + printf("Info: flg %X Gw %s Mtu %d Mac %02X:%02X:%02X:%02X:%02X:%02X\n", rIt.Info_X.InterfaceFlag_E, rIt.Info_X.IpGateway_S.c_str(), rIt.Info_X.MtuSize_U32, + rIt.Info_X.MacAddress[0], rIt.Info_X.MacAddress[1], rIt.Info_X.MacAddress[2], rIt.Info_X.MacAddress[3], rIt.Info_X.MacAddress[4], rIt.Info_X.MacAddress[5]); + } +/* + asio::io_context io; + asio::ip::tcp::resolver resolver(io); + asio::ip::tcp::resolver::query query(asio::ip::host_name(), ""); + asio::ip::tcp::resolver::iterator it = resolver.resolve(query); + while (it != asio::ip::tcp::resolver::iterator()) + { + asio::ip::address addr = (it++)->endpoint().address(); + if (addr.is_v6()) + { + std::cout << "ipv6 address: "; + } + else + std::cout << "ipv4 address: "; + + std::cout << addr.to_string() << std::endl; + + } + */ +} +#endif + +USE_BOF_NAMESPACE() + +BOFERR AppBofAssertCallback(const std::string &_rFile_S, uint32_t _Line_U32, const std::string &_rMasg_S) +{ + printf("Assert in %s line %d Msg %s\n", _rFile_S.c_str(), _Line_U32, _rMasg_S.c_str()); + return BOF_ERR_NO_ERROR; +} + +int main(int argc, char *argv[]) +{ +#if 0 + char *p = new char[5]; + return 0; +#else + int Rts_i; + BOFERR Sts_E; + BOFSTDPARAM StdParam_X; + std::string HelpString_S, Cwd_S; + + StdParam_X.AssertInRelease_B = true; + StdParam_X.AssertCallback = AppBofAssertCallback; + Sts_E = Bof_Initialize(StdParam_X); + BOF_ASSERT(Sts_E == BOF_ERR_NO_ERROR); + Bof_GetCurrentDirectory(Cwd_S); + printf("\nPwd %s\nRunning BofStd V %s on %s under %s\n", Cwd_S.c_str(), StdParam_X.Version_S.c_str(), StdParam_X.ComputerName_S.c_str(), StdParam_X.OsName_S.c_str()); + // for (int i = 0; i < 7; i++) + //{ + // printf("hello world %d\n", i); + // } + // const char *pp = StdParam_X.ComputerName_S.c_str(); + +#if defined(_WIN32) +#else + // Ok on tge2, there is an uart ::testing::GTEST_FLAG(filter) = "-Uart_Test.*"; // No hw +#endif + testing::InitGoogleTest(&argc, argv); + // Dont touch + //::testing::GTEST_FLAG(filter) = "Api_Test.*"; + //::testing::GTEST_FLAG(filter) = "Async_Test.*"; + //::testing::GTEST_FLAG(filter) = "AsyncMuticastDelegate_Test.*"; + //::testing::GTEST_FLAG(filter) = "BinSerializer_Test.*"; + //::testing::GTEST_FLAG(filter) = "Bit_Test.*"; + //::testing::GTEST_FLAG(filter) = "ConIo_Test.*"; + //::testing::GTEST_FLAG(filter) = "CallbackCollection_Test.*"; + //::testing::GTEST_FLAG(filter) = "CircularBuffer_Test.*"; + //::testing::GTEST_FLAG(filter) = "CmdLineParser_Test.*"; + //::testing::GTEST_FLAG(filter) = "Crypto_Test.*"; + //::testing::GTEST_FLAG(filter) = "DateTime_Test.*"; + //::testing::GTEST_FLAG(filter) = "Enum_Test.*"; + //::testing::GTEST_FLAG(filter) = "Fs_Test.*"; + //::testing::GTEST_FLAG(filter) = "Guid_Test.*"; + //::testing::GTEST_FLAG(filter) = "JsonParser_Test.*"; + //::testing::GTEST_FLAG(filter) = "JsonWriter_Test.*"; + //::testing::GTEST_FLAG(filter) = "Logger_Test.*"; + //::testing::GTEST_FLAG(filter) = "NaryTreeKv_Test.*"; + //::testing::GTEST_FLAG(filter) = "Path_Test.*"; + //::testing::GTEST_FLAG(filter) = "Pipe_Test.*"; + //::testing::GTEST_FLAG(filter) = "Pot_Test.*"; + //::testing::GTEST_FLAG(filter) = "Process_Test.*"; + //::testing::GTEST_FLAG(filter) = "Queue_Test.*"; + //::testing::GTEST_FLAG(filter) = "RamDb_Test.*"; + //::testing::GTEST_FLAG(filter) = "RawCircularBuffer_Test.*"; + //::testing::GTEST_FLAG(filter) = "RawCircularBufferInSlotMode_Test.*"; + //::testing::GTEST_FLAG(filter) = "Shell_Test.*"; + //::testing::GTEST_FLAG(filter) = "SocketOs_Test.*"; + //::testing::GTEST_FLAG(filter) = "SocketTcp_Test.*"; + //::testing::GTEST_FLAG(filter) = "SocketUdp_Test.*"; + //::testing::GTEST_FLAG(filter) = "SockIo_Client_Server_Test.*"; + //::testing::GTEST_FLAG(filter) = "SockIo_Test.*"; + //::testing::GTEST_FLAG(filter) = "String_Test.*"; + //::testing::GTEST_FLAG(filter) = "StringCircularBuffer_Test.*"; + ////::testing::GTEST_FLAG(filter) = "stringformatter a fixer.*"; + //::testing::GTEST_FLAG(filter) = "System_Test.*"; + //::testing::GTEST_FLAG(filter) = "Threading_Test.*"; + //::testing::GTEST_FLAG(filter) = "BofThreadPool_Test.*"; + //::testing::GTEST_FLAG(filter) = "Timecode_Test.*"; + //::testing::GTEST_FLAG(filter) = "Uart_Test.*"; + //::testing::GTEST_FLAG(filter) = "Uri_Test.*"; + //::testing::GTEST_FLAG(filter) = "XmlParser_Test.*"; + + // Use these one + //::testing::GTEST_FLAG(filter) = "SockIo_Test.*"; + //::testing::GTEST_FLAG(filter) = "JsonParser_Test.*"; + //::testing::GTEST_FLAG(filter) = "JsonParser_Test.*:XmlWriter_Test.*"; + //::testing::GTEST_FLAG(filter) = "CmdLineParser_Test.*:U7ri_Test.*"; + //::testing::GTEST_FLAG(filter) = "Threading_Test.MultiThreadWithoutMutex"; + //::testing::GTEST_FLAG(filter) = "System_Test.Rational"; + //::testing::GTEST_FLAG(filter) = "RawCircularBuffer_Test.FillWrapOverwrite"; + //::testing::GTEST_FLAG(filter) = "RawCircularBuffer_Test.*:CircularBuffer_Test.*:RawCircularBufferInSlotMode_Test.*"; + //::testing::GTEST_FLAG(filter) = "RawCircularBufferNoSlotsize_Test.LoopByteBuffer"; + //::testing::GTEST_FLAG(filter) = "RawCircularBuffer_Test.*:RawCircularBufferInSlotMode_Test.*"; + // std::string CrtDir_S; + // BOF::Bof_GetCurrentDirectory(CrtDir_S); + // printf("-CrtDir_S->%s\n", CrtDir_S.c_str()); + Rts_i = RUN_ALL_TESTS(); + + Sts_E = Bof_Shutdown(); + BOF_ASSERT(Sts_E == BOF_ERR_NO_ERROR); + +#if defined(NDEBUG) // We are in Release compil +#else + std::string Buffer_S; + std::cout << "\nPress any key followed by enter to to quit ..." << std::endl; + std::getline(std::cin, Buffer_S); +#endif + + return Rts_i; +#endif +} + +/* +* WINDOWS +[==========] 189 tests from 48 test suites ran. (108823 ms total) +[ PASSED ] 189 tests. + + YOU HAVE 3 DISABLED TESTS + + LINUX: +[==========] 189 tests from 48 test suites ran. (60706 ms total) +[ PASSED ] 189 tests. + + YOU HAVE 3 DISABLED TESTS + + +need to launch test with +su +root@ad6c87cec684:/home/bha/bld/bofstd/tests# setcap CAP_SYS_NICE+ep ./bofstd-tests +exit +./bofstd-tests + +to be able to use the FIFO scheduler in my docker container + +On Tge2: +[==========] 174 tests from 46 test suites ran. (45466 ms total) +[ PASSED ] 174 tests. + + YOU HAVE 7 DISABLED TESTS +*/ +/* +root@evstge2:/root# ifconfig +eth-1gb0 Link encap:Ethernet HWaddr 00:1C:F3:0A:20:44 + inet addr:10.129.171.112 Bcast:10.129.171.255 Mask:255.255.255.0 + inet6 addr: fe80::21c:f3ff:fe0a:2044/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:9000 Metric:1 + RX packets:10 errors:0 dropped:1 overruns:0 frame:0 + TX packets:32 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:10000 + RX bytes:1336 (1.3 KiB) TX bytes:5334 (5.2 KiB) + Memory:1ae4000-1ae4fff + +eth-1gb1 Link encap:Ethernet HWaddr 00:1C:F3:0A:20:45 + inet addr:10.129.172.21 Bcast:10.129.172.255 Mask:255.255.255.0 + inet6 addr: fe80::21c:f3ff:fe0a:2045/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:9000 Metric:1 + RX packets:0 errors:0 dropped:0 overruns:0 frame:0 + TX packets:29 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:10000 + RX bytes:0 (0.0 B) TX bytes:5207 (5.0 KiB) + Memory:1ae6000-1ae6fff + +lo Link encap:Local Loopback + inet addr:127.0.0.1 Mask:255.0.0.0 + inet6 addr: ::1/128 Scope:Host + UP LOOPBACK RUNNING MTU:65536 Metric:1 + RX packets:360 errors:0 dropped:0 overruns:0 frame:0 + TX packets:360 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:28323 (27.6 KiB) TX bytes:28323 (27.6 KiB) + +root@evstge2:/root# ^C +root@evstge2:/root# ^C +root@evstge2:/root# ip a +1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 scope host lo + valid_lft forever preferred_lft forever + inet6 ::1/128 scope host + valid_lft forever preferred_lft forever +2: sit0@NONE: mtu 1480 qdisc noop state DOWN group default qlen 1000 + link/sit 0.0.0.0 brd 0.0.0.0 +3: eth-1gb0: mtu 9000 qdisc prio state UP group default qlen 10000 + link/ether 00:1c:f3:0a:20:44 brd ff:ff:ff:ff:ff:ff + inet 10.129.171.112/24 brd 10.129.171.255 scope global eth-1gb0 + valid_lft forever preferred_lft forever + inet6 fe80::21c:f3ff:fe0a:2044/64 scope link + valid_lft forever preferred_lft forever +4: eth-1gb1: mtu 9000 qdisc prio state UP group default qlen 10000 + link/ether 00:1c:f3:0a:20:45 brd ff:ff:ff:ff:ff:ff + inet 10.129.172.21/24 brd 10.129.172.255 scope global eth-1gb1 + valid_lft forever preferred_lft forever + inet6 fe80::21c:f3ff:fe0a:2045/64 scope link + valid_lft forever preferred_lft forever +5: eth-10gb0: mtu 9000 qdisc noop state DOWN group default qlen 1000 + link/ether 00:1c:f3:0a:20:46 brd ff:ff:ff:ff:ff:ff +6: eth-10gb1: mtu 9000 qdisc noop state DOWN group default qlen 1000 + link/ether 00:1c:f3:0a:20:47 brd ff:ff:ff:ff:ff:ff +root@evstge2:/root# + +*/ \ No newline at end of file diff --git a/lib/src/ut_async.cpp b/lib/src/ut_async.cpp new file mode 100755 index 0000000..ddf5a32 --- /dev/null +++ b/lib/src/ut_async.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013-2023, OnBings All rights reserved. + * + * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR + * PURPOSE. + * + * This module implements the unit testing of the bofasync class + * + * Name: ut_enum.cpp + * Author: Bernard HARMEL: onbings@dscloud.me + * Web: onbings.dscloud.me + * Revision: 1.0 + * + * Rem: Nothing + * + * History: + * + * V 1.00 Dec 26 2013 BHA : Initial release + */ + +/*** Include files ***********************************************************/ + +#include "gtestrunner.h" +#include + +/*** Class *************************************************************************************************************************/ + +USE_BOF_NAMESPACE() + +static uint32_t S_pCpt_U32[3]; +void a() +{ + // printf("A\n"); + Bof_MsSleep(10); + S_pCpt_U32[0]++; +} +void b() +{ + // printf("B\n"); + Bof_MsSleep(50); + S_pCpt_U32[1]++; +} +void c() +{ + // printf("C\n"); + Bof_MsSleep(100); + S_pCpt_U32[2]++; +} +TEST(Async_Test, CommandQueue) +{ + BOF_COMMAND_QUEUE_PARAM CommandQueueParam_X; + BOF_COMMAND_QUEUE_ENTRY pCommand_X[3]; + uint32_t i_U32, Start_U32, DeltaInMs_U32; + + CommandQueueParam_X.PollTimeoutInMs_U32 = 200; + CommandQueueParam_X.MaxPendingRequest_U32 = 4 * 3; + CommandQueueParam_X.ThreadCpuCoreAffinityMask_U64 = 0; + CommandQueueParam_X.ThreadSchedulerPolicy_E = BOF_THREAD_SCHEDULER_POLICY_OTHER; + CommandQueueParam_X.ThreadPriority_E = BOF_THREAD_PRIORITY_000; + BofCommandQueue CmdQ(CommandQueueParam_X); + + memset(S_pCpt_U32, 0, sizeof(S_pCpt_U32)); + pCommand_X[0].Name_S = "CmdA"; + pCommand_X[0].Cmd = a; + pCommand_X[1].Name_S = "CmdB"; + pCommand_X[1].Cmd = b; + pCommand_X[2].Name_S = "CmdC"; + pCommand_X[2].Cmd = c; + Start_U32 = Bof_GetMsTickCount(); + for (i_U32 = 0; i_U32 < 4; i_U32++) + { + EXPECT_EQ(CmdQ.PostCommand(false, pCommand_X[2]), BOF_ERR_NO_ERROR); + EXPECT_EQ(CmdQ.PostCommand(false, pCommand_X[1]), BOF_ERR_NO_ERROR); + EXPECT_EQ(CmdQ.PostCommand(false, pCommand_X[0]), BOF_ERR_NO_ERROR); + } + // full + // EXPECT_NE(CmdQ.PostCommand(false, pCommand_X[0]), BOF_ERR_NO_ERROR); + + DeltaInMs_U32 = Bof_ElapsedMsTime(Start_U32); + EXPECT_LT(DeltaInMs_U32, 10); + while (CmdQ.IsProcessingCommand()) + { + Bof_MsSleep(10); + } + DeltaInMs_U32 = Bof_ElapsedMsTime(Start_U32); + printf("DeltaCmd=%d ms\n", DeltaInMs_U32); + // EXPECT_GT(DeltaInMs_U32, 1610); + // EXPECT_LT(DeltaInMs_U32, 1650); + EXPECT_EQ(S_pCpt_U32[0], 4); + EXPECT_EQ(S_pCpt_U32[1], 4); + EXPECT_EQ(S_pCpt_U32[2], 4); +} + +TEST(Async_Test, OverloadCommandQueue) +{ + BOF_COMMAND_QUEUE_PARAM CommandQueueParam_X; + BOF_COMMAND_QUEUE_ENTRY Command_X; + uint32_t i_U32, Start_U32, DeltaInMs_U32; + + CommandQueueParam_X.PollTimeoutInMs_U32 = 200; + CommandQueueParam_X.MaxPendingRequest_U32 = 3; + CommandQueueParam_X.ThreadCpuCoreAffinityMask_U64 = 0; + CommandQueueParam_X.ThreadSchedulerPolicy_E = BOF_THREAD_SCHEDULER_POLICY_OTHER; + CommandQueueParam_X.ThreadPriority_E = BOF_THREAD_PRIORITY_000; + BofCommandQueue CmdQ(CommandQueueParam_X); + + memset(S_pCpt_U32, 0, sizeof(S_pCpt_U32)); + Command_X.Name_S = "Cmd"; + Command_X.Cmd = a; + Start_U32 = Bof_GetMsTickCount(); + for (i_U32 = 0; i_U32 < 100; i_U32++) + { + CmdQ.PostCommand(false, Command_X); + } + // should be full + EXPECT_NE(CmdQ.PostCommand(false, Command_X), BOF_ERR_NO_ERROR); + while (CmdQ.IsProcessingCommand()) + { + Bof_MsSleep(10); + } + EXPECT_EQ(CmdQ.PostCommand(false, Command_X), BOF_ERR_NO_ERROR); + EXPECT_EQ(S_pCpt_U32[0], 4); + while (CmdQ.IsProcessingCommand()) + { + Bof_MsSleep(10); + } +} diff --git a/lib/src/ut_fs.cpp b/lib/src/ut_fs.cpp new file mode 100755 index 0000000..40d9bcd --- /dev/null +++ b/lib/src/ut_fs.cpp @@ -0,0 +1,695 @@ +/* + * Copyright (c) 2013-2033, OnBings All rights reserved. + * + * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR + * PURPOSE. + * + * This module implements the unit testing of the boffs class + * + * Name: ut_fs.cpp + * Author: Bernard HARMEL: onbings@dscloud.me + * Web: onbings.dscloud.me + * Revision: 1.0 + * + * Rem: Nothing + * + * History: + * + * V 1.00 Dec 26 2013 BHA : Initial release + */ +#include "bofstd/bofstring.h" +#include + +#include "gtestrunner.h" + +USE_BOF_NAMESPACE() + +TEST(Fs_Test, DirectoryManagement) +{ + BOFERR Sts_E; + std::string CrtDir_S, NewDir_S; + BOF_FILE_PERMISSION Permission_E; + BofPath CrtDir, NewPath, FileAsDirPath; + uintptr_t Io, Io2; + std::string NewFull_S; + BOF_FILE_TYPE FileType_E; + uint64_t Size_U64; + +#if defined(_WIN32) +#else + std::string Cwd_S; + BOF::Bof_GetCurrentDirectory(Cwd_S); + EXPECT_EQ(Bof_SetCurrentDirectory("/tmp/"), BOF_ERR_NO_ERROR); +#endif + Sts_E = Bof_GetCurrentDirectory(CrtDir); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + FileAsDirPath = CrtDir.FullPathName(false) + "babar1"; + Permission_E = BOF_FILE_PERMISSION_READ_FOR_ALL | BOF_FILE_PERMISSION_WRITE_FOR_ALL; + Size_U64 = Bof_GetFileSize(FileAsDirPath); + Sts_E = Bof_DeleteFile(FileAsDirPath); + EXPECT_TRUE((Size_U64 == 0xFFFFFFFFFFFFFFFF) || (Size_U64 == 0x7FFFFFFFFFFFFFFF)); // Linux 0x7FFFFFFFFFFFFFFF Win 0xFFFFFFFFFFFFFFFF ??? + + Sts_E = Bof_CleanupDirectory(true, BofPath(FileAsDirPath.FullPathName(false) + "/"), true); + Sts_E = Bof_CleanupDirectory(true, BofPath(FileAsDirPath.FullPathName(false) + "/../babar2/"), true); + + FileType_E = Bof_GetFileType(CrtDir); + EXPECT_EQ(FileType_E, BOF_FILE_TYPE::BOF_FILE_DIR); + + NewFull_S = CrtDir.FullPathName(false) + "babar1/"; + + NewPath = CrtDir; + Sts_E = NewPath.Combine("/babar1/"); // Remove double // + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + NewPath = CrtDir; + Sts_E = NewPath.Combine("babar1/"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + EXPECT_EQ(NewPath.IsValid(), true); + EXPECT_EQ(NewPath.IsExist(), false); + EXPECT_EQ(NewPath.IsDirectory(), true); + EXPECT_EQ(NewPath.IsFile(), false); + EXPECT_STREQ(NewPath.FullPathName(false).c_str(), NewFull_S.c_str()); + EXPECT_STREQ(NewPath.DirectoryName(true, false).c_str(), NewFull_S.c_str()); + EXPECT_STREQ(NewPath.Extension().c_str(), ""); + EXPECT_STREQ(NewPath.FileNameWithExtension().c_str(), ""); + EXPECT_STREQ(NewPath.FileNameWithoutExtension().c_str(), ""); + + Sts_E = Bof_CreateFile(Permission_E, FileAsDirPath, false, Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileAsDirPath.IsValid(), true); + EXPECT_TRUE(FileAsDirPath.IsExist()); + EXPECT_TRUE(FileAsDirPath.IsFile()); + EXPECT_FALSE(FileAsDirPath.IsDirectory()); + + Sts_E = Bof_CloseFile(Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(Io, -1); + + FileType_E = Bof_GetFileType("FileAsDirPath123456789"); + EXPECT_EQ(FileType_E, BOF_FILE_TYPE::BOF_FILE_DONT_EXIST); + FileType_E = Bof_GetFileType(FileAsDirPath); + EXPECT_EQ(FileType_E, BOF_FILE_TYPE::BOF_FILE_REG); + FileType_E = Bof_GetFileType(CrtDir); + EXPECT_EQ(FileType_E, BOF_FILE_TYPE::BOF_FILE_DIR); + + Sts_E = Bof_CreateFile(Permission_E, FileAsDirPath, true, Io2); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileAsDirPath.IsValid(), true); + EXPECT_TRUE(FileAsDirPath.IsExist()); + EXPECT_TRUE(FileAsDirPath.IsFile()); + EXPECT_FALSE(FileAsDirPath.IsDirectory()); + + Sts_E = Bof_CloseFile(Io2); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(Io2, -1); + + Sts_E = Bof_CreateFile(Permission_E, FileAsDirPath, true, Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileAsDirPath.IsValid(), true); + EXPECT_TRUE(FileAsDirPath.IsExist()); + EXPECT_TRUE(FileAsDirPath.IsFile()); + EXPECT_FALSE(FileAsDirPath.IsDirectory()); + + Sts_E = Bof_CreateFile(Permission_E, FileAsDirPath, true, Io2); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileAsDirPath.IsValid(), true); + EXPECT_TRUE(FileAsDirPath.IsExist()); + EXPECT_TRUE(FileAsDirPath.IsFile()); + EXPECT_FALSE(FileAsDirPath.IsDirectory()); + + Sts_E = Bof_CloseFile(Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(Io, -1); + + Sts_E = Bof_CloseFile(Io2); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(Io2, -1); + + Sts_E = Bof_CreateDirectory(Permission_E, NewPath); + EXPECT_NE(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_DeleteFile(FileAsDirPath); // To be sure + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CreateDirectory(Permission_E, NewPath); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CreateDirectory(Permission_E, NewPath); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_GetFsPermission(NewPath, Permission_E); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + EXPECT_TRUE((Permission_E & BOF_FILE_PERMISSION_READ_FOR_ALL) == BOF_FILE_PERMISSION_READ_FOR_ALL); + EXPECT_TRUE((Permission_E & BOF_FILE_PERMISSION_WRITE_FOR_ALL) == BOF_FILE_PERMISSION_WRITE_FOR_ALL); +#if defined(_WIN32) + EXPECT_TRUE((Permission_E & BOF_FILE_PERMISSION_EXEC_FOR_ALL) == BOF_FILE_PERMISSION_EXEC_FOR_ALL); +#else + EXPECT_FALSE((Permission_E & BOF_FILE_PERMISSION_EXEC_FOR_ALL) == BOF_FILE_PERMISSION_EXEC_FOR_ALL); +#endif + NewPath = CrtDir; + Sts_E = NewPath.Combine("babar2/babar3/../babar4/../babar5/"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CreateDirectory(Permission_E, NewPath); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + NewPath = CrtDir; + Sts_E = NewPath.Combine("babar1"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CleanupDirectory(true, NewPath, true); + EXPECT_NE(Sts_E, BOF_ERR_NO_ERROR); + + NewPath = CrtDir; + Sts_E = NewPath.Combine("babar1/"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CleanupDirectory(true, NewPath, true); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + NewPath = CrtDir; + Sts_E = NewPath.Combine("babar2/babar5/"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CleanupDirectory(true, NewPath, false); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CleanupDirectory(true, NewPath, true); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + NewPath = CrtDir; + Sts_E = NewPath.Combine("babar2/"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CleanupDirectory(true, NewPath, true); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); +#if defined(_WIN32) +#else + EXPECT_EQ(BOF::Bof_SetCurrentDirectory(Cwd_S), BOF_ERR_NO_ERROR); +#endif +} + +TEST(Fs_Test, FileManagement) +{ + BOFERR Sts_E; + std::string CrtDir_S, NewDir_S; + BOF_FILE_PERMISSION Permission_E; + BofPath CrtDir, NewPath, FileAsDirPath; + uintptr_t Io, Io2; + std::string NewFull_S; + uint64_t Size_U64; + BOF_FILE_TYPE FileType_E; + +#if defined(_WIN32) +#else + std::string Cwd_S; + BOF::Bof_GetCurrentDirectory(Cwd_S); + EXPECT_EQ(Bof_SetCurrentDirectory("/tmp/"), BOF_ERR_NO_ERROR); +#endif + Sts_E = Bof_GetCurrentDirectory(CrtDir); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_STRNE(CrtDir.FullPathName(false).c_str(), ""); + EXPECT_TRUE(CrtDir.FullPathName(false).back() == '/'); + + FileAsDirPath = CrtDir.FullPathName(false) + "babar1"; + Permission_E = BOF_FILE_PERMISSION_READ_FOR_ALL | BOF_FILE_PERMISSION_WRITE_FOR_ALL; + // To be sure + Sts_E = Bof_DeleteFile(FileAsDirPath); + Sts_E = Bof_CleanupDirectory(true, BofPath(FileAsDirPath.FullPathName(false) + "/"), true); + Sts_E = Bof_CleanupDirectory(true, BofPath(FileAsDirPath.FullPathName(false) + "/../babar2/"), true); + + FileType_E = Bof_GetFileType(CrtDir); + EXPECT_EQ(FileType_E, BOF_FILE_TYPE::BOF_FILE_DIR); + + NewFull_S = CrtDir.FullPathName(false) + "babar1/"; + + NewPath = CrtDir; + Sts_E = NewPath.Combine("babar1/"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(NewPath.IsValid(), true); + EXPECT_EQ(NewPath.IsExist(), false); + EXPECT_EQ(NewPath.IsDirectory(), true); + EXPECT_EQ(NewPath.IsFile(), false); + EXPECT_STREQ(NewPath.FullPathName(false).c_str(), NewFull_S.c_str()); + EXPECT_STREQ(NewPath.DirectoryName(true, false).c_str(), NewFull_S.c_str()); + EXPECT_STREQ(NewPath.Extension().c_str(), ""); + EXPECT_STREQ(NewPath.FileNameWithExtension().c_str(), ""); + EXPECT_STREQ(NewPath.FileNameWithoutExtension().c_str(), ""); + + Sts_E = Bof_CreateFile(Permission_E, FileAsDirPath, false, Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileAsDirPath.IsValid(), true); + EXPECT_TRUE(FileAsDirPath.IsExist()); + EXPECT_TRUE(FileAsDirPath.IsFile()); + EXPECT_FALSE(FileAsDirPath.IsDirectory()); + Size_U64 = Bof_GetFileSize(FileAsDirPath); + EXPECT_EQ(Size_U64, 0); + + Sts_E = Bof_CloseFile(Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(Io, -1); + + Sts_E = Bof_CreateFile(Permission_E, FileAsDirPath, true, Io2); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileAsDirPath.IsValid(), true); + EXPECT_TRUE(FileAsDirPath.IsExist()); + EXPECT_TRUE(FileAsDirPath.IsFile()); + EXPECT_FALSE(FileAsDirPath.IsDirectory()); + + Sts_E = Bof_CloseFile(Io2); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(Io2, -1); + + Sts_E = Bof_CreateFile(Permission_E, FileAsDirPath, true, Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileAsDirPath.IsValid(), true); + EXPECT_TRUE(FileAsDirPath.IsExist()); + EXPECT_TRUE(FileAsDirPath.IsFile()); + EXPECT_FALSE(FileAsDirPath.IsDirectory()); + + Sts_E = Bof_CreateFile(Permission_E, FileAsDirPath, true, Io2); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileAsDirPath.IsValid(), true); + EXPECT_TRUE(FileAsDirPath.IsExist()); + EXPECT_TRUE(FileAsDirPath.IsFile()); + EXPECT_FALSE(FileAsDirPath.IsDirectory()); + + Sts_E = Bof_CloseFile(Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(Io, -1); + + Sts_E = Bof_CloseFile(Io2); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(Io2, -1); + + Sts_E = Bof_CreateDirectory(Permission_E, NewPath); + EXPECT_NE(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_DeleteFile(FileAsDirPath); // To be sure + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CreateDirectory(Permission_E, NewPath); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CreateDirectory(Permission_E, NewPath); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_GetFsPermission(NewPath, Permission_E); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + EXPECT_TRUE((Permission_E & BOF_FILE_PERMISSION_READ_FOR_ALL) == BOF_FILE_PERMISSION_READ_FOR_ALL); + EXPECT_TRUE((Permission_E & BOF_FILE_PERMISSION_WRITE_FOR_ALL) == BOF_FILE_PERMISSION_WRITE_FOR_ALL); +#if defined(_WIN32) + EXPECT_TRUE((Permission_E & BOF_FILE_PERMISSION_EXEC_FOR_ALL) == BOF_FILE_PERMISSION_EXEC_FOR_ALL); +#else + EXPECT_FALSE((Permission_E & BOF_FILE_PERMISSION_EXEC_FOR_ALL) == BOF_FILE_PERMISSION_EXEC_FOR_ALL); +#endif + + NewPath = CrtDir; + Sts_E = NewPath.Combine("babar2/babar3/../babar4/../babar5/"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + Size_U64 = Bof_GetFileSize(NewPath); + EXPECT_NE(Size_U64, 0); + + Sts_E = Bof_CreateDirectory(Permission_E, NewPath); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + NewPath = CrtDir; + Sts_E = NewPath.Combine("babar1"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CleanupDirectory(true, NewPath, true); + EXPECT_NE(Sts_E, BOF_ERR_NO_ERROR); + + NewPath = CrtDir; + Sts_E = NewPath.Combine("babar1/"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CleanupDirectory(true, NewPath, true); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + NewPath = CrtDir; + Sts_E = NewPath.Combine("babar2/babar5"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CleanupDirectory(true, NewPath, true); + EXPECT_NE(Sts_E, BOF_ERR_NO_ERROR); + + NewPath = CrtDir; + Sts_E = NewPath.Combine("babar2/"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CleanupDirectory(true, NewPath, true); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); +#if defined(_WIN32) +#else + EXPECT_EQ(BOF::Bof_SetCurrentDirectory(Cwd_S), BOF_ERR_NO_ERROR); +#endif +} + +TEST(Fs_Test, EntireFile) +{ + BOFERR Sts_E; + BOF_FILE_PERMISSION Permission_E; + std::string Line_S, LineRead_S; + BofPath CrtDir, Path; + + Permission_E = BOF_FILE_PERMISSION_READ_FOR_ALL | BOF_FILE_PERMISSION_WRITE_FOR_ALL; + Line_S = "Hello World"; + +#if defined(_WIN32) +#else + std::string Cwd_S; + BOF::Bof_GetCurrentDirectory(Cwd_S); + EXPECT_EQ(Bof_SetCurrentDirectory("/tmp/"), BOF_ERR_NO_ERROR); +#endif + Sts_E = Bof_GetCurrentDirectory(CrtDir); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Path.CurrentDirectoryName(CrtDir.FullPathName(false)); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Path = "BhaFile.txt"; + + EXPECT_EQ(Bof_WriteLine(Permission_E, Path, false, Line_S), BOF_ERR_NO_ERROR); + EXPECT_EQ(Bof_WriteLine(Permission_E, Path, true, Line_S), BOF_ERR_NO_ERROR); + EXPECT_EQ(Bof_ReadLine(Path, LineRead_S), BOF_ERR_NO_ERROR); + Line_S = Line_S + Line_S; + EXPECT_STREQ(LineRead_S.c_str(), Line_S.c_str()); +#if defined(_WIN32) +#else + EXPECT_EQ(BOF::Bof_SetCurrentDirectory(Cwd_S), BOF_ERR_NO_ERROR); +#endif +} +TEST(Fs_Test, FileLayout) +{ + BOFERR Sts_E; + BOF_FILE_PERMISSION Permission_E; + // Permission_E = BOF_FILE_PERMISSION_READ_FOR_ALL | BOF_FILE_PERMISSION_WRITE_FOR_ALL; + BofPath CrtDir, DirLayoutRoot, Dir, File, NewFile; + uint32_t i_U32, j_U32, k_U32, Nb_U32; + uintptr_t Io; + std::string Line_S, LineRead_S; + uint64_t Pos_U64, GetPos_U64, NewPos_U64, Size_U64, Size2_U64; + + Sts_E = Bof_GetCurrentDirectory(CrtDir); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + DirLayoutRoot = CrtDir; + Sts_E = DirLayoutRoot.Combine("TstRoot/"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CleanupDirectory(true, DirLayoutRoot, true); + + Permission_E = BOF_FILE_PERMISSION_READ_FOR_ALL | BOF_FILE_PERMISSION_WRITE_FOR_ALL | BOF_FILE_PERMISSION_EXEC_FOR_ALL; + Sts_E = Bof_CreateDirectory(Permission_E, DirLayoutRoot); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_SetCurrentDirectory(DirLayoutRoot); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_GetCurrentDirectory(Dir); + EXPECT_TRUE(DirLayoutRoot == Dir); + + for (i_U32 = 0; i_U32 < 10; i_U32++) + { + Dir = DirLayoutRoot; + Sts_E = Dir.Combine("SubDir_" + std::to_string(i_U32) + "/Level1/Level2/"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CreateDirectory(Permission_E, Dir); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + if (i_U32 < 8) + { + for (j_U32 = 0; j_U32 < 8; j_U32++) + { + File = Bof_Sprintf("%sFile_%06d.%d", Dir.FullPathName(false).c_str(), j_U32, (j_U32 % 2) ? 1 : 2); + Sts_E = Bof_CreateFile(Permission_E, File, false, Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Pos_U64 = 0; + for (k_U32 = 0; k_U32 < 100; k_U32++) + { + Line_S = Bof_Sprintf("This is line %06d\n", k_U32); + Nb_U32 = static_cast(Line_S.size()); + Sts_E = Bof_WriteFile(Io, Nb_U32, reinterpret_cast(Line_S.c_str())); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(Nb_U32, Line_S.size()); + Pos_U64 += Nb_U32; + GetPos_U64 = Bof_GetFileIoPosition(Io); + EXPECT_EQ(GetPos_U64, Pos_U64); + } + Sts_E = Bof_CloseFile(Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(Io, -1); + Size_U64 = Bof_GetFileSize(File); + EXPECT_NE(Size_U64, 0); + + NewFile = Bof_Sprintf("%sFile_%06d.%d.ren", Dir.FullPathName(false).c_str(), j_U32, (j_U32 % 2) ? 1 : 2); + Sts_E = Bof_RenameFile(File, NewFile); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_CopyFile(true, NewFile, File); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Size2_U64 = Bof_GetFileSize(NewFile); + EXPECT_EQ(Size_U64, Size2_U64); + + Sts_E = Bof_DeleteFile(NewFile); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Bof_OpenFile(File, true, false, Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Pos_U64 = 0; + for (k_U32 = 0; k_U32 < 100; k_U32 += 2) + { + NewPos_U64 = Bof_SetFileIoPosition(Io, Pos_U64, BOF_SEEK_METHOD::BOF_SEEK_BEGIN); + EXPECT_EQ(NewPos_U64, Pos_U64); + Line_S = Bof_Sprintf("This is line %06d\n", k_U32); + Nb_U32 = static_cast(Line_S.size()); + Sts_E = Bof_ReadLine(Io, LineRead_S); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(Nb_U32, Line_S.size()); + EXPECT_STREQ(Line_S.c_str(), LineRead_S.c_str()); + Pos_U64 += Nb_U32; + Pos_U64 += Nb_U32; + } + Sts_E = Bof_CloseFile(Io); + } + } + } + Sts_E = Bof_SetCurrentDirectory(CrtDir); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); +} + +// Must be after FileLayout +TEST(Fs_Test, DirEnum) +{ + BOFERR Sts_E; + BofPath CrtDir, DirLayoutRoot, Path; + BOF_FILE_FOUND FileFound_X; + std::vector FileCollection; + uint32_t i_U32; + BofDateTime DateTime; + + Sts_E = Bof_GetCurrentDirectory(CrtDir); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + DirLayoutRoot = CrtDir; + Sts_E = DirLayoutRoot.Combine("TstRoot/"); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + // FileCollection.clear(); + // Sts_E = Bof_FindFile("C:\\bld\\evs-muse\\resources\\", "*", BOF::BOF_FILE_TYPE::BOF_FILE_DIR, false, FileCollection); + + FileCollection.clear(); + Sts_E = Bof_FindFile(DirLayoutRoot, "*.*", BOF_FILE_TYPE::BOF_FILE_ALL, true, 0xFFFFFFFF, FileCollection); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileCollection.size(), 94); // 64 file and 30 dir + for (i_U32 = 0; i_U32 < FileCollection.size(); i_U32++) + { + // Sts_E = Bof_TimeInSecSince1970_To_BofDateTime(FileCollection[i_U32].LastAccess_X, DateTime_X); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + // printf("Size %06lld Time %s Dir %s Path %s\n", FileCollection[i_U32].Size_U64, Bof_FormatDateTime(DateTime_X).c_str(), FileCollection[i_U32].Path.IsDirectory() ? "true " : "false", FileCollection[i_U32].Path.FullPathName(false).c_str()); + } + FileCollection.clear(); + Sts_E = Bof_FindFile(DirLayoutRoot, "*.*", BOF_FILE_TYPE::BOF_FILE_ALL, false, 0xFFFFFFFF, FileCollection); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileCollection.size(), 10); + for (i_U32 = 0; i_U32 < FileCollection.size(); i_U32++) + { + // Sts_E = Bof_TimeInSecSince1970_To_BofDateTime(FileCollection[i_U32].LastAccess_X, DateTime_X); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + // printf("Size %06lld Time %s Dir %s Path %s\n", FileCollection[i_U32].Size_U64, Bof_FormatDateTime(DateTime_X).c_str(), FileCollection[i_U32].Path.IsDirectory() ? "true " : "false", FileCollection[i_U32].Path.FullPathName(false).c_str()); + } + FileCollection.clear(); + Sts_E = Bof_FindFile(DirLayoutRoot, "*.1", BOF_FILE_TYPE::BOF_FILE_DIR, true, 0xFFFFFFFF, FileCollection); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileCollection.size(), 30); + FileCollection.clear(); + Sts_E = Bof_FindFile(DirLayoutRoot, "*.1", BOF_FILE_TYPE::BOF_FILE_ALL, true, 0xFFFFFFFF, FileCollection); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileCollection.size(), 62); // 32 file and 30 dir + FileCollection.clear(); + Sts_E = Bof_FindFile(DirLayoutRoot, "*.2", BOF_FILE_TYPE::BOF_FILE_REG, true, 0xFFFFFFFF, FileCollection); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileCollection.size(), 32); + + FileCollection.clear(); + Sts_E = Bof_FindFile(DirLayoutRoot, "*.*", BOF_FILE_TYPE::BOF_FILE_DIR, false, 0xFFFFFFFF, FileCollection); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileCollection.size(), 10); + + FileCollection.clear(); + Sts_E = Bof_FindFile(DirLayoutRoot, "*.*", BOF_FILE_TYPE::BOF_FILE_REG, true, 0xFFFFFFFF, FileCollection); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileCollection.size(), 64); // not 80 as the two last dir are empty + + FileCollection.clear(); + Sts_E = Bof_FindFile(DirLayoutRoot, "*.*", BOF_FILE_TYPE::BOF_FILE_ALL, false, 0xFFFFFFFF, FileCollection); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_EQ(FileCollection.size(), 10); + + FileCollection.clear(); + Sts_E = Bof_FindFile(DirLayoutRoot, "*.*", BOF_FILE_TYPE::BOF_FILE_ALL, false, 7, FileCollection); + EXPECT_EQ(Sts_E, BOF_ERR_CANCEL); + EXPECT_EQ(FileCollection.size(), 7); +} + +TEST(Fs_Test, CreateTempFile) +{ + uintptr_t Io; + BOFERR Sts_E; + BofPath DirPath, Path; + + Sts_E = Bof_GetCurrentDirectory(DirPath); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Path = DirPath; + Sts_E = Bof_CreateTempFile(BOF_FILE_PERMISSION_ALL_FOR_ALL, Path, "tmp", Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + EXPECT_STREQ(Path.DirectoryName(false, false).c_str(), DirPath.DirectoryName(false, false).c_str()); + EXPECT_STREQ(Path.Extension().c_str(), "tmp"); + Sts_E = Bof_CloseFile(Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); +} + +TEST(Fs_Test, ResetFileContentReOpenMode) +{ + BOFERR Sts_E; + BOF_FILE_PERMISSION Permission_E; + std::string Line_S, NewLine_S, LineRead_S, LineWrt_S; + BofPath Dir, Path; + uintptr_t Io; + uint32_t Nb_U32; + /* + std::string RawData_S; + uint32_t Start_U32, Delta_U32, i_U32; + //https://www.learningcontainer.com/sample-docx-file-for-testing/ + for (i_U32 = 0; i_U32 < 10; i_U32++) + { + Start_U32 = BOF::Bof_GetMsTickCount(); + Sts_E = Bof_ReadFile("C:/Users/User/Downloads/32-MB-docx-file-download.docx", RawData_S); + Delta_U32 = BOF::Bof_ElapsedMsTime(Start_U32); + //printf("[%d] Delta %d ms Sz %zd B %zd KB %zd MB Err %s\n", i_U32, Delta_U32, RawData_S.size(), RawData_S.size() / 1024, RawData_S.size() / 1024 / 1024,BOF::Bof_ErrorCode(Sts_E)); + } + */ + Permission_E = BOF_FILE_PERMISSION_READ_FOR_ALL | BOF_FILE_PERMISSION_WRITE_FOR_ALL; + Line_S = "Hello World"; + + Sts_E = Bof_GetCurrentDirectory(Dir); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Path.CurrentDirectoryName(Dir.FullPathName(false)); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Path = "BhaFile.txt"; + + Sts_E = Bof_CreateFile(Permission_E, Path, false, Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + Nb_U32 = static_cast(Line_S.size()); + EXPECT_EQ(Bof_WriteFile(Io, Nb_U32, reinterpret_cast(Line_S.c_str())), BOF_ERR_NO_ERROR); + EXPECT_EQ(Nb_U32, Line_S.size()); + + Nb_U32 = static_cast(Line_S.size()); + EXPECT_EQ(Bof_WriteFile(Io, Nb_U32, reinterpret_cast(Line_S.c_str())), BOF_ERR_NO_ERROR); + EXPECT_EQ(Nb_U32, Line_S.size()); + + EXPECT_EQ(Bof_ReadFile(Path, LineRead_S), BOF_ERR_NO_ERROR); + NewLine_S = Line_S + Line_S; + EXPECT_STREQ(LineRead_S.c_str(), NewLine_S.c_str()); + + EXPECT_EQ(Bof_ResetFileContent(Path, true, 0), BOF_ERR_NO_ERROR); + + EXPECT_EQ(Bof_ReadFile(Path, LineRead_S), BOF_ERR_NO_ERROR); + EXPECT_STREQ(LineRead_S.c_str(), ""); + + LineWrt_S = "Bye cruel World"; + Nb_U32 = static_cast(LineWrt_S.size()); + EXPECT_EQ(Bof_WriteFile(Io, Nb_U32, reinterpret_cast(LineWrt_S.c_str())), BOF_ERR_NO_ERROR); + EXPECT_EQ(Nb_U32, LineWrt_S.size()); + + EXPECT_EQ(Bof_CloseFile(Io), BOF_ERR_NO_ERROR); + EXPECT_EQ(Bof_ReadFile(Path, LineRead_S), BOF_ERR_NO_ERROR); + EXPECT_STREQ(LineRead_S.c_str(), ""); // Extra zero are inserted at the beginning as Io has an offset of Line_S.size() but the file has been shrinked to O byte->write add extra 0 upp to crt file pos LineWrt_S.c_str()); +} + +TEST(Fs_Test, ResetFileContent) +{ + BOFERR Sts_E; + BOF_FILE_PERMISSION Permission_E; + std::string Line_S, NewLine_S, LineRead_S, LineWrt_S; + BofPath Dir, Path; + uintptr_t Io; + uint32_t Nb_U32; + + Permission_E = BOF_FILE_PERMISSION_READ_FOR_ALL | BOF_FILE_PERMISSION_WRITE_FOR_ALL; + Line_S = "Hello World"; + + Sts_E = Bof_GetCurrentDirectory(Dir); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Sts_E = Path.CurrentDirectoryName(Dir.FullPathName(false)); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + + Path = "BhaFile.txt"; + + Sts_E = Bof_CreateFile(Permission_E, Path, false, Io); + EXPECT_EQ(Sts_E, BOF_ERR_NO_ERROR); + Nb_U32 = static_cast(Line_S.size()); + EXPECT_EQ(Bof_WriteFile(Io, Nb_U32, reinterpret_cast(Line_S.c_str())), BOF_ERR_NO_ERROR); + EXPECT_EQ(Nb_U32, Line_S.size()); + + Nb_U32 = static_cast(Line_S.size()); + EXPECT_EQ(Bof_WriteFile(Io, Nb_U32, reinterpret_cast(Line_S.c_str())), BOF_ERR_NO_ERROR); + EXPECT_EQ(Nb_U32, Line_S.size()); + + EXPECT_EQ(Bof_ReadFile(Path, LineRead_S), BOF_ERR_NO_ERROR); + NewLine_S = Line_S + Line_S; + EXPECT_STREQ(LineRead_S.c_str(), NewLine_S.c_str()); + +#if defined(_WIN32) +#else + EXPECT_EQ(Bof_ResetFileContent(Path, false, Line_S.size()), BOF_ERR_NO_ERROR); + + EXPECT_EQ(Bof_ReadFile(Path, LineRead_S), BOF_ERR_NO_ERROR); + EXPECT_STREQ(LineRead_S.c_str(), Line_S.c_str()); + + LineWrt_S = "Bye cruel World"; + Nb_U32 = static_cast(LineWrt_S.size()); + EXPECT_EQ(Bof_WriteFile(Io, Nb_U32, reinterpret_cast(LineWrt_S.c_str())), BOF_ERR_NO_ERROR); + EXPECT_EQ(Nb_U32, LineWrt_S.size()); + + EXPECT_EQ(Bof_CloseFile(Io), BOF_ERR_NO_ERROR); + EXPECT_EQ(Bof_ReadFile(Path, LineRead_S), BOF_ERR_NO_ERROR); + // EXPECT_STREQ(LineRead_S.c_str(), (Line_S + LineWrt_S).c_str()); + EXPECT_STREQ(LineRead_S.c_str(), Line_S.c_str()); // Extra zero are inserted at the beginning as Io has an offset of Line_S.size() but the file has been shrinked to O byte->write add extra 0 upp to crt file pos LineWrt_S.c_str()); +#endif +} \ No newline at end of file diff --git a/lib/src/ut_jsonparserwriter.cpp b/lib/src/ut_jsonparserwriter.cpp new file mode 100755 index 0000000..b2d2415 --- /dev/null +++ b/lib/src/ut_jsonparserwriter.cpp @@ -0,0 +1,997 @@ +/* + * Copyright (c) 2015-2025, OnBings All rights reserved. + * + * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR + * PURPOSE. + * + * This module implements the unit tests of the jsonparser library + * + * Name: ut_jsonparser.cpp + * Author: b.harmel@gmail.com + * Revision: 1.0 + * + * Rem: Based on google test + * + * History: + * + * V 1.00 vendredi 30 mai 2014 16:51:15 b.harmel : Initial release + */ +#include +#include +#include +#include +#include +#include + +#include "gtestrunner.h" + +USE_BOF_NAMESPACE() +#include "ut_parser.h" + +#include +#include +/* + "JsonType": { + "bool": true, + "decimal": 10, + "float": 3.14, + "string": "Hello world !\n", + "null": null, + "employee": { + "name": "John", + "age": 30, + "city": "New York" + }, + "employees": [ "John", "Anna", "Peter" ] + } +*/ +void PrintRoot(Json::Value _Root) +{ + Json::Value::iterator It = _Root.begin(); + std::string name; + int i = 0; + + for (It = _Root.begin(); It != _Root.end(); It++) + { + name = _Root.getMemberNames()[i]; + if (_Root[name].isInt()) + { + std::cout << "MemberName " << name << " int " << std::endl; + std::cout << _Root[name].asInt() << std::endl; + } + else if (_Root[name].isDouble()) + { + std::cout << "MemberName " << name << " double " << std::endl; + std::cout << _Root[name].asDouble() << std::endl; + } + else if (_Root[name].isBool()) + { + std::cout << "MemberName " << name << " bool " << std::endl; + std::cout << _Root[name].asBool() << std::endl; + } + else if (_Root[name].isArray()) + { + std::cout << "MemberName " << name << " array size " << _Root[name].size() << std::endl; + int size = _Root[name].size(); + for (int i = 0; i < size; i++) + { + Json::Value dat1 = _Root[name]; + PrintRoot(dat1.get(i, _Root[name])); + } + std::cout << "MemberName " << name << " array is object " << std::endl; + } + else if (_Root[name].isInt64()) + { + std::cout << "MemberName " << name << " array " << std::endl; + std::cout << _Root[name].asInt64() << std::endl; + } + else if (_Root[name].isString()) + { + std::cout << "MemberName " << name << " string " << std::endl; + std::cout << _Root[name].asString() << std::endl; + } + else if (_Root[name].isObject()) + { + std::cout << "MemberName " << name << " object " << std::endl; + PrintRoot(_Root[name]); + // std::cout << root[name].asCString() << std::endl; + } + else + { + std::cout << "MemberName " << name << " unknown type " << std::endl; + // std::cout << root[name].asCString() << std::endl; + } + i++; + } +} +TEST(JsonParser_Test, JsonTypeNative) +{ + Json::Value Root, Val; + std::ifstream Ifs; + Json::CharReaderBuilder JsonReader; + JSONCPP_STRING JsonErr; + + std::string Cwd_S; + BOF::Bof_GetCurrentDirectory(Cwd_S); + BOF::BofPath Path(Cwd_S); + Path.Combine("../../binaries/bin/data/jsonparser.json"); + printf("Cwd=%s Path=%s\n",Cwd_S.c_str(),Path.ToString().c_str()); + Ifs.open("../../binaries/bin/data/jsonparser.json"); + JsonReader["collectComments"] = true; + if (!parseFromStream(JsonReader, Ifs, &Root, &JsonErr)) + { + std::cout << JsonErr << std::endl; + Ifs.close(); + } + else + { + Ifs.close(); + + Val = Root["JsonType"]; + Val = Root["MmgwSetting"]; + // PrintRoot(Root); + } +} + +// BOFERR JsonParseResultUltimateCheck(uint32_t /*_Index_U32*/, const BOFPARAMETER & /*_rBofCommandlineOption_X*/, const bool _CheckOk_B, const char * /*_pOptNewVal_c*/) +BOFERR JsonParseResultUltimateCheck(uint32_t /*_Index_U32*/, const BOFPARAMETER &_rBofCommandlineOption_X, const bool _CheckOk_B, const char *_pOptNewVal_c) +{ + BOFERR Rts_E = _CheckOk_B ? BOF_ERR_NO_ERROR : BOF_ERR_NO; + return Rts_E; +} + +bool JsonParseError(int _Sts_i, const BOFPARAMETER &_rJsonEntry_X, const char *_pValue) +{ + bool Rts_B = true; + return Rts_B; +} + +BOFERR JsonWriteResultUltimateCheck(uint32_t /*_Index_U32*/, const BOFPARAMETER & /*_rBofCommandlineOption_X*/, const bool _CheckOk_B, const char * /*_pOptNewVal_c*/) +{ + BOFERR Rts_E = _CheckOk_B ? BOF_ERR_NO_ERROR : BOF_ERR_NO; + return Rts_E; +} + +bool JsonWriteError(int /*_Sts_E*/, const BOFPARAMETER & /*_rJsonEntry_X*/, const char * /*_pValue*/) +{ + bool Rts_B = true; + return Rts_B; +} +//{"JsonType": {"bool":true, "decimal":10, "float":3.14, "string":"Hello world !\n", "employee":{"name":"John", "age":30, "city":"New York"}, "employees":["John", "Anna", "Peter"] }} +JSON_TYPE S_JsonType_X; +std::vector S_JsonTypeSchemaCollection = { + {nullptr, "bool", "", "", "JsonType", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_JsonType_X.Bool_B, BOOL, 0, 0)}, + {nullptr, "decimal", "", "", "JsonType", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_JsonType_X.Decimal_S64, INT64, 0, 0)}, + {nullptr, "float", "", "", "JsonType", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_JsonType_X.Double_lf, DOUBLE, 0, 0)}, + {nullptr, "string", "", "", "JsonType", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_JsonType_X.String_S, STDSTRING, 0, 0)}, + + {nullptr, "name", "", "", "JsonType.employee", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_JsonType_X.Employee_X.Name_S, STDSTRING, 0, 0)}, + {nullptr, "age", "", "", "JsonType.employee", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_JsonType_X.Employee_X.Age_S32, INT16, 0, 0)}, + {nullptr, "city", "", "", "JsonType.employee", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_JsonType_X.Employee_X.City_S, STDSTRING, 0, 0)}, + + {nullptr, "name", "", "", "JsonType.employees", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(JSON_OBJECT, S_JsonType_X.pEmployee_X, Name_S, STDSTRING, 0, 0)}, + {nullptr, "age", "", "", "JsonType.employees", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(JSON_OBJECT, S_JsonType_X.pEmployee_X, Age_S32, INT32, 0, 0)}, + {nullptr, "city", "", "", "JsonType.employees", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(JSON_OBJECT, S_JsonType_X.pEmployee_X, City_S, STDSTRING, 0, 0)}, + + {nullptr, "", "", "", "JsonType.strings", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_JsonType_X.StringCollection, STDSTRING, 0, 0)}, +}; +TEST(JsonParser_Test, JsonType) +{ + BofJsonParser *pBofJsonParser_O; + const char *pValue_c; + int Sts_i; + BofPath CrtDir, Path; + std::string JsonData_S; + + S_JsonType_X.Reset(); + + Bof_GetCurrentDirectory(CrtDir); + Path = CrtDir + "../../binaries/bin/data/jsonparser.json"; + // printf("crtdir %s Jsonpath is %s\n", CrtDir.FullPathName(false).c_str(), Path.FullPathName(false).c_str()); + + EXPECT_EQ(Bof_ReadFile(Path, JsonData_S), BOF_ERR_NO_ERROR); + + pBofJsonParser_O = new BofJsonParser(JsonData_S); + EXPECT_TRUE(pBofJsonParser_O != nullptr); + Sts_i = pBofJsonParser_O->ToByte(S_JsonTypeSchemaCollection, JsonParseResultUltimateCheck, JsonParseError); + EXPECT_EQ(Sts_i, 0); + + EXPECT_TRUE(S_JsonType_X.Bool_B); + EXPECT_EQ(S_JsonType_X.Decimal_S64, 10); + EXPECT_EQ(S_JsonType_X.Double_lf, 3.14); + EXPECT_STREQ(S_JsonType_X.String_S.c_str(), "Hello world !\n"); + EXPECT_EQ(S_JsonType_X.Employee_X.Age_S32, 30); + EXPECT_STREQ(S_JsonType_X.Employee_X.Name_S.c_str(), "John"); + EXPECT_STREQ(S_JsonType_X.Employee_X.City_S.c_str(), "New York"); + EXPECT_EQ(S_JsonType_X.pEmployee_X[0].Age_S32, 30); + EXPECT_STREQ(S_JsonType_X.pEmployee_X[0].Name_S.c_str(), "John"); + EXPECT_STREQ(S_JsonType_X.pEmployee_X[0].City_S.c_str(), "New York"); + EXPECT_EQ(S_JsonType_X.pEmployee_X[1].Age_S32, 20); + EXPECT_STREQ(S_JsonType_X.pEmployee_X[1].Name_S.c_str(), "Anna"); + EXPECT_STREQ(S_JsonType_X.pEmployee_X[1].City_S.c_str(), "LosAngeles"); + EXPECT_EQ(S_JsonType_X.pEmployee_X[2].Age_S32, 10); + EXPECT_STREQ(S_JsonType_X.pEmployee_X[2].Name_S.c_str(), "Peter"); + EXPECT_STREQ(S_JsonType_X.pEmployee_X[2].City_S.c_str(), "Denver"); + EXPECT_EQ(S_JsonType_X.pEmployee_X[3].Age_S32, 0); + EXPECT_STREQ(S_JsonType_X.pEmployee_X[3].Name_S.c_str(), ""); + EXPECT_STREQ(S_JsonType_X.pEmployee_X[3].City_S.c_str(), ""); + + EXPECT_EQ(S_JsonType_X.StringCollection.size(), 3); + EXPECT_STREQ(S_JsonType_X.StringCollection[0].c_str(), "John"); + EXPECT_STREQ(S_JsonType_X.StringCollection[1].c_str(), "Anna"); + EXPECT_STREQ(S_JsonType_X.StringCollection[2].c_str(), "Peter"); + + /* + pValue_c = pBofJsonParser_O->GetFirstElementFromOid("MulFtpUserSetting.DeployIpAddress"); + EXPECT_TRUE(pValue_c != nullptr); + pValue_c = pBofJsonParser_O->GetNextElementFromOid(); + EXPECT_TRUE(pValue_c == nullptr); + + pValue_c = pBofJsonParser_O->GetFirstElementFromOid("MulFtpUserSetting.catalog.book.id"); + EXPECT_TRUE(pValue_c != nullptr); + pValue_c = pBofJsonParser_O->GetNextElementFromOid(); + EXPECT_TRUE(pValue_c != nullptr); +*/ + BOF_SAFE_DELETE(pBofJsonParser_O); +} +static PARSER_APPPARAM S_AppParamJson_X; +static std::vector S_OptionJsonCollection = { + {nullptr, "id", "id", "", "MulFtpUserSetting.catalog.book", BOFPARAMETER_ARG_FLAG::XML_ATTRIBUTE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(BOOKPARAM, S_AppParamJson_X.pBook_X, pId_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pBook_X[0].pId_c) - 1)}, + + {nullptr, "DeployIpAddress", "DeployIpAddress", "", "MulFtpUserSetting", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AppParamJson_X.DeployIpAddress_X, IPV4, 0, 0)}, + {nullptr, "DeployIpPort", "DeployIpPort", "", "MulFtpUserSetting", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AppParamJson_X.DeployIpPort_U16, UINT16, 0, 0)}, + {nullptr, "DeployProtocol", "DeployProtocol", "", "MulFtpUserSetting", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AppParamJson_X.pDeployProtocol_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pDeployProtocol_c) - 1)}, + {nullptr, "DeployDirectory", "DeployDirectory", "", "MulFtpUserSetting", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AppParamJson_X.pDeployDirectory_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pDeployDirectory_c) - 1)}, + {nullptr, "LoginUser", "LoginUser", "", "MulFtpUserSetting", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AppParamJson_X.pLoginUser_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pLoginUser_c) - 1)}, + {nullptr, "LoginPassword", "LoginPassword", "", "MulFtpUserSetting", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AppParamJson_X.pLoginPassword_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pLoginPassword_c) - 1)}, + {nullptr, "Email", "Email", "", "MulFtpUserSetting", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AppParamJson_X.pEmail_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pEmail_c) - 1)}, + {nullptr, "UserName", "UserName", "", "MulFtpUserSetting", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AppParamJson_X.pUserName_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pUserName_c) - 1)}, + {nullptr, "UserCompany", "UserCompany", "", "MulFtpUserSetting", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AppParamJson_X.pUserCompany_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pUserCompany_c) - 1)}, + {nullptr, "ToolChainBaseDirectory", "ToolChainBaseDirectory", "", "MulFtpUserSetting", BOFPARAMETER_ARG_FLAG::NONE, + BOF_PARAM_DEF_VARIABLE(S_AppParamJson_X.pToolChainBaseDirectory_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pToolChainBaseDirectory_c) - 1)}, + {nullptr, "TemplateProjectBaseDirectory", "TemplateProjectBaseDirectory", "", "MulFtpUserSetting", BOFPARAMETER_ARG_FLAG::NONE, + BOF_PARAM_DEF_VARIABLE(S_AppParamJson_X.pTemplateProjectBaseDirectory_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pTemplateProjectBaseDirectory_c) - 1)}, + + // For xml serialize xml array entry must be contiguous MulFtpUserSetting.catalog.book + {nullptr, "id", "id", "", "MulFtpUserSetting.catalog.book", BOFPARAMETER_ARG_FLAG::XML_ATTRIBUTE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(BOOKPARAM, S_AppParamJson_X.pBook_X, pId_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pBook_X[0].pId_c) - 1)}, + {nullptr, "author", "author", "", "MulFtpUserSetting.catalog.book", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(BOOKPARAM, S_AppParamJson_X.pBook_X, pAuthor_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pBook_X[0].pAuthor_c) - 1)}, + + {nullptr, "title", "title", "", "MulFtpUserSetting.catalog.book", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(BOOKPARAM, S_AppParamJson_X.pBook_X, pTitle_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pBook_X[0].pTitle_c) - 1)}, + {nullptr, "genre", "genre", "", "MulFtpUserSetting.catalog.book", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(BOOKPARAM, S_AppParamJson_X.pBook_X, pGenre_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pBook_X[0].pGenre_c) - 1)}, + {nullptr, "price", "price", "", "MulFtpUserSetting.catalog.book", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(BOOKPARAM, S_AppParamJson_X.pBook_X, Price_f, FLOAT, 0, 0)}, + + // BAD for json { nullptr, "tag", "dbg1", "", "MulFtpUserSetting.catalog.book.bhaattr", BOFPARAMETER_ARG_FLAG::XML_ATTRIBUTE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(BOOKPARAM, S_AppParamJson_X.pBook_X, pBha1_c, CHARSTRING, 0, 0) }, + + {nullptr, "bha", "dbg2", "", "MulFtpUserSetting.catalog.book", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(BOOKPARAM, S_AppParamJson_X.pBook_X, pBha2_c, CHARSTRING, 0, 0)}, + {nullptr, "publish_date", "publish_date", "%Y-%m-%d", "MulFtpUserSetting.catalog.book", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(BOOKPARAM, S_AppParamJson_X.pBook_X, PublishDate, DATE, 0, 0)}, + {nullptr, "description", "description", "", "MulFtpUserSetting.catalog.book", BOFPARAMETER_ARG_FLAG::NONE, + BOF_PARAM_DEF_ARRAY_OF_STRUCT(BOOKPARAM, S_AppParamJson_X.pBook_X, pDescription_c, CHARSTRING, 1, sizeof(S_AppParamJson_X.pBook_X[0].pDescription_c) - 1)}, + + {nullptr, "a", "other a", "", "MulFtpUserSetting.arrayofother.other", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(OTHER, S_AppParamJson_X.pOther_X, a_U32, UINT32, 0, 0)}, + {nullptr, "b", "other b", "", "MulFtpUserSetting.arrayofother.other", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(OTHER, S_AppParamJson_X.pOther_X, b_U32, UINT32, 0, 0)}, + {nullptr, "c", "other c", "", "MulFtpUserSetting.arrayofother.other", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY_OF_STRUCT(OTHER, S_AppParamJson_X.pOther_X, c_U32, UINT32, 0, 0)}, + +}; + +static IPSENDER S_IpSenderParam_X; +static std::vector S_IpSenderOptionCollection = { + {nullptr, "description", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_IpSenderParam_X.Description_S, STDSTRING, 0, 0)}, + {nullptr, "device_id", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_IpSenderParam_X.DeviceId_S, STDSTRING, 0, 0)}, + {nullptr, "flow_id", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_IpSenderParam_X.FlowId_S, STDSTRING, 0, 0)}, + {nullptr, "id", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_IpSenderParam_X.Id_S, STDSTRING, 0, 0)}, + {nullptr, "label", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_IpSenderParam_X.Label_S, STDSTRING, 0, 0)}, + {nullptr, "manifest_href", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_IpSenderParam_X.HrefManifest_S, STDSTRING, 0, 0)}, + // { nullptr, "e", "", "", "add_sender.tags.taglist", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY(S_IpSenderParam_X.pTag_S, STDSTRING, 0, 0) }, + {nullptr, "", "", "", "add_sender.tags.", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY(S_IpSenderParam_X.pTag_S, STDSTRING, 0, 0)}, + {nullptr, "transport", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_IpSenderParam_X.Transport_S, STDSTRING, 0, 0)}, + {nullptr, "version", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_IpSenderParam_X.Version_S, STDSTRING, 0, 0)}, +}; +static IPMANIFEST S_IpManifestParam_X; +static std::vector S_IpManifestOptionCollection = { + {nullptr, "", "", "", "add_manifest.sdp", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_ARRAY(S_IpManifestParam_X.pSdpLine_S, STDSTRING, 0, 0)}, + {nullptr, "sender_id", "", "", "add_manifest", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_IpManifestParam_X.SenderId_S, STDSTRING, 0, 0)}, +}; +static IPCONNECT S_IpConnectParam_X; +static std::vector S_IpConnectOptionCollection = { + {nullptr, "receiver_id", "", "", "connect", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_IpConnectParam_X.ReceiverId_S, STDSTRING, 0, 0)}, + {nullptr, "", "", "", "connect.sdp", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_IpConnectParam_X.SdpCollection, STDSTRING, 0, 0)}, +}; + +//{"add_device":{"id":"a8500668-9218-4063-ba36-9b4900b82e67","label":"","node_id":"00000000-0000-0000-0000-000000000000","receivers":[],"senders":[],"type":"","version":""}} +ADD_DEVICE S_AddDevice_X; +std::vector S_AddDeviceSchemaCollection = { + {nullptr, "id", "", "", "add_device", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddDevice_X.Id, GUID, 0, 0)}, + {nullptr, "label", "", "", "add_device", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddDevice_X.Label_S, STDSTRING, 0, 0)}, + {nullptr, "node_id", "", "", "add_device", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddDevice_X.NodeId, GUID, 0, 0)}, + {nullptr, "", "", "", "add_device.receivers", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_AddDevice_X.ReceiverCollection, STDSTRING, 0, 0)}, + {nullptr, "", "", "", "add_device.senders", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_AddDevice_X.SenderCollection, STDSTRING, 0, 0)}, + {nullptr, "type", "", "", "add_device", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddDevice_X.Type_S, STDSTRING, 0, 0)}, + {nullptr, "version", "", "", "add_device", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddDevice_X.Version_S, STDSTRING, 0, 0)}, +}; + +//{"add_source":{"caps":{},"description":"OUT1","device_id":"a8500668-9218-4063-ba36-9b4900b82e67","format":"","id":"895085f3-76a1-4f09-b3dd-2aabeb230cd8","label":"Player A","parents":[],"tags":{"":[]},"version":""}} +ADD_SOURCE S_AddSource_X; +std::vector S_AddSourceSchemaCollection = { + {nullptr, "caps", "", "", "add_source", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSource_X.Caps_S, STDSTRING, 0, 0)}, + {nullptr, "description", "", "", "add_source", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSource_X.Description_S, STDSTRING, 0, 0)}, + {nullptr, "device_id", "", "", "add_source", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSource_X.DeviceId, GUID, 0, 0)}, + {nullptr, "format", "", "", "add_source", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSource_X.Format_S, STDSTRING, 0, 0)}, + {nullptr, "id", "", "", "add_source", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSource_X.Id, GUID, 0, 0)}, + {nullptr, "label", "", "", "add_source", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSource_X.Label_S, STDSTRING, 0, 0)}, + {nullptr, "", "", "", "add_source.parents", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_AddSource_X.ParentCollection, STDSTRING, 0, 0)}, + {nullptr, "", "", "", "add_source.tags.", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_AddSource_X.TagCollection, STDSTRING, 0, 0)}, + {nullptr, "version", "", "", "add_source", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSource_X.Version_S, STDSTRING, 0, 0)}, +}; + +//{"add_flow":{"description":"OUT1","format":"","id":"40b94c9d-9bf1-4721-95ae-4316b4e080ea","label":"Player A","parents":[],"source_id":"895085f3-76a1-4f09-b3dd-2aabeb230cd8","tags":{"":[]},"version":""}} +ADD_FLOW S_AddFlow_X; +std::vector S_AddFlowSchemaCollection = { + {nullptr, "description", "", "", "add_flow", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddFlow_X.Description_S, STDSTRING, 0, 0)}, + {nullptr, "format", "", "", "add_flow", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddFlow_X.Format_S, STDSTRING, 0, 0)}, + {nullptr, "id", "", "", "add_flow", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddFlow_X.Id, GUID, 0, 0)}, + {nullptr, "label", "", "", "add_flow", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddFlow_X.Label_S, STDSTRING, 0, 0)}, + {nullptr, "", "", "", "add_flow.parents", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_AddFlow_X.ParentCollection, STDSTRING, 0, 0)}, + {nullptr, "source_id", "", "", "add_flow", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddFlow_X.SourceId, GUID, 0, 0)}, + {nullptr, "", "", "", "add_flow.tags.", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_AddFlow_X.TagCollection, STDSTRING, 0, 0)}, + {nullptr, "version", "", "", "add_flow", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddFlow_X.Version_S, STDSTRING, 0, 0)}, +}; + +//{"add_sender":{"description":"OUT1","device_id":"a8500668-9218-4063-ba36-9b4900b82e67","flow_id":"40b94c9d-9bf1-4721-95ae-4316b4e080ea","id":"edbe7239-8659-46c9-a4f7-85b46a2efc73","label":"Player +// A","manifest_href":"","tags":{"":[]},"transport":"","version":""}} +ADD_SENDER S_AddSender_X; +std::vector S_AddSenderSchemaCollection = { + {nullptr, "description", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSender_X.Description_S, STDSTRING, 0, 0)}, + {nullptr, "device_id", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSender_X.DeviceId, GUID, 0, 0)}, + {nullptr, "flow_id", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSender_X.FlowId, GUID, 0, 0)}, + {nullptr, "id", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSender_X.Id, GUID, 0, 0)}, + {nullptr, "label", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSender_X.Label_S, STDSTRING, 0, 0)}, + {nullptr, "manifest_href", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSender_X.HrefManifest_S, STDSTRING, 0, 0)}, + {nullptr, "", "", "", "add_sender.tags.", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_AddSender_X.TagCollection, STDSTRING, 0, 0)}, + {nullptr, "transport", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSender_X.Transport_S, STDSTRING, 0, 0)}, + {nullptr, "version", "", "", "add_sender", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddSender_X.Version_S, STDSTRING, 0, 0)}, +}; + +//{"add_receiver":{"caps":{},"description":"IN1","device_id":"a8500668-9218-4063-ba36-9b4900b82e67","format":"","id":"998a20b2-2a8a-42c3-a527-46d1de96a9df","label":"Recorder +// A","subscription":{"sender_id":"00000000-0000-0000-0000-000000000000"},"tags":{"":[]},"transport":"","version":""}} +ADD_RECEIVER S_AddReceiver_X; +std::vector S_AddReceiverSchemaCollection = { + {nullptr, "caps", "", "", "add_receiver", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddReceiver_X.Caps_S, STDSTRING, 0, 0)}, + {nullptr, "description", "", "", "add_receiver", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddReceiver_X.Description_S, STDSTRING, 0, 0)}, + {nullptr, "device_id", "", "", "add_receiver", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddReceiver_X.DeviceId, GUID, 0, 0)}, + {nullptr, "format", "", "", "add_receiver", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddReceiver_X.Format_S, STDSTRING, 0, 0)}, + {nullptr, "id", "", "", "add_receiver", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddReceiver_X.Id, GUID, 0, 0)}, + {nullptr, "label", "", "", "add_receiver", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddReceiver_X.Label_S, STDSTRING, 0, 0)}, + {nullptr, "sender_id", "", "", "add_receiver.subscription", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddReceiver_X.SubscriptionSenderId, GUID, 0, 0)}, + {nullptr, "", "", "", "add_receiver.tags.", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_AddReceiver_X.TagCollection, STDSTRING, 0, 0)}, + {nullptr, "transport", "", "", "add_receiver", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddReceiver_X.Transport_S, STDSTRING, 0, 0)}, + {nullptr, "version", "", "", "add_receiver", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddReceiver_X.Version_S, STDSTRING, 0, 0)}, +}; + +//{"add_manifest":{"sdp":["v=0","o=- 0 0 IN IP4 18.52.86.0","s=OUT1","i=Player A","c=IN IP4 33.67.101.0/32","t=0 0","m=video 16384 RTP/AVP 96","a=rtpmap:96 raw/90000","a=fmtp:96 packetization-mode=1"],"sender_id":"edbe7239-8659-46c9-a4f7-85b46a2efc73"}} +ADD_MANIFEST S_AddManifest_X; +std::vector S_AddManifestSchemaCollection = { + {nullptr, "sender_id", "", "", "add_manifest", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_AddManifest_X.SenderId, GUID, 0, 0)}, + {nullptr, "", "", "", "add_manifest.sdp", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_AddManifest_X.SdpLineCollection, STDSTRING, 0, 0)}, +}; + +//{"connect":{"receiver_id":"1c513fc7-faa8-4a89-bd1c-56d8b00a1355","sdp":["v=0","o=- 0 0 IN IP4 18.52.86.0","s=OUT1","i=Player A","c=IN IP4 33.67.101.0/32","t=0 0","m=video 16384 RTP/AVP 96","a=rtpmap:96 raw/90000","a=fmtp:96 packetization-mode=1"]}} +CMD_CONNECT S_CmdConnect_X; +std::vector S_CmdConnectSchemaCollection = { + {nullptr, "receiver_id", "", "", "connect", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_CmdConnect_X.ReceiverId, GUID, 0, 0)}, + {nullptr, "", "", "", "connect.sdp", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_CmdConnect_X.SdpLineCollection, STDSTRING, 0, 0)}, +}; + +//{"status_receivers":{"arg":""}} +CMD_STATUS_RECEIVERS S_CmdStatusReceiver_X; +std::vector S_CmdStatusReceiverSchemaCollection = { + {nullptr, "arg", "", "", "status_receivers", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_CmdStatusReceiver_X.Arg_S, STDSTRING, 0, 0)}, +}; +//{"status_receivers":{"":[{"id":"1c513fc7-faa8-4a89-bd1c-56d8b00a1355","ip":"18.52.86.0:1234","present":"both","impaired":"true","state":"AB"},{"id":"1c513fc7-faa8-4a89-bd1c-56d8b00adead","ip":"18.52.86.2:1235","present":"primary","impaired":"false","state":"A"}] +//}} +REPLY_STATUS_RECEIVERS S_ReplyStatusReceiver_X; +std::vector S_ReplyStatusReceiverSchemaCollection = { + {nullptr, "id", "", "", "status_receivers", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_ReplyStatusReceiver_X.IdCollection, GUID, 0, 0)}, + {nullptr, "ip", "", "", "status_receivers", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_ReplyStatusReceiver_X.IpCollection, IPV4, 0, 0)}, + {nullptr, "present", "", "", "status_receivers", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_ReplyStatusReceiver_X.PresentCollection, STDSTRING, 0, 0)}, + {nullptr, "impaired", "", "", "status_receivers", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_ReplyStatusReceiver_X.ImpairedCollection, BOOL, 0, 0)}, + {nullptr, "state", "", "", "status_receivers", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_ReplyStatusReceiver_X.StateCollection, STDSTRING, 0, 0)}, +}; + +//{"status_senders":{"arg":""}} +CMD_STATUS_SENDERS S_CmdStatusSender_X; +std::vector S_CmdStatusSenderSchemaCollection = { + {nullptr, "arg", "", "", "status_senders", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VARIABLE(S_CmdStatusSender_X.Arg_S, STDSTRING, 0, 0)}, +}; + +//{"status_senders":{"":[{"id":"1c513fc7-faa8-4a89-bd1c-56d8b00a1356","ip":"118.52.86.0:1234","present":"lost","impaired":"true","state":"B"},{"id":"1c513fc7-faa8-4a89-bd1c-56d8b00abeef","ip":"18.52.86.222:235","present":"primary","impaired":"true","state":"XA"}] +//}} +REPLY_STATUS_SENDERS S_ReplyStatusSender_X; +std::vector S_ReplyStatusSenderSchemaCollection = { + {nullptr, "id", "", "", "status_senders", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_ReplyStatusSender_X.IdCollection, GUID, 0, 0)}, + {nullptr, "ip", "", "", "status_senders", BOFPARAMETER_ARG_FLAG::IP_FORMAT_PORT, BOF_PARAM_DEF_VECTOR(S_ReplyStatusSender_X.IpCollection, IPV4, 0, 0)}, + {nullptr, "present", "", "", "status_senders", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_ReplyStatusSender_X.PresentCollection, STDSTRING, 0, 0)}, + {nullptr, "impaired", "", "", "status_senders", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_ReplyStatusSender_X.ImpairedCollection, BOOL, 0, 0)}, + {nullptr, "state", "", "", "status_senders", BOFPARAMETER_ARG_FLAG::NONE, BOF_PARAM_DEF_VECTOR(S_ReplyStatusSender_X.StateCollection, STDSTRING, 0, 0)}, +}; + +TEST(JsonParser_Test, Json) +{ + BofJsonParser *pBofJsonParser_O; + const char *pValue_c; + int Sts_i; + BofPath CrtDir, Path; + std::string JsonData_S; + + std::string JsonIn_S = " { \r\n \"add_source\" \t :\t\r{kjlkjljl"; + EXPECT_STREQ("add_source", BofJsonParser::S_RootName(JsonIn_S).c_str()); + + S_AppParamJson_X.Reset(); + Bof_GetCurrentDirectory(CrtDir); + Path = CrtDir + "../../binaries/bin/data/jsonparser.json"; + + EXPECT_EQ(Bof_ReadFile(Path, JsonData_S), BOF_ERR_NO_ERROR); + + pBofJsonParser_O = new BofJsonParser(JsonData_S); + EXPECT_TRUE(pBofJsonParser_O != nullptr); + Sts_i = pBofJsonParser_O->ToByte(S_OptionJsonCollection, JsonParseResultUltimateCheck, JsonParseError); + EXPECT_EQ(Sts_i, 0); + + // Check S_AppParam_X content + pValue_c = pBofJsonParser_O->GetFirstElementFromOid("MulFtpUserSetting.DeployIpAddress"); + EXPECT_TRUE(pValue_c != nullptr); + pValue_c = pBofJsonParser_O->GetNextElementFromOid(); + EXPECT_TRUE(pValue_c == nullptr); + + pValue_c = pBofJsonParser_O->GetFirstElementFromOid("MulFtpUserSetting.catalog.book.id"); + EXPECT_TRUE(pValue_c != nullptr); + pValue_c = pBofJsonParser_O->GetNextElementFromOid(); + EXPECT_TRUE(pValue_c != nullptr); + + BOF_SAFE_DELETE(pBofJsonParser_O); +} + +TEST(JsonParser_Test, IpSenderDeser) +{ + const char *pValue_c; + int Sts_i; + + BofJsonParser BofJsonParser_O("{\"add_sender\":{\"description\":\"OUT1\",\"device_id\":\"f98f5eaa-cda5-4396-b975-407748ba513b\",\"flow_id\":\"a3fc4d73-6fdc-4221-ae10-e1b6e006ac5c\",\"id\":\"a8a0b68c-0fbd-4b94-ad95-f637d4c4c6a3\",\"label\":\"Player " + "A\",\"manifest_href\":\"http:/bha.txt\",\"tags\":{\"\":[\"1\",\"2\",\"3\"]},\"transport\":\"\",\"version\":\"\"}}"); + + Sts_i = BofJsonParser_O.ToByte(S_IpSenderOptionCollection, JsonParseResultUltimateCheck, JsonParseError); + EXPECT_EQ(Sts_i, 0); + + // Check S_AppParam_X content + pValue_c = BofJsonParser_O.GetFirstElementFromOid("add_sender.device_id"); + EXPECT_TRUE(pValue_c != nullptr); + pValue_c = BofJsonParser_O.GetNextElementFromOid(); + EXPECT_TRUE(pValue_c == nullptr); + + pValue_c = BofJsonParser_O.GetFirstElementFromOid("add_sender.tags.."); + EXPECT_TRUE(pValue_c != nullptr); + pValue_c = BofJsonParser_O.GetNextElementFromOid(); + EXPECT_TRUE(pValue_c != nullptr); +} +TEST(JsonParser_Test, ManifestDeser) +{ + const char *pValue_c; + int Sts_i; + + BofJsonParser BofJsonParser_O("{\"add_manifest\":{\"sdp\":[\"v=0\",\"o=- 0 0 IN IP4 18.52.86.2\",\"s=OUT3\",\"i=Player C\",\"c=IN IP4 33.67.101.2/32\",\"t=0 0\",\"m=video 16386 RTP/AVP 96\",\"a=rtpmap:96 raw/90000\",\"a=fmtp:96 " + "packetization-mode=1\"],\"sender_id\":\"81f4da21-c9ef-4b90-ab03-a4893cae32ed\"}}"); + + Sts_i = BofJsonParser_O.ToByte(S_IpManifestOptionCollection, JsonParseResultUltimateCheck, JsonParseError); + EXPECT_EQ(Sts_i, 0); + + // Check S_AppParam_X content + pValue_c = BofJsonParser_O.GetFirstElementFromOid("add_manifest.sender_id"); + EXPECT_TRUE(pValue_c != nullptr); + pValue_c = BofJsonParser_O.GetNextElementFromOid(); + EXPECT_TRUE(pValue_c == nullptr); + + pValue_c = BofJsonParser_O.GetFirstElementFromOid("add_manifest.sdp."); + EXPECT_TRUE(pValue_c != nullptr); + pValue_c = BofJsonParser_O.GetNextElementFromOid(); + EXPECT_TRUE(pValue_c != nullptr); +} +TEST(JsonParser_Test, ConnectDeser) +{ + const char *pValue_c; + int Sts_i; + + BofJsonParser BofJsonParser_O("{\"connect\":{\"receiver_id\":\"1c513fc7-faa8-4a89-bd1c-56d8b00a1355\",\"sdp\":[\"v=0\",\"o=- 0 0 IN IP4 18.52.86.0\",\"s=OUT1\",\"i=Player A\",\"c=IN IP4 33.67.101.0/32\",\"t=0 0\",\"m=video 16384 RTP/AVP " + "96\",\"a=rtpmap:96 raw/90000\",\"a=fmtp:96 packetization-mode=1\"]}}"); + + Sts_i = BofJsonParser_O.ToByte(S_IpConnectOptionCollection, JsonParseResultUltimateCheck, JsonParseError); + EXPECT_EQ(Sts_i, 0); + + // Check S_AppParam_X content + pValue_c = BofJsonParser_O.GetFirstElementFromOid("connect.receiver_id"); + EXPECT_TRUE(pValue_c != nullptr); + pValue_c = BofJsonParser_O.GetNextElementFromOid(); + EXPECT_TRUE(pValue_c == nullptr); + + pValue_c = BofJsonParser_O.GetFirstElementFromOid("connect.sdp."); + EXPECT_TRUE(pValue_c != nullptr); + pValue_c = BofJsonParser_O.GetNextElementFromOid(); + EXPECT_TRUE(pValue_c != nullptr); +} + +TEST(JsonWriter_Test, Json) +{ + BOFERR Sts_E; + std::string JsonOut_S; + BofJsonWriter BofJsonWriter_O; + BofJsonParser *pBofJsonParser_O; + BofPath CrtDir, Path; + std::string JsonData_S; + + // memset(&S_AppParam_X, 0, sizeof(S_AppParam_X) ); + Bof_GetCurrentDirectory(CrtDir); + Path = CrtDir + "../../binaries/bin/data/jsonparser.json"; + EXPECT_EQ(Bof_ReadFile(Path, JsonData_S), BOF_ERR_NO_ERROR); + + pBofJsonParser_O = new BofJsonParser(JsonData_S); + EXPECT_TRUE(pBofJsonParser_O != nullptr); + Sts_E = pBofJsonParser_O->ToByte(S_OptionJsonCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + + Sts_E = BofJsonWriter_O.FromByte(true, true, S_OptionJsonCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + + Sts_E = BofJsonWriter_O.FromByte(false, true, S_OptionJsonCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + + BOF_SAFE_DELETE(pBofJsonParser_O); +} + +TEST(JsonWriter_Test, IpSenderSer) +{ + BOFERR Sts_E; + std::string JsonOut_S; + std::string JsonIn_S = "{\"add_sender\":{\"description\":\"OUT1\",\"device_id\":\"f98f5eaa-cda5-4396-b975-407748ba513b\",\"flow_id\":\"a3fc4d73-6fdc-4221-ae10-e1b6e006ac5c\",\"id\":\"a8a0b68c-0fbd-4b94-ad95-f637d4c4c6a3\",\"label\":\"Player " + "A\",\"manifest_href\":\"http:/bha.txt\",\"tags\":{\"\":[\"1\",\"2\",\"3\",\"\",\"\",\"\",\"\",\"\"]},\"transport\":\"\",\"version\":\"\"}}\n"; + BofJsonWriter BofJsonWriter; + S_IpSenderParam_X.Reset(); + BofJsonParser BofJsonParser_O(JsonIn_S); + + Sts_E = BofJsonParser_O.ToByte(S_IpSenderOptionCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + + Sts_E = BofJsonWriter.FromByte(true, true, S_IpSenderOptionCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + /* + std::string t="{\"add_sender\":{\"description\":\"OUT1\",\"device_id\":\"f98f5eaa-cda5-4396-b975-407748ba513b\",\"flow_id\":\"a3fc4d73-6fdc-4221-ae10-e1b6e006ac5c\",\"id\":\"a8a0b68c-0fbd-4b94-ad95-f637d4c4c6a3\",\"label\":\"Player + A\",\"manifest_href\":\"http:/bha.txt\",\"tags\":{\"\":[{\"\":\"1\"},{\"\":\"2\"},{\"\":\"3\"},{\"\":\"\"},{\"\":\"\"},{\"\":\"\"},{\"\":\"\"},{\"\":\"\"},{\"\":\"\"},{\"\":\"\"},{\"\":\"\"},{\"\":\"\"},{\"\":\"\"},{\"\":\"\"},{\"\":\"\"},{\"\":\"\"}]},\"transport\":\"\",\"version\":\"\"}}\n"; + const char *p = JsonOut_S.c_str(); + const char *q = t.c_str(); + while (*p == *q) { p++; q++; } + */ + Sts_E = BofJsonWriter.FromByte(false, true, S_IpSenderOptionCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); +} + +TEST(JsonWriter_Test, ManifestSer) +{ + BOFERR Sts_E; + std::string JsonOut_S; + std::string JsonIn_S = "{\"add_manifest\":{\"sdp\":[\"v=0\",\"o=- 0 0 IN IP4 18.52.86.2\",\"s=OUT3\",\"i=Player C\",\"c=IN IP4 33.67.101.2/32\",\"t=0 0\",\"m=video 16386 RTP/AVP 96\",\"a=rtpmap:96 raw/90000\",\"a=fmtp:96 " + "packetization-mode=1\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"],\"sender_id\":\"81f4da21-c9ef-4b90-ab03-a4893cae32ed\"}}\n"; + + BofJsonWriter BofJsonWriter; + S_IpManifestParam_X.Reset(); + BofJsonParser BofJsonParser_O(JsonIn_S); + + Sts_E = BofJsonParser_O.ToByte(S_IpManifestOptionCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + + Sts_E = BofJsonWriter.FromByte(true, true, S_IpManifestOptionCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + + Sts_E = BofJsonWriter.FromByte(false, true, S_IpManifestOptionCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); +} + +TEST(JsonWriter_Test, ConnectSer) +{ + BOFERR Sts_E; + std::string JsonOut_S; + std::string JsonIn_S = "{\"connect\":{\"receiver_id\":\"1c513fc7-faa8-4a89-bd1c-56d8b00a1355\",\"sdp\":[\"v=0\",\"o=- 0 0 IN IP4 18.52.86.0\",\"s=OUT1\",\"i=Player A\",\"c=IN IP4 33.67.101.0/32\",\"t=0 0\",\"m=video 16384 RTP/AVP 96\",\"a=rtpmap:96 " + "raw/90000\",\"a=fmtp:96 packetization-mode=1\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]}}\n"; + + BofJsonWriter BofJsonWriter; + S_IpConnectParam_X.Reset(); + BofJsonParser BofJsonParser_O(JsonIn_S); + + JsonOut_S = ""; + Sts_E = BofJsonWriter.FromByte(true, true, S_IpConnectOptionCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), "{\"connect\":{\"receiver_id\":\"\"}}\n"); + + Sts_E = BofJsonParser_O.ToByte(S_IpConnectOptionCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + + JsonOut_S = ""; + Sts_E = BofJsonWriter.FromByte(true, true, S_IpConnectOptionCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + + /* + std::string t = "{\"connect\":{\"receiver_id\":\"1c513fc7-faa8-4a89-bd1c-56d8b00a1355\",\"sdp\":[{\"\":\"v=0\"},{\"\":\"o=- 0 0 IN IP4 18.52.86.0\"},{\"\":\"s=OUT1\"},{\"\":\"i=Player A\"},{\"\":\"c=IN IP4 33.67.101.0/32\"},{\"\":\"t=0 + 0\"},{\"\":\"m=video 16384 RTP/AVP 96\"},{\"\":\"a=rtpmap:96 raw/90000\"},{\"\":\"a=fmtp:96 packetization-mode=1\"}]}}\n"; const char *p = JsonOut_S.c_str(); const char *q = t.c_str(); while (*p == *q) { p++; q++; } + */ + + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + + Sts_E = BofJsonWriter.FromByte(false, true, S_IpConnectOptionCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); +} + +TEST(JsonWriter_Test, IpSwitcherSerDeser) +{ + BOFERR Sts_E; + std::string JsonIn_S, JsonOut_S; + BofJsonWriter JsonWriter; + // S_AddDevice_X + S_AddDevice_X.Reset(); + JsonIn_S = "{\"add_device\":{\"id\":\"a8500668-9218-4063-ba36-9b4900b82e67\",\"label\":\"\",\"node_id\":\"00000000-0000-0000-0000-000000000000\",\"receivers\":[],\"senders\":[],\"type\":\"\",\"version\":\"\"}}\n"; + BofJsonParser JsonParser(JsonIn_S); + // goto l; + + EXPECT_TRUE(JsonParser.IsValid()); + EXPECT_STREQ(JsonParser.RootName().c_str(), "add_device"); + EXPECT_STREQ(JsonParser.RootName().c_str(), BofJsonParser::S_RootName(JsonIn_S).c_str()); + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_AddDeviceSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), "{\"add_device\":{\"id\":\"00000000-0000-0000-0000-000000000000\",\"label\":\"\",\"node_id\":\"00000000-0000-0000-0000-000000000000\",\"type\":\"\",\"version\":\"\"}}\n"); + + Sts_E = JsonParser.ToByte(S_AddDeviceSchemaCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + // printf("Id %s\n", S_AddDevice_X.Id.ToString(true).c_str()); + // printf("Node %s\n", S_AddDevice_X.NodeId.ToString(true).c_str()); + + //\"receivers\":[],\"senders\":[], are null + JsonIn_S = "{\"add_device\":{\"id\":\"a8500668-9218-4063-ba36-9b4900b82e67\",\"label\":\"\",\"node_id\":\"00000000-0000-0000-0000-000000000000\",\"type\":\"\",\"version\":\"\"}}\n"; + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_AddDeviceSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + + // S_AddSource_X + S_AddSource_X.Reset(); + JsonIn_S = "{\"add_source\":{\"caps\":{},\"description\":\"OUT1\",\"device_id\":\"a8500668-9218-4063-ba36-9b4900b82e67\",\"format\":\"\",\"id\":\"895085f3-76a1-4f09-b3dd-2aabeb230cd8\",\"label\":\"Player " + "A\",\"parents\":[],\"tags\":{\"\":[]},\"version\":\"\"}}\n"; + JsonParser = JsonIn_S; + + EXPECT_TRUE(JsonParser.IsValid()); + EXPECT_STREQ(JsonParser.RootName().c_str(), "add_source"); + EXPECT_STREQ(JsonParser.RootName().c_str(), BofJsonParser::S_RootName(JsonIn_S).c_str()); + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_AddSourceSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), "{\"add_source\":{\"caps\":\"\",\"description\":\"\",\"device_id\":\"00000000-0000-0000-0000-000000000000\",\"format\":\"\",\"id\":\"00000000-0000-0000-0000-000000000000\",\"label\":\"\",\"version\":\"\"}}\n"); + + Sts_E = JsonParser.ToByte(S_AddSourceSchemaCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + // printf("Id %s\n", S_AddSource_X.Id.ToString(true).c_str()); + // printf("Device %s\n", S_AddSource_X.DeviceId.ToString(true).c_str()); + + // caps:{} -> caps:"" + //\"parents\":[],\"tags\":{\"\":[]} are null + JsonIn_S = "{\"add_source\":{\"caps\":\"\",\"description\":\"OUT1\",\"device_id\":\"a8500668-9218-4063-ba36-9b4900b82e67\",\"format\":\"\",\"id\":\"895085f3-76a1-4f09-b3dd-2aabeb230cd8\",\"label\":\"Player A\",\"version\":\"\"}}\n"; + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_AddSourceSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + + // S_AddFlow_X + S_AddFlow_X.Reset(); + JsonIn_S = "{\"add_flow\":{\"description\":\"OUT1\",\"format\":\"\",\"id\":\"40b94c9d-9bf1-4721-95ae-4316b4e080ea\",\"label\":\"Player A\",\"parents\":[],\"source_id\":\"895085f3-76a1-4f09-b3dd-2aabeb230cd8\",\"tags\":{\"\":[]},\"version\":\"\"}}\n"; + JsonParser = JsonIn_S; + + EXPECT_TRUE(JsonParser.IsValid()); + EXPECT_STREQ(JsonParser.RootName().c_str(), "add_flow"); + EXPECT_STREQ(JsonParser.RootName().c_str(), BofJsonParser::S_RootName(JsonIn_S).c_str()); + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_AddFlowSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), "{\"add_flow\":{\"description\":\"\",\"format\":\"\",\"id\":\"00000000-0000-0000-0000-000000000000\",\"label\":\"\",\"source_id\":\"00000000-0000-0000-0000-000000000000\",\"version\":\"\"}}\n"); + + Sts_E = JsonParser.ToByte(S_AddFlowSchemaCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + // printf("Id %s\n", S_AddFlow_X.Id.ToString(true).c_str()); + // printf("SourceId %s\n", S_AddFlow_X.SourceId.ToString(true).c_str()); + + //\"parents\":[],\"tags\":{\"\":[]} are null + JsonIn_S = "{\"add_flow\":{\"description\":\"OUT1\",\"format\":\"\",\"id\":\"40b94c9d-9bf1-4721-95ae-4316b4e080ea\",\"label\":\"Player A\",\"source_id\":\"895085f3-76a1-4f09-b3dd-2aabeb230cd8\",\"version\":\"\"}}\n"; + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_AddFlowSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + + // S_AddSender_X + S_AddSender_X.Reset(); + JsonIn_S = "{\"add_sender\":{\"description\":\"OUT1\",\"device_id\":\"a8500668-9218-4063-ba36-9b4900b82e67\",\"flow_id\":\"40b94c9d-9bf1-4721-95ae-4316b4e080ea\",\"id\":\"edbe7239-8659-46c9-a4f7-85b46a2efc73\",\"label\":\"Player " + "A\",\"manifest_href\":\"\",\"tags\":{\"\":[]},\"transport\":\"\",\"version\":\"\"}}\n"; + JsonParser = JsonIn_S; + + EXPECT_TRUE(JsonParser.IsValid()); + EXPECT_STREQ(JsonParser.RootName().c_str(), "add_sender"); + EXPECT_STREQ(JsonParser.RootName().c_str(), BofJsonParser::S_RootName(JsonIn_S).c_str()); + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_AddSenderSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), "{\"add_sender\":{\"description\":\"\",\"device_id\":\"00000000-0000-0000-0000-000000000000\",\"flow_id\":\"00000000-0000-0000-0000-000000000000\",\"id\":\"00000000-0000-0000-0000-000000000000\",\"label\":\"\",\"manifest_" + "href\":\"\",\"transport\":\"\",\"version\":\"\"}}\n"); + + Sts_E = JsonParser.ToByte(S_AddSenderSchemaCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + // printf("Id %s\n", S_AddFlow_X.Id.ToString(true).c_str()); + // printf("SourceId %s\n", S_AddFlow_X.SourceId.ToString(true).c_str()); + + //"tags" is null + JsonIn_S = "{\"add_sender\":{\"description\":\"OUT1\",\"device_id\":\"a8500668-9218-4063-ba36-9b4900b82e67\",\"flow_id\":\"40b94c9d-9bf1-4721-95ae-4316b4e080ea\",\"id\":\"edbe7239-8659-46c9-a4f7-85b46a2efc73\",\"label\":\"Player " + "A\",\"manifest_href\":\"\",\"transport\":\"\",\"version\":\"\"}}\n"; + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_AddSenderSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + + // S_AddReceiver_X + S_AddReceiver_X.Reset(); + JsonIn_S = "{\"add_receiver\":{\"caps\":{},\"description\":\"IN1\",\"device_id\":\"a8500668-9218-4063-ba36-9b4900b82e67\",\"format\":\"\",\"id\":\"998a20b2-2a8a-42c3-a527-46d1de96a9df\",\"label\":\"Recorder " + "A\",\"subscription\":{\"sender_id\":\"00000000-0000-0000-0000-000000000000\"},\"tags\":{\"\":[]},\"transport\":\"\",\"version\":\"\"}}\n"; + JsonParser = JsonIn_S; + + EXPECT_TRUE(JsonParser.IsValid()); + EXPECT_STREQ(JsonParser.RootName().c_str(), "add_receiver"); + EXPECT_STREQ(JsonParser.RootName().c_str(), BofJsonParser::S_RootName(JsonIn_S).c_str()); + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_AddReceiverSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), "{\"add_receiver\":{\"caps\":\"\",\"description\":\"\",\"device_id\":\"00000000-0000-0000-0000-000000000000\",\"format\":\"\",\"id\":\"00000000-0000-0000-0000-000000000000\",\"label\":\"\",\"subscription\":{\"sender_id\":" + "\"00000000-0000-0000-0000-000000000000\"},\"transport\":\"\",\"version\":\"\"}}\n"); + + Sts_E = JsonParser.ToByte(S_AddReceiverSchemaCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + // printf("Id %s\n", S_AddFlow_X.Id.ToString(true).c_str()); + // printf("SourceId %s\n", S_AddFlow_X.SourceId.ToString(true).c_str()); + + // caps:{} -> caps:"" + //\"tags\":{\"\":[]} is null + JsonIn_S = "{\"add_receiver\":{\"caps\":\"\",\"description\":\"IN1\",\"device_id\":\"a8500668-9218-4063-ba36-9b4900b82e67\",\"format\":\"\",\"id\":\"998a20b2-2a8a-42c3-a527-46d1de96a9df\",\"label\":\"Recorder " + "A\",\"subscription\":{\"sender_id\":\"00000000-0000-0000-0000-000000000000\"},\"transport\":\"\",\"version\":\"\"}}\n"; + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_AddReceiverSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + + // S_AddManifest_X + + S_AddManifest_X.Reset(); + JsonIn_S = "{\"add_manifest\":{\"sdp\":[\"v=0\",\"o=- 0 0 IN IP4 18.52.86.0\",\"s=OUT1\",\"i=Player A\",\"c=IN IP4 33.67.101.0/32\",\"t=0 0\",\"m=video 16384 RTP/AVP 96\",\"a=rtpmap:96 raw/90000\",\"a=fmtp:96 " + "packetization-mode=1\"],\"sender_id\":\"edbe7239-8659-46c9-a4f7-85b46a2efc73\"}}\n"; + JsonParser = JsonIn_S; + + EXPECT_TRUE(JsonParser.IsValid()); + EXPECT_STREQ(JsonParser.RootName().c_str(), "add_manifest"); + EXPECT_STREQ(JsonParser.RootName().c_str(), BofJsonParser::S_RootName(JsonIn_S).c_str()); + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_AddManifestSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), "{\"add_manifest\":{\"sender_id\":\"00000000-0000-0000-0000-000000000000\"}}\n"); + + Sts_E = JsonParser.ToByte(S_AddManifestSchemaCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + // printf("SenderId %s\n", S_AddManifest_X.SenderId.ToString(true).c_str()); + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_AddManifestSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + + // S_CmdConnect_X + S_CmdConnect_X.Reset(); + JsonIn_S = "{\"connect\":{\"receiver_id\":\"1c513fc7-faa8-4a89-bd1c-56d8b00a1355\",\"sdp\":[\"v=0\",\"o=- 0 0 IN IP4 18.52.86.0\",\"s=OUT1\",\"i=Player A\",\"c=IN IP4 33.67.101.0/32\",\"t=0 0\",\"m=video 16384 RTP/AVP 96\",\"a=rtpmap:96 " + "raw/90000\",\"a=fmtp:96 packetization-mode=1\"]}}\n"; + JsonParser = JsonIn_S; + + EXPECT_TRUE(JsonParser.IsValid()); + EXPECT_STREQ(JsonParser.RootName().c_str(), "connect"); + EXPECT_STREQ(JsonParser.RootName().c_str(), BofJsonParser::S_RootName(JsonIn_S).c_str()); + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_CmdConnectSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), "{\"connect\":{\"receiver_id\":\"00000000-0000-0000-0000-000000000000\"}}\n"); + + Sts_E = JsonParser.ToByte(S_CmdConnectSchemaCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + // printf("ReceiverId %s\n", S_CmdConnect_X.ReceiverId.ToString(true).c_str()); + + // caps:{} -> caps:"" + //\"tags\":{\"\":[]} is null + JsonIn_S = "{\"connect\":{\"receiver_id\":\"1c513fc7-faa8-4a89-bd1c-56d8b00a1355\",\"sdp\":[\"v=0\",\"o=- 0 0 IN IP4 18.52.86.0\",\"s=OUT1\",\"i=Player A\",\"c=IN IP4 33.67.101.0/32\",\"t=0 0\",\"m=video 16384 RTP/AVP 96\",\"a=rtpmap:96 " + "raw/90000\",\"a=fmtp:96 packetization-mode=1\"]}}\n"; + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_CmdConnectSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + + // S_CmdStatusReceiver_X + S_CmdStatusReceiver_X.Reset(); + JsonIn_S = "{\"status_receivers\":{\"arg\":\"\"}}\n"; + JsonParser = JsonIn_S; + + EXPECT_TRUE(JsonParser.IsValid()); + EXPECT_STREQ(JsonParser.RootName().c_str(), "status_receivers"); + EXPECT_STREQ(JsonParser.RootName().c_str(), BofJsonParser::S_RootName(JsonIn_S).c_str()); + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_CmdStatusReceiverSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + + Sts_E = JsonParser.ToByte(S_CmdStatusReceiverSchemaCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_CmdStatusReceiverSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + + // S_ReplyStatusReceiver_X + S_ReplyStatusReceiver_X.Reset(); + + JsonIn_S = "{\"status_receivers\":[{\"id\":\"1c513fc7-faa8-4a89-bd1c-56d8b00a1355\",\"impaired\":\"true\",\"ip\":\"18.52.86.0\",\"present\":\"both\",\"state\":\"AB\"},{\"id\":\"1c513fc7-faa8-4a89-bd1c-56d8b00adead\",\"impaired\":\"false\",\"ip\":\"18." + "52.86.2\",\"present\":\"primary\",\"state\":\"A\"}]}\n"; + JsonParser = JsonIn_S; + + EXPECT_TRUE(JsonParser.IsValid()); + EXPECT_STREQ(JsonParser.RootName().c_str(), "status_receivers"); + EXPECT_STREQ(JsonParser.RootName().c_str(), BofJsonParser::S_RootName(JsonIn_S).c_str()); + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_ReplyStatusReceiverSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), "{}\n"); + + Sts_E = JsonParser.ToByte(S_ReplyStatusReceiverSchemaCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + for (auto Item : S_ReplyStatusReceiver_X.IdCollection) + { + // printf("Sts Rcv Id %s\n", Item.ToString(true).c_str()); + } + for (auto Item : S_ReplyStatusReceiver_X.IpCollection) + { + // printf("Sts Rcv Ip %s\n", Item.ToString(true, false, false, true).c_str()); + } + for (auto Item : S_ReplyStatusReceiver_X.PresentCollection) + { + // printf("Sts Rcv Present %s\n", Item.c_str()); + } + for (auto Item : S_ReplyStatusReceiver_X.ImpairedCollection) + { + // printf("Sts Rcv Impaired %s\n", Item ? "True" : "False"); + } + for (auto Item : S_ReplyStatusReceiver_X.StateCollection) + { + // printf("Sts Rcv State %s\n", Item.c_str()); + } + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_ReplyStatusReceiverSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + + // S_CmdStatusSender_X + S_CmdStatusReceiver_X.Reset(); + JsonIn_S = "{\"status_senders\":{\"arg\":\"\"}}\n"; + + JsonParser = JsonIn_S; + + EXPECT_TRUE(JsonParser.IsValid()); + EXPECT_STREQ(JsonParser.RootName().c_str(), "status_senders"); + EXPECT_STREQ(JsonParser.RootName().c_str(), BofJsonParser::S_RootName(JsonIn_S).c_str()); + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_CmdStatusSenderSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + + Sts_E = JsonParser.ToByte(S_CmdStatusSenderSchemaCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_CmdStatusSenderSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); + + // S_ReplyStatusSender_X + // l: + S_ReplyStatusSender_X.Reset(); + + JsonIn_S = "{\"status_senders\":[{\"id\":\"1c513fc7-faa8-4a89-bd1c-56d8b00a1356\",\"impaired\":\"true\",\"ip\":\"18.52.86.0:1\",\"present\":\"lost\",\"state\":\"B\"},{\"id\":\"1c513fc7-faa8-4a89-bd1c-56d8b00abeef\",\"impaired\":\"true\",\"ip\":\"18.52." + "86.222:235\",\"present\":\"primary\",\"state\":\"XA\"}]}\n"; + JsonParser = JsonIn_S; + + EXPECT_TRUE(JsonParser.IsValid()); + EXPECT_STREQ(JsonParser.RootName().c_str(), "status_senders"); + EXPECT_STREQ(JsonParser.RootName().c_str(), BofJsonParser::S_RootName(JsonIn_S).c_str()); + + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_ReplyStatusSenderSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), "{}\n"); + + Sts_E = JsonParser.ToByte(S_ReplyStatusSenderSchemaCollection, JsonWriteResultUltimateCheck, JsonWriteError); + EXPECT_EQ(Sts_E, 0); + for (auto Item : S_ReplyStatusSender_X.IdCollection) + { + // printf("Sts Snd Id %s\n", Item.ToString(true).c_str()); + } + for (auto Item : S_ReplyStatusSender_X.IpCollection) + { + // printf("Sts Snd Ip %s\n", Item.ToString(true, false, false, true).c_str()); + } + for (auto Item : S_ReplyStatusSender_X.PresentCollection) + { + // printf("Sts Snd Present %s\n", Item.c_str()); + } + for (auto Item : S_ReplyStatusSender_X.ImpairedCollection) + { + // printf("Sts Snd Impaired %s\n", Item ? "True" : "False"); + } + for (auto Item : S_ReplyStatusSender_X.StateCollection) + { + // printf("Sts Snd State %s\n", Item.c_str()); + } + JsonOut_S = ""; + Sts_E = JsonWriter.FromByte(true, true, S_ReplyStatusSenderSchemaCollection, JsonOut_S); + EXPECT_EQ(Sts_E, 0); + EXPECT_STREQ(JsonOut_S.c_str(), JsonIn_S.c_str()); +} + +#if 0 +TEST(JsonParser_Test, JsonCfg) +{ + BofJsonParser *pBofJsonParser_O; + int Sts_i; + BofPath CrtDir, Path; + std::string JsonData_S, JsonOut_S; + BofJsonWriter BofJsonWriter_O; + std::string Cfg_S; + /* + //printf("sz MMGW_API_STATE %d MMGW_BOARD_STATE %d MMGW_BOARD_CHANNEL %d BOF_SOCKET_ADDRESS %d\n",sizeof(MMGW_API_STATE), sizeof(MMGW_BOARD_STATE),sizeof(MMGW_BOARD_CHANNEL),sizeof(BOF_SOCKET_ADDRESS)); + //printf("ONE O %p 1 %p 2 %p\n", &S_MmgwApiState_X.pBoardState_X[0].pHrInput_X[0].IoActive_B,&S_MmgwApiState_X.pBoardState_X[0].pHrInput_X[1].IoActive_B, &S_MmgwApiState_X.pBoardState_X[0].pHrInput_X[2].IoActive_B,&S_MmgwApiState_X.pBoardState_X[0].pHrInput_X[3].IoActive_B); + //printf("TWO O %p 1 %p 2 %p\n", &S_MmgwApiState_X.pBoardState_X[1].pHrInput_X[0].IoActive_B,&S_MmgwApiState_X.pBoardState_X[1].pHrInput_X[1].IoActive_B, &S_MmgwApiState_X.pBoardState_X[1].pHrInput_X[2].IoActive_B,&S_MmgwApiState_X.pBoardState_X[1].pHrInput_X[3].IoActive_B); + */ + S_MmgwApiState_X.Reset(); + Bof_GetCurrentDirectory(CrtDir); + Path = CrtDir + "jsonparser.json"; + EXPECT_EQ(Bof_ReadFile(Path, JsonData_S), BOF_ERR_NO_ERROR); + + pBofJsonParser_O = new BofJsonParser(JsonData_S); + EXPECT_TRUE(pBofJsonParser_O != nullptr); + Sts_i = pBofJsonParser_O->ToByte(S_CfgJsonCollection, JsonParseResultUltimateCheck, JsonParseError); + EXPECT_EQ(Sts_i, 0); + + DisplayConfig(); + + + // EXPECT_EQ(BofJsonWriter_O.FromByte(false, S_CfgJsonCollection, JsonOut_S), BOF_ERR_NO_ERROR); + //printf("%s\n",JsonOut_S.c_str()); + + BOF_SAFE_DELETE(pBofJsonParser_O); +} +#endif \ No newline at end of file