Base frontend module
- Naming style migrated to camel-case - P7lib logger sources added - Vcpkg manifest, CMake presets and build moved to root - SDL2, Vulkan and RmlUi dependencies added - Logger LOG macro added - Logger configuration - SDL2 window configuration - Vulkan configuration - RmlUi configuration - SDL event loop
This commit is contained in:
parent
06ecfe88c1
commit
32f4597c4d
12
.vscode/launch.json
vendored
Normal file
12
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"type": "cmake",
|
||||
"request": "launch",
|
||||
"name": "Debug portfile(s)",
|
||||
"cmakeDebugType": "external",
|
||||
"pipeName": "\\\\.\\pipe\\vcpkg_ext_portfile_dbg",
|
||||
"preLaunchTask": "Debug vcpkg commands"
|
||||
}
|
||||
]
|
||||
}
|
||||
15
CMakeLists.txt
Normal file
15
CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
cmake_minimum_required (VERSION 3.8)
|
||||
|
||||
if (POLICY CMP0141)
|
||||
cmake_policy(SET CMP0141 NEW)
|
||||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
|
||||
endif()
|
||||
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
project ("EtrediaEmpires")
|
||||
|
||||
add_subdirectory ("p7lib")
|
||||
add_subdirectory ("ECSAPI")
|
||||
add_subdirectory ("frontend")
|
||||
@ -1,12 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "DEBUG",
|
||||
"inherits": "x64-debug",
|
||||
"environment": {
|
||||
"VCPKG_ROOT": "E:/vcpkg/vcpkg"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -13,15 +13,15 @@ find_package(EnTT CONFIG REQUIRED)
|
||||
|
||||
# Link library
|
||||
|
||||
add_library(ECS ${HEADERS} ${SOURCES})
|
||||
add_library(ECS::ECS ALIAS ECS)
|
||||
add_library(${PROJECT_NAME} ${HEADERS} ${SOURCES})
|
||||
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
|
||||
|
||||
target_link_libraries(ECS PUBLIC Economy::Economy)
|
||||
target_link_libraries(ECS PRIVATE EnTT::EnTT)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC Economy::Economy)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE EnTT::EnTT)
|
||||
|
||||
target_include_directories(ECS PUBLIC include/)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC include/)
|
||||
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||
set_property(TARGET ECS PROPERTY CXX_STANDARD 20)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
|
||||
endif()
|
||||
@ -5,10 +5,10 @@
|
||||
namespace ee_ecs
|
||||
{
|
||||
|
||||
void init(init_configuration config);
|
||||
void init(InitConfiguration config);
|
||||
void start();
|
||||
|
||||
template<typename T>
|
||||
const std::vector<enterprise_info> get_all_enterprises();
|
||||
//const enterprise_info get_enterprise(uint32_t id);
|
||||
const std::vector<EnterpriseInfo> getAllEnterprises();
|
||||
//const EnterpriseInfo getEnterprise(uint32_t id);
|
||||
}
|
||||
@ -6,19 +6,19 @@
|
||||
namespace ee_ecs
|
||||
{
|
||||
|
||||
struct init_configuration
|
||||
struct InitConfiguration
|
||||
{
|
||||
std::unordered_map<int16_t, ee_economy::container> states;
|
||||
std::unordered_map<int16_t, ee_economy::Container> states;
|
||||
};
|
||||
|
||||
struct enterprise_info
|
||||
struct EnterpriseInfo
|
||||
{
|
||||
const ee_economy::enterprise* info = nullptr;
|
||||
const ee_economy::container* storage = nullptr;
|
||||
const ee_economy::Enterprise* info = nullptr;
|
||||
const ee_economy::Container* storage = nullptr;
|
||||
std::variant<
|
||||
const ee_economy::miner*,
|
||||
const ee_economy::deliverer*
|
||||
> special_info;
|
||||
const ee_economy::Miner*,
|
||||
const ee_economy::Deliverer*
|
||||
> specialInfo;
|
||||
};
|
||||
|
||||
}
|
||||
@ -7,28 +7,27 @@
|
||||
|
||||
namespace ee_ecs
|
||||
{
|
||||
class world
|
||||
class World
|
||||
{
|
||||
|
||||
private:
|
||||
entt::registry registry;
|
||||
std::unordered_map<int16_t, entt::entity> states_table;
|
||||
std::unordered_map<int16_t, entt::entity> statesTable;
|
||||
|
||||
void update_enterprises();
|
||||
void updateEnterprises();
|
||||
|
||||
public:
|
||||
// Run every registered system
|
||||
void update();
|
||||
|
||||
entt::entity register_state(const int16_t id, const ee_economy::container &resources);
|
||||
entt::entity registerState(const int16_t id, const ee_economy::Container &resources);
|
||||
|
||||
entt::entity spawn_enterprise(
|
||||
const bool is_building,
|
||||
entt::entity spawnEnterprise(
|
||||
const bool isBuilding,
|
||||
const ee_economy::ACTION_TYPE action,
|
||||
const entt::entity state,
|
||||
const ee_economy::enterprise_defaults &defaults
|
||||
const ee_economy::EnterpriseDefaults &defaults
|
||||
);
|
||||
|
||||
entt::registry& get_registry();
|
||||
entt::registry& getRegistry();
|
||||
};
|
||||
}
|
||||
@ -2,13 +2,13 @@
|
||||
#include <ee_ecs/ecs.hpp>
|
||||
|
||||
|
||||
static ee_ecs::world world_instance;
|
||||
static ee_ecs::World worldInstance;
|
||||
|
||||
void ee_ecs::init(ee_ecs::init_configuration config)
|
||||
void ee_ecs::init(ee_ecs::InitConfiguration config)
|
||||
{
|
||||
for (auto& [id, container]: config.states)
|
||||
{
|
||||
world_instance.register_state(id, container);
|
||||
worldInstance.registerState(id, container);
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,24 +18,24 @@ void ee_ecs::start()
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const std::vector<ee_ecs::enterprise_info> ee_ecs::get_all_enterprises()
|
||||
const std::vector<ee_ecs::EnterpriseInfo> ee_ecs::getAllEnterprises()
|
||||
{
|
||||
std::vector<enterprise_info> result;
|
||||
std::vector<EnterpriseInfo> result;
|
||||
//TODO: REPLACE VIEWS WITH GROUPS!
|
||||
auto enterprises = world_instance.get_registry().group<>(entt::get<
|
||||
ee_economy::enterprise,
|
||||
ee_economy::container,
|
||||
auto enterprises = worldInstance.getRegistry().group<>(entt::get<
|
||||
ee_economy::Enterprise,
|
||||
ee_economy::Container,
|
||||
T
|
||||
>);
|
||||
result.reserve(enterprises.size_hint());
|
||||
|
||||
for (auto [entity, enterprise, container, action]: enterprises.each())
|
||||
{
|
||||
enterprise_info eninfo;
|
||||
EnterpriseInfo eninfo;
|
||||
eninfo.info = &enterprise;
|
||||
|
||||
eninfo.storage = &container;
|
||||
eninfo.special_info = &action;
|
||||
eninfo.specialInfo = &action;
|
||||
|
||||
result.push_back(eninfo);
|
||||
}
|
||||
|
||||
@ -2,61 +2,61 @@
|
||||
#include <ee_ecs/ecs.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
void ee_ecs::world::update_enterprises()
|
||||
void ee_ecs::World::updateEnterprises()
|
||||
{
|
||||
ee_economy::enterprise_routine(this->registry);
|
||||
ee_economy::enterpriseRoutine(this->registry);
|
||||
|
||||
ee_economy::mining(this->registry);
|
||||
ee_economy::delivering(this->registry);
|
||||
}
|
||||
|
||||
void ee_ecs::world::update()
|
||||
void ee_ecs::World::update()
|
||||
{
|
||||
this->update_enterprises();
|
||||
this->updateEnterprises();
|
||||
}
|
||||
|
||||
entt::entity ee_ecs::world::register_state(const int16_t id, const ee_economy::container &resources)
|
||||
entt::entity ee_ecs::World::registerState(const int16_t id, const ee_economy::Container &resources)
|
||||
{
|
||||
if (this->states_table.contains(id))
|
||||
if (this->statesTable.contains(id))
|
||||
throw std::invalid_argument("State with this Id is already registered");
|
||||
|
||||
entt::entity entity = this->registry.create();
|
||||
|
||||
this->registry.emplace<ee_economy::state>(entity, id);
|
||||
this->registry.emplace<ee_economy::container>(
|
||||
this->registry.emplace<ee_economy::State>(entity, id);
|
||||
this->registry.emplace<ee_economy::Container>(
|
||||
entity,
|
||||
resources.capacity,
|
||||
resources.total,
|
||||
resources.content
|
||||
);
|
||||
|
||||
this->states_table[id] = entity;
|
||||
this->statesTable[id] = entity;
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
entt::entity ee_ecs::world::spawn_enterprise(
|
||||
const bool is_building,
|
||||
entt::entity ee_ecs::World::spawnEnterprise(
|
||||
const bool isBuilding,
|
||||
const ee_economy::ACTION_TYPE action,
|
||||
const entt::entity state,
|
||||
const ee_economy::enterprise_defaults &defaults
|
||||
const ee_economy::EnterpriseDefaults &defaults
|
||||
)
|
||||
{
|
||||
entt::entity entity = this->registry.create();
|
||||
|
||||
this->registry.emplace<ee_economy::enterprise>(
|
||||
this->registry.emplace<ee_economy::Enterprise>(
|
||||
entity,
|
||||
is_building,
|
||||
isBuilding,
|
||||
state,
|
||||
action,
|
||||
|
||||
defaults.base_efficiency * defaults.factor_efficiency,
|
||||
defaults.baseEfficiency * defaults.factorEfficiency,
|
||||
|
||||
defaults.base_efficiency,
|
||||
defaults.factor_efficiency
|
||||
defaults.baseEfficiency,
|
||||
defaults.factorEfficiency
|
||||
);
|
||||
|
||||
this->registry.emplace<ee_economy::container>(
|
||||
this->registry.emplace<ee_economy::Container>(
|
||||
entity,
|
||||
defaults.container.capacity,
|
||||
defaults.container.total,
|
||||
@ -67,13 +67,13 @@ entt::entity ee_ecs::world::spawn_enterprise(
|
||||
{
|
||||
case ee_economy::ACTION_TYPE::MINING:
|
||||
{
|
||||
this->registry.emplace<ee_economy::miner>(entity, defaults.resource_target);
|
||||
this->registry.emplace<ee_economy::Miner>(entity, defaults.resourceTarget);
|
||||
break;
|
||||
}
|
||||
|
||||
case ee_economy::ACTION_TYPE::DELIVERY:
|
||||
{
|
||||
this->registry.emplace<ee_economy::deliverer>(entity, defaults.resource_target);
|
||||
this->registry.emplace<ee_economy::Deliverer>(entity, defaults.resourceTarget);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -84,4 +84,4 @@ entt::entity ee_ecs::world::spawn_enterprise(
|
||||
return entity;
|
||||
}
|
||||
|
||||
entt::registry& ee_ecs::world::get_registry() {return this->registry;}
|
||||
entt::registry& ee_ecs::World::getRegistry() {return this->registry;}
|
||||
@ -1,3 +1,5 @@
|
||||
project(ecs_tests)
|
||||
|
||||
# List sources
|
||||
|
||||
set(SOURCES "test_conf.hpp" "main.cpp" "world.cpp" "benchmark.cpp")
|
||||
@ -10,14 +12,14 @@ find_package(GTest CONFIG REQUIRED)
|
||||
|
||||
include(GoogleTest)
|
||||
|
||||
add_executable(ecs_tests ${SOURCES})
|
||||
target_link_libraries(ecs_tests PRIVATE GTest::gtest_main)
|
||||
target_link_libraries(ecs_tests PRIVATE ECS::ECS)
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE GTest::gtest_main)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ECS::ECS)
|
||||
|
||||
# Test
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||
set_property(TARGET ecs_tests PROPERTY CXX_STANDARD 20)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
|
||||
endif()
|
||||
|
||||
gtest_discover_tests(ecs_tests)
|
||||
gtest_discover_tests(${PROJECT_NAME})
|
||||
@ -17,7 +17,7 @@ private:
|
||||
};
|
||||
|
||||
template<typename Func, typename... Args>
|
||||
void generic_with(Func func) {
|
||||
void genericWith(Func func) {
|
||||
timer timer;
|
||||
func();
|
||||
timer.elapsed();
|
||||
@ -25,7 +25,7 @@ void generic_with(Func func) {
|
||||
|
||||
TEST_F(WorldBenchmark, UpdateSystems)
|
||||
{
|
||||
generic_with([&]() {
|
||||
genericWith([&]() {
|
||||
world.update();
|
||||
});
|
||||
}
|
||||
@ -5,27 +5,27 @@
|
||||
|
||||
struct WorldBenchmark : testing::Test
|
||||
{
|
||||
ee_ecs::world world;
|
||||
ee_ecs::World world;
|
||||
|
||||
void SetUp()
|
||||
{
|
||||
for (int16_t i = 0; i < 1000; i++)
|
||||
{
|
||||
ee_economy::container resources = {.capacity = 100.0};
|
||||
ee_economy::Container resources = {.capacity = 100.0};
|
||||
resources.add(ee_economy::RESOURCE_TYPE::COAL, 100.0);
|
||||
entt::entity state = world.register_state(i, resources);
|
||||
entt::entity state = world.registerState(i, resources);
|
||||
|
||||
ee_economy::enterprise_defaults miner = {
|
||||
ee_economy::EnterpriseDefaults miner = {
|
||||
.container = {.capacity = 100.0},
|
||||
.resource_target = ee_economy::RESOURCE_TYPE::GOLD,
|
||||
.base_efficiency = 1.0
|
||||
.resourceTarget = ee_economy::RESOURCE_TYPE::GOLD,
|
||||
.baseEfficiency = 1.0
|
||||
};
|
||||
|
||||
world.spawn_enterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner);
|
||||
world.spawn_enterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner);
|
||||
world.spawn_enterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner);
|
||||
world.spawn_enterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner);
|
||||
world.spawn_enterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner);
|
||||
world.spawnEnterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner);
|
||||
world.spawnEnterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner);
|
||||
world.spawnEnterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner);
|
||||
world.spawnEnterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner);
|
||||
world.spawnEnterprise(false, ee_economy::ACTION_TYPE::MINING, state, miner);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,76 +5,76 @@
|
||||
|
||||
TEST(WorldTest, RegisterState)
|
||||
{
|
||||
ee_ecs::world world;
|
||||
ee_ecs::World world;
|
||||
|
||||
ee_economy::container res = {.capacity = 100.0};
|
||||
ee_economy::Container res = {.capacity = 100.0};
|
||||
res.add(ee_economy::RESOURCE_TYPE::COAL, 98.0);
|
||||
entt::entity state = world.register_state(10, res);
|
||||
entt::entity state = world.registerState(10, res);
|
||||
|
||||
ee_economy::state registered_state = world.get_registry().get<ee_economy::state>(state);
|
||||
ee_economy::container registered_container = world.get_registry().get<ee_economy::container>(state);
|
||||
ee_economy::State registeredState = world.getRegistry().get<ee_economy::State>(state);
|
||||
ee_economy::Container registeredContainer = world.getRegistry().get<ee_economy::Container>(state);
|
||||
|
||||
ASSERT_EQ(registered_state.external_id, 10);
|
||||
ASSERT_DOUBLE_EQ(registered_container.content[ee_economy::RESOURCE_TYPE::COAL], 98.0);
|
||||
ASSERT_EQ(registeredState.externalId, 10);
|
||||
ASSERT_DOUBLE_EQ(registeredContainer.content[ee_economy::RESOURCE_TYPE::COAL], 98.0);
|
||||
}
|
||||
|
||||
TEST(WorldTest, RegisterStateDuplicate)
|
||||
{
|
||||
ee_ecs::world world;
|
||||
ee_ecs::World world;
|
||||
|
||||
world.register_state(10, {});
|
||||
world.registerState(10, {});
|
||||
|
||||
ASSERT_THROW({
|
||||
world.register_state(10, {});
|
||||
world.registerState(10, {});
|
||||
}, std::invalid_argument);
|
||||
}
|
||||
|
||||
TEST(WorldTest, SpawnMiner)
|
||||
{
|
||||
ee_ecs::world world;
|
||||
ee_ecs::World world;
|
||||
|
||||
entt::entity state = world.get_registry().create();
|
||||
world.get_registry().emplace<ee_economy::state>(state, (int16_t)0);
|
||||
world.get_registry().emplace<ee_economy::container>(state, 100.0);
|
||||
entt::entity state = world.getRegistry().create();
|
||||
world.getRegistry().emplace<ee_economy::State>(state, (int16_t)0);
|
||||
world.getRegistry().emplace<ee_economy::Container>(state, 100.0);
|
||||
|
||||
ee_economy::enterprise_defaults defaults = {
|
||||
ee_economy::EnterpriseDefaults defaults = {
|
||||
.container = {.capacity = 100.0 },
|
||||
.resource_target = ee_economy::RESOURCE_TYPE::COAL,
|
||||
.base_efficiency = 1.0,
|
||||
.resourceTarget = ee_economy::RESOURCE_TYPE::COAL,
|
||||
.baseEfficiency = 1.0,
|
||||
};
|
||||
|
||||
entt::entity enterprise = world.spawn_enterprise(false, ee_economy::ACTION_TYPE::MINING, state, defaults);
|
||||
entt::entity enterprise = world.spawnEnterprise(false, ee_economy::ACTION_TYPE::MINING, state, defaults);
|
||||
|
||||
ee_economy::enterprise registered_enterprise = world.get_registry().get<ee_economy::enterprise>(enterprise);
|
||||
ee_economy::miner registered_action = world.get_registry().get<ee_economy::miner>(enterprise);
|
||||
ee_economy::container registered_container = world.get_registry().get<ee_economy::container>(enterprise);
|
||||
ee_economy::Enterprise registeredEnterprise = world.getRegistry().get<ee_economy::Enterprise>(enterprise);
|
||||
ee_economy::Miner registeredAction = world.getRegistry().get<ee_economy::Miner>(enterprise);
|
||||
ee_economy::Container registeredContainer = world.getRegistry().get<ee_economy::Container>(enterprise);
|
||||
|
||||
ASSERT_DOUBLE_EQ(registered_enterprise.base_efficiency, 1.0);
|
||||
ASSERT_EQ(registered_action.resource, ee_economy::RESOURCE_TYPE::COAL);
|
||||
ASSERT_DOUBLE_EQ(registered_container.capacity, 100.0);
|
||||
ASSERT_DOUBLE_EQ(registeredEnterprise.baseEfficiency, 1.0);
|
||||
ASSERT_EQ(registeredAction.resource, ee_economy::RESOURCE_TYPE::COAL);
|
||||
ASSERT_DOUBLE_EQ(registeredContainer.capacity, 100.0);
|
||||
}
|
||||
|
||||
TEST(WorldTest, SpawnDeliverer)
|
||||
{
|
||||
ee_ecs::world world;
|
||||
ee_ecs::World world;
|
||||
|
||||
entt::entity state = world.get_registry().create();
|
||||
world.get_registry().emplace<ee_economy::state>(state, (int16_t)0);
|
||||
world.get_registry().emplace<ee_economy::container>(state, 100.0);
|
||||
entt::entity state = world.getRegistry().create();
|
||||
world.getRegistry().emplace<ee_economy::State>(state, (int16_t)0);
|
||||
world.getRegistry().emplace<ee_economy::Container>(state, 100.0);
|
||||
|
||||
ee_economy::enterprise_defaults defaults = {
|
||||
ee_economy::EnterpriseDefaults defaults = {
|
||||
.container = {.capacity = 100.0 },
|
||||
.resource_target = ee_economy::RESOURCE_TYPE::COAL,
|
||||
.base_efficiency = 1.0,
|
||||
.resourceTarget = ee_economy::RESOURCE_TYPE::COAL,
|
||||
.baseEfficiency = 1.0,
|
||||
};
|
||||
|
||||
entt::entity enterprise = world.spawn_enterprise(false, ee_economy::ACTION_TYPE::DELIVERY, state, defaults);
|
||||
entt::entity enterprise = world.spawnEnterprise(false, ee_economy::ACTION_TYPE::DELIVERY, state, defaults);
|
||||
|
||||
ee_economy::enterprise registered_enterprise = world.get_registry().get<ee_economy::enterprise>(enterprise);
|
||||
ee_economy::deliverer registered_action = world.get_registry().get<ee_economy::deliverer>(enterprise);
|
||||
ee_economy::container registered_container = world.get_registry().get<ee_economy::container>(enterprise);
|
||||
ee_economy::Enterprise registeredEnterprise = world.getRegistry().get<ee_economy::Enterprise>(enterprise);
|
||||
ee_economy::Deliverer registeredAction = world.getRegistry().get<ee_economy::Deliverer>(enterprise);
|
||||
ee_economy::Container registeredContainer = world.getRegistry().get<ee_economy::Container>(enterprise);
|
||||
|
||||
ASSERT_DOUBLE_EQ(registered_enterprise.base_efficiency, 1.0);
|
||||
ASSERT_EQ(registered_action.resource, ee_economy::RESOURCE_TYPE::COAL);
|
||||
ASSERT_DOUBLE_EQ(registered_container.capacity, 100.0);
|
||||
ASSERT_DOUBLE_EQ(registeredEnterprise.baseEfficiency, 1.0);
|
||||
ASSERT_EQ(registeredAction.resource, ee_economy::RESOURCE_TYPE::COAL);
|
||||
ASSERT_DOUBLE_EQ(registeredContainer.capacity, 100.0);
|
||||
}
|
||||
@ -21,13 +21,13 @@ find_package(EnTT CONFIG REQUIRED)
|
||||
|
||||
# Link library
|
||||
|
||||
add_library(Economy ${HEADERS} ${HEADERS_COMPONENTS} ${SOURCES} ${SOURCES_SYSTEMS})
|
||||
add_library(Economy::Economy ALIAS Economy)
|
||||
add_library(${PROJECT_NAME} ${HEADERS} ${HEADERS_COMPONENTS} ${SOURCES} ${SOURCES_SYSTEMS})
|
||||
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
|
||||
|
||||
target_link_libraries(Economy PRIVATE EnTT::EnTT)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE EnTT::EnTT)
|
||||
|
||||
target_include_directories(Economy PUBLIC include/)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC include/)
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||
set_property(TARGET Economy PROPERTY CXX_STANDARD 20)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
|
||||
endif()
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
namespace ee_economy
|
||||
{
|
||||
struct container
|
||||
struct Container
|
||||
{
|
||||
double capacity = 0.;
|
||||
double total = 0.;
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
namespace ee_economy
|
||||
{
|
||||
struct deliver_contract
|
||||
struct DeliverContract
|
||||
{
|
||||
entt::entity from;
|
||||
entt::entity to;
|
||||
@ -15,10 +15,10 @@ namespace ee_economy
|
||||
double distance = 1.0;
|
||||
};
|
||||
|
||||
struct deliverer
|
||||
struct Deliverer
|
||||
{
|
||||
RESOURCE_TYPE resource = RESOURCE_TYPE::NONE;
|
||||
|
||||
std::vector<deliver_contract> contracts;
|
||||
std::vector<DeliverContract> contracts;
|
||||
};
|
||||
}
|
||||
@ -5,9 +5,9 @@
|
||||
|
||||
namespace ee_economy
|
||||
{
|
||||
struct enterprise
|
||||
struct Enterprise
|
||||
{
|
||||
bool is_building = false;
|
||||
bool isBuilding = false;
|
||||
entt::entity state;
|
||||
ACTION_TYPE action = ACTION_TYPE::STORE;
|
||||
|
||||
@ -17,39 +17,39 @@ namespace ee_economy
|
||||
* Production -
|
||||
*/
|
||||
double efficiency = 0.;
|
||||
double base_efficiency = 0.;
|
||||
double factor_efficiency = 1.;
|
||||
double baseEfficiency = 0.;
|
||||
double factorEfficiency = 1.;
|
||||
|
||||
std::vector<entt::entity> links_from;
|
||||
std::vector<entt::entity> links_to;
|
||||
std::vector<entt::entity> linksFrom;
|
||||
std::vector<entt::entity> linksTo;
|
||||
|
||||
uint16_t staff_size = 1;
|
||||
uint16_t staffSize = 1;
|
||||
|
||||
// This can be splitted in percents between bank enterprises in future
|
||||
double total_money = 0;
|
||||
double totalMoney = 0;
|
||||
double salary = 0;
|
||||
bool is_bankrupt = false;
|
||||
bool isBankrupt = false;
|
||||
|
||||
void set_money(double value)
|
||||
void setMoney(double value)
|
||||
{
|
||||
total_money = value;
|
||||
totalMoney = value;
|
||||
}
|
||||
|
||||
inline void update_efficiency()
|
||||
inline void updateEfficiency()
|
||||
{
|
||||
this->efficiency = this->base_efficiency * this->factor_efficiency;
|
||||
this->efficiency = this->baseEfficiency * this->factorEfficiency;
|
||||
}
|
||||
|
||||
void set_base_efficiency(double value)
|
||||
void setBaseEfficiency(double value)
|
||||
{
|
||||
this->base_efficiency = value;
|
||||
update_efficiency();
|
||||
this->baseEfficiency = value;
|
||||
updateEfficiency();
|
||||
}
|
||||
|
||||
void set_factor_efficiency(double value)
|
||||
void setFactorEfficiency(double value)
|
||||
{
|
||||
this->factor_efficiency = value;
|
||||
update_efficiency();
|
||||
this->factorEfficiency = value;
|
||||
updateEfficiency();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
namespace ee_economy
|
||||
{
|
||||
struct miner
|
||||
struct Miner
|
||||
{
|
||||
RESOURCE_TYPE resource = RESOURCE_TYPE::NONE;
|
||||
};
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
namespace ee_economy
|
||||
{
|
||||
struct producer
|
||||
struct Producer
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
namespace ee_economy
|
||||
{
|
||||
struct state {
|
||||
int16_t external_id = -1;
|
||||
struct State {
|
||||
int16_t externalId = -1;
|
||||
};
|
||||
}
|
||||
@ -4,12 +4,12 @@
|
||||
|
||||
namespace ee_economy
|
||||
{
|
||||
struct enterprise_defaults
|
||||
struct EnterpriseDefaults
|
||||
{
|
||||
container container;
|
||||
Container container;
|
||||
|
||||
RESOURCE_TYPE resource_target = RESOURCE_TYPE::NONE;
|
||||
double base_efficiency = 0.0;
|
||||
double factor_efficiency = 1.0;
|
||||
RESOURCE_TYPE resourceTarget = RESOURCE_TYPE::NONE;
|
||||
double baseEfficiency = 0.0;
|
||||
double factorEfficiency = 1.0;
|
||||
};
|
||||
}
|
||||
@ -6,18 +6,18 @@
|
||||
|
||||
namespace ee_economy
|
||||
{
|
||||
struct exchange_rule
|
||||
struct ExchangeRule
|
||||
{
|
||||
double out_value;
|
||||
double outValue;
|
||||
|
||||
std::unordered_map<RESOURCE_TYPE, double> consume;
|
||||
};
|
||||
|
||||
const std::unordered_map<RESOURCE_TYPE, exchange_rule> resources_exchange = {
|
||||
const std::unordered_map<RESOURCE_TYPE, exchange_rule> resourcesExchange = {
|
||||
{
|
||||
RESOURCE_TYPE::FABRIC,
|
||||
exchange_rule {
|
||||
.out_value = 2.,
|
||||
.outValue = 2.,
|
||||
.consume = {
|
||||
{RESOURCE_TYPE::WOOL, 3.}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
namespace ee_economy
|
||||
{
|
||||
void enterprise_routine(entt::registry& registry);
|
||||
void enterpriseRoutine(entt::registry& registry);
|
||||
|
||||
void mining(entt::registry& registry);
|
||||
// void producing(entt::registry& registry);
|
||||
|
||||
@ -2,54 +2,54 @@
|
||||
|
||||
void ee_economy::delivering(entt::registry ®istry)
|
||||
{
|
||||
auto deliverers = registry.view<enterprise, deliverer, container>();
|
||||
auto deliverers = registry.view<Enterprise, Deliverer, Container>();
|
||||
|
||||
for (auto [entity, enterprise, deliverer, storage]: deliverers.each())
|
||||
{
|
||||
if (enterprise.is_bankrupt) continue;
|
||||
if (enterprise.isBankrupt) continue;
|
||||
|
||||
for (deliver_contract &contract: deliverer.contracts)
|
||||
for (DeliverContract &contract: deliverer.contracts)
|
||||
{
|
||||
double paid_amount = contract.amount;
|
||||
double paidAmount = contract.amount;
|
||||
|
||||
if (contract.cost > 0)
|
||||
{
|
||||
ee_economy::enterprise &sponsor = registry.get<ee_economy::enterprise>(contract.sponsor);
|
||||
Enterprise &sponsor = registry.get<Enterprise>(contract.sponsor);
|
||||
|
||||
double cost_per_one = contract.cost / contract.amount;
|
||||
double costPerOne = contract.cost / contract.amount;
|
||||
double payment = contract.cost;
|
||||
|
||||
if (payment > sponsor.total_money)
|
||||
if (payment > sponsor.totalMoney)
|
||||
{
|
||||
payment = (int)(sponsor.total_money / cost_per_one) * cost_per_one;
|
||||
paid_amount = payment / cost_per_one;
|
||||
payment = (int)(sponsor.totalMoney / costPerOne) * costPerOne;
|
||||
paidAmount = payment / costPerOne;
|
||||
}
|
||||
sponsor.set_money(sponsor.total_money - payment);
|
||||
enterprise.set_money(enterprise.total_money + payment);
|
||||
sponsor.setMoney(sponsor.totalMoney - payment);
|
||||
enterprise.setMoney(enterprise.totalMoney + payment);
|
||||
contract.cost -= payment;
|
||||
}
|
||||
|
||||
container &from_storage = registry.get<container>(contract.from);
|
||||
container &to_storage = registry.get<container>(contract.to);
|
||||
Container &fromStorage = registry.get<Container>(contract.from);
|
||||
Container &toStorage = registry.get<Container>(contract.to);
|
||||
|
||||
double deliver_value = enterprise.efficiency;
|
||||
double deliverValue = enterprise.efficiency;
|
||||
if (contract.amount < enterprise.efficiency)
|
||||
deliver_value = contract.amount;
|
||||
if (to_storage.total + deliver_value > to_storage.capacity)
|
||||
deliver_value = to_storage.capacity - to_storage.total;
|
||||
if (deliver_value > from_storage.content[deliverer.resource])
|
||||
deliver_value = from_storage.content[deliverer.resource];
|
||||
if (deliver_value > paid_amount)
|
||||
deliver_value = paid_amount;
|
||||
if (deliver_value < 0.0)
|
||||
deliver_value = 0.0;
|
||||
deliverValue = contract.amount;
|
||||
if (toStorage.total + deliverValue > toStorage.capacity)
|
||||
deliverValue = toStorage.capacity - toStorage.total;
|
||||
if (deliverValue > fromStorage.content[deliverer.resource])
|
||||
deliverValue = fromStorage.content[deliverer.resource];
|
||||
if (deliverValue > paidAmount)
|
||||
deliverValue = paidAmount;
|
||||
if (deliverValue < 0.0)
|
||||
deliverValue = 0.0;
|
||||
|
||||
to_storage.add(deliverer.resource, deliver_value);
|
||||
from_storage.add(deliverer.resource, -deliver_value);
|
||||
contract.amount -= deliver_value;
|
||||
toStorage.add(deliverer.resource, deliverValue);
|
||||
fromStorage.add(deliverer.resource, -deliverValue);
|
||||
contract.amount -= deliverValue;
|
||||
}
|
||||
|
||||
std::erase_if(deliverer.contracts, [](const deliver_contract &contract) {
|
||||
std::erase_if(deliverer.contracts, [](const DeliverContract &contract) {
|
||||
return contract.amount <= 0.0;
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
#include <ee_economy/economy.hpp>
|
||||
|
||||
void ee_economy::enterprise_routine(entt::registry ®istry)
|
||||
void ee_economy::enterpriseRoutine(entt::registry ®istry)
|
||||
{
|
||||
auto enterprises = registry.view<enterprise>();
|
||||
auto enterprises = registry.view<Enterprise>();
|
||||
|
||||
for (auto [entity, enterprise]: enterprises.each())
|
||||
{
|
||||
double salary_debt = enterprise.salary * enterprise.staff_size;
|
||||
if (enterprise.total_money < salary_debt)
|
||||
double salaryDebt = enterprise.salary * enterprise.staffSize;
|
||||
if (enterprise.totalMoney < salaryDebt)
|
||||
{
|
||||
enterprise.is_bankrupt = true;
|
||||
enterprise.set_money(0.0);
|
||||
enterprise.isBankrupt = true;
|
||||
enterprise.setMoney(0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
enterprise.set_money(enterprise.total_money - salary_debt);
|
||||
enterprise.setMoney(enterprise.totalMoney - salaryDebt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,21 +2,21 @@
|
||||
|
||||
void ee_economy::mining(entt::registry ®istry)
|
||||
{
|
||||
auto miners = registry.view<enterprise, miner, container>();
|
||||
auto miners = registry.view<Enterprise, Miner, Container>();
|
||||
|
||||
for (auto [entity, enterprise, miner, local_storage]: miners.each())
|
||||
for (auto [entity, enterprise, miner, localStorage]: miners.each())
|
||||
{
|
||||
if (enterprise.is_bankrupt) continue;
|
||||
if (enterprise.isBankrupt) continue;
|
||||
|
||||
container& state = registry.get<container>(enterprise.state);
|
||||
Container& state = registry.get<Container>(enterprise.state);
|
||||
|
||||
double mined_value = enterprise.efficiency;
|
||||
if (local_storage.total + mined_value > local_storage.capacity)
|
||||
mined_value = local_storage.capacity - local_storage.total;
|
||||
if (mined_value > state.content[miner.resource])
|
||||
mined_value = state.content[miner.resource];
|
||||
double minedValue = enterprise.efficiency;
|
||||
if (localStorage.total + minedValue > localStorage.capacity)
|
||||
minedValue = localStorage.capacity - localStorage.total;
|
||||
if (minedValue > state.content[miner.resource])
|
||||
minedValue = state.content[miner.resource];
|
||||
|
||||
local_storage.add(miner.resource, mined_value);
|
||||
state.add(miner.resource, -mined_value);
|
||||
localStorage.add(miner.resource, minedValue);
|
||||
state.add(miner.resource, -minedValue);
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,5 @@
|
||||
project(economy_tests)
|
||||
|
||||
# List sources
|
||||
|
||||
set(SOURCES "test_conf.hpp" "main.cpp"
|
||||
@ -11,14 +13,14 @@ find_package(GTest CONFIG REQUIRED)
|
||||
|
||||
include(GoogleTest)
|
||||
|
||||
add_executable(economy_tests ${SOURCES})
|
||||
target_link_libraries(economy_tests PRIVATE GTest::gtest_main)
|
||||
target_link_libraries(economy_tests PRIVATE Economy::Economy)
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE GTest::gtest_main)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Economy::Economy)
|
||||
|
||||
# Test
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||
set_property(TARGET economy_tests PROPERTY CXX_STANDARD 20)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
|
||||
endif()
|
||||
|
||||
gtest_discover_tests(economy_tests)
|
||||
gtest_discover_tests(${PROJECT_NAME})
|
||||
@ -6,140 +6,140 @@ TEST_F(SystemsTest, DeliverySingleNormal)
|
||||
{
|
||||
// [Miner -> Storage] by Deliverer
|
||||
|
||||
ee_economy::enterprise &deliverer_enterprise = registry.get<ee_economy::enterprise>(deliverer);
|
||||
ee_economy::deliverer &deliverer_deliverer = registry.get<ee_economy::deliverer>(deliverer);
|
||||
ee_economy::Enterprise &delivererEnterprise = registry.get<ee_economy::Enterprise>(deliverer);
|
||||
ee_economy::Deliverer &delivererDeliverer = registry.get<ee_economy::Deliverer>(deliverer);
|
||||
|
||||
deliverer_deliverer.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
deliverer_enterprise.set_base_efficiency(1.0);
|
||||
deliverer_deliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0});
|
||||
delivererDeliverer.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
delivererEnterprise.setBaseEfficiency(1.0);
|
||||
delivererDeliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0});
|
||||
|
||||
ee_economy::container &from_container = registry.get<ee_economy::container>(miner);
|
||||
ee_economy::container &to_container = registry.get<ee_economy::container>(storage);
|
||||
ee_economy::Container &fromContainer = registry.get<ee_economy::Container>(miner);
|
||||
ee_economy::Container &toContainer = registry.get<ee_economy::Container>(storage);
|
||||
|
||||
from_container.capacity = 15.0;
|
||||
from_container.add(ee_economy::RESOURCE_TYPE::COAL, 15.0);
|
||||
fromContainer.capacity = 15.0;
|
||||
fromContainer.add(ee_economy::RESOURCE_TYPE::COAL, 15.0);
|
||||
|
||||
to_container.capacity = 15.0;
|
||||
toContainer.capacity = 15.0;
|
||||
|
||||
ee_economy::delivering(registry);
|
||||
|
||||
ASSERT_DOUBLE_EQ(from_container.total, 14.0);
|
||||
ASSERT_DOUBLE_EQ(from_container.content[ee_economy::RESOURCE_TYPE::COAL], 14.0);
|
||||
ASSERT_DOUBLE_EQ(to_container.total, 1.0);
|
||||
ASSERT_DOUBLE_EQ(to_container.content[ee_economy::RESOURCE_TYPE::COAL], 1.0);
|
||||
ASSERT_EQ(deliverer_deliverer.contracts.size(), 1);
|
||||
ASSERT_DOUBLE_EQ(fromContainer.total, 14.0);
|
||||
ASSERT_DOUBLE_EQ(fromContainer.content[ee_economy::RESOURCE_TYPE::COAL], 14.0);
|
||||
ASSERT_DOUBLE_EQ(toContainer.total, 1.0);
|
||||
ASSERT_DOUBLE_EQ(toContainer.content[ee_economy::RESOURCE_TYPE::COAL], 1.0);
|
||||
ASSERT_EQ(delivererDeliverer.contracts.size(), 1);
|
||||
}
|
||||
|
||||
TEST_F(SystemsTest, DeliverySingleEmpty)
|
||||
{
|
||||
// [Miner -> Storage] by Deliverer
|
||||
|
||||
ee_economy::enterprise &deliverer_enterprise = registry.get<ee_economy::enterprise>(deliverer);
|
||||
ee_economy::deliverer &deliverer_deliverer = registry.get<ee_economy::deliverer>(deliverer);
|
||||
ee_economy::Enterprise &delivererEnterprise = registry.get<ee_economy::Enterprise>(deliverer);
|
||||
ee_economy::Deliverer &delivererDeliverer = registry.get<ee_economy::Deliverer>(deliverer);
|
||||
|
||||
deliverer_deliverer.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
deliverer_enterprise.set_base_efficiency(1.0);
|
||||
deliverer_deliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0});
|
||||
delivererDeliverer.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
delivererEnterprise.setBaseEfficiency(1.0);
|
||||
delivererDeliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0});
|
||||
|
||||
ee_economy::container &from_container = registry.get<ee_economy::container>(miner);
|
||||
ee_economy::container &to_container = registry.get<ee_economy::container>(storage);
|
||||
ee_economy::Container &fromContainer = registry.get<ee_economy::Container>(miner);
|
||||
ee_economy::Container &toContainer = registry.get<ee_economy::Container>(storage);
|
||||
|
||||
from_container.capacity = 15.0;
|
||||
to_container.capacity = 15.0;
|
||||
fromContainer.capacity = 15.0;
|
||||
toContainer.capacity = 15.0;
|
||||
|
||||
ee_economy::delivering(registry);
|
||||
|
||||
ASSERT_DOUBLE_EQ(from_container.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(from_container.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
ASSERT_DOUBLE_EQ(to_container.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(to_container.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
ASSERT_EQ(deliverer_deliverer.contracts.size(), 1);
|
||||
ASSERT_DOUBLE_EQ(fromContainer.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(fromContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
ASSERT_DOUBLE_EQ(toContainer.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(toContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
ASSERT_EQ(delivererDeliverer.contracts.size(), 1);
|
||||
}
|
||||
|
||||
TEST_F(SystemsTest, DeliverySinglePoor)
|
||||
{
|
||||
// [Miner -> Storage] by Deliverer
|
||||
|
||||
ee_economy::enterprise &deliverer_enterprise = registry.get<ee_economy::enterprise>(deliverer);
|
||||
ee_economy::deliverer &deliverer_deliverer = registry.get<ee_economy::deliverer>(deliverer);
|
||||
ee_economy::Enterprise &delivererEnterprise = registry.get<ee_economy::Enterprise>(deliverer);
|
||||
ee_economy::Deliverer &delivererDeliverer = registry.get<ee_economy::Deliverer>(deliverer);
|
||||
|
||||
deliverer_deliverer.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
deliverer_enterprise.set_base_efficiency(1.0);
|
||||
deliverer_deliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0});
|
||||
delivererDeliverer.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
delivererEnterprise.setBaseEfficiency(1.0);
|
||||
delivererDeliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0});
|
||||
|
||||
ee_economy::container &from_container = registry.get<ee_economy::container>(miner);
|
||||
ee_economy::container &to_container = registry.get<ee_economy::container>(storage);
|
||||
ee_economy::Container &fromContainer = registry.get<ee_economy::Container>(miner);
|
||||
ee_economy::Container &toContainer = registry.get<ee_economy::Container>(storage);
|
||||
|
||||
from_container.capacity = 15.0;
|
||||
from_container.add(ee_economy::RESOURCE_TYPE::COAL, 0.5);
|
||||
fromContainer.capacity = 15.0;
|
||||
fromContainer.add(ee_economy::RESOURCE_TYPE::COAL, 0.5);
|
||||
|
||||
to_container.capacity = 15.0;
|
||||
toContainer.capacity = 15.0;
|
||||
|
||||
ee_economy::delivering(registry);
|
||||
|
||||
ASSERT_DOUBLE_EQ(from_container.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(from_container.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
ASSERT_DOUBLE_EQ(to_container.total, 0.5);
|
||||
ASSERT_DOUBLE_EQ(to_container.content[ee_economy::RESOURCE_TYPE::COAL], 0.5);
|
||||
ASSERT_EQ(deliverer_deliverer.contracts.size(), 1);
|
||||
ASSERT_DOUBLE_EQ(fromContainer.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(fromContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
ASSERT_DOUBLE_EQ(toContainer.total, 0.5);
|
||||
ASSERT_DOUBLE_EQ(toContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.5);
|
||||
ASSERT_EQ(delivererDeliverer.contracts.size(), 1);
|
||||
}
|
||||
|
||||
TEST_F(SystemsTest, DeliverySingleFinishContract)
|
||||
{
|
||||
// [Miner -> Storage] by Deliverer
|
||||
|
||||
ee_economy::enterprise &deliverer_enterprise = registry.get<ee_economy::enterprise>(deliverer);
|
||||
ee_economy::deliverer &deliverer_deliverer = registry.get<ee_economy::deliverer>(deliverer);
|
||||
ee_economy::Enterprise &delivererEnterprise = registry.get<ee_economy::Enterprise>(deliverer);
|
||||
ee_economy::Deliverer &delivererDeliverer = registry.get<ee_economy::Deliverer>(deliverer);
|
||||
|
||||
deliverer_deliverer.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
deliverer_enterprise.set_base_efficiency(15.0);
|
||||
deliverer_deliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0});
|
||||
delivererDeliverer.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
delivererEnterprise.setBaseEfficiency(15.0);
|
||||
delivererDeliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0});
|
||||
|
||||
ee_economy::container &from_container = registry.get<ee_economy::container>(miner);
|
||||
ee_economy::container &to_container = registry.get<ee_economy::container>(storage);
|
||||
ee_economy::Container &fromContainer = registry.get<ee_economy::Container>(miner);
|
||||
ee_economy::Container &toContainer = registry.get<ee_economy::Container>(storage);
|
||||
|
||||
from_container.capacity = 15.0;
|
||||
from_container.add(ee_economy::RESOURCE_TYPE::COAL, 15.0);
|
||||
fromContainer.capacity = 15.0;
|
||||
fromContainer.add(ee_economy::RESOURCE_TYPE::COAL, 15.0);
|
||||
|
||||
to_container.capacity = 15.0;
|
||||
toContainer.capacity = 15.0;
|
||||
|
||||
ee_economy::delivering(registry);
|
||||
|
||||
ASSERT_DOUBLE_EQ(from_container.total, 5.0);
|
||||
ASSERT_DOUBLE_EQ(from_container.content[ee_economy::RESOURCE_TYPE::COAL], 5.0);
|
||||
ASSERT_DOUBLE_EQ(to_container.total, 10.0);
|
||||
ASSERT_DOUBLE_EQ(to_container.content[ee_economy::RESOURCE_TYPE::COAL], 10.0);
|
||||
ASSERT_EQ(deliverer_deliverer.contracts.size(), 0);
|
||||
ASSERT_DOUBLE_EQ(fromContainer.total, 5.0);
|
||||
ASSERT_DOUBLE_EQ(fromContainer.content[ee_economy::RESOURCE_TYPE::COAL], 5.0);
|
||||
ASSERT_DOUBLE_EQ(toContainer.total, 10.0);
|
||||
ASSERT_DOUBLE_EQ(toContainer.content[ee_economy::RESOURCE_TYPE::COAL], 10.0);
|
||||
ASSERT_EQ(delivererDeliverer.contracts.size(), 0);
|
||||
}
|
||||
|
||||
TEST_F(SystemsTest, DeliveryMultipleFinishPoorCycle)
|
||||
{
|
||||
// [Miner -> Storage | Storage -> Miner] by Deliverer
|
||||
|
||||
ee_economy::enterprise &deliverer_enterprise = registry.get<ee_economy::enterprise>(deliverer);
|
||||
ee_economy::deliverer &deliverer_deliverer = registry.get<ee_economy::deliverer>(deliverer);
|
||||
ee_economy::Enterprise &delivererEnterprise = registry.get<ee_economy::Enterprise>(deliverer);
|
||||
ee_economy::Deliverer &delivererDeliverer = registry.get<ee_economy::Deliverer>(deliverer);
|
||||
|
||||
deliverer_deliverer.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
deliverer_enterprise.set_base_efficiency(16.0);
|
||||
deliverer_deliverer.contracts.push_back({.from = miner, .to = storage, .amount = 20.0});
|
||||
deliverer_deliverer.contracts.push_back({.from = storage, .to = miner, .amount = 5.0});
|
||||
delivererDeliverer.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
delivererEnterprise.setBaseEfficiency(16.0);
|
||||
delivererDeliverer.contracts.push_back({.from = miner, .to = storage, .amount = 20.0});
|
||||
delivererDeliverer.contracts.push_back({.from = storage, .to = miner, .amount = 5.0});
|
||||
|
||||
ee_economy::container &miner_container = registry.get<ee_economy::container>(miner);
|
||||
ee_economy::container &storage_container = registry.get<ee_economy::container>(storage);
|
||||
ee_economy::Container &minerContainer = registry.get<ee_economy::Container>(miner);
|
||||
ee_economy::Container &storageContainer = registry.get<ee_economy::Container>(storage);
|
||||
|
||||
miner_container.capacity = 15.0;
|
||||
miner_container.add(ee_economy::RESOURCE_TYPE::COAL, 15.0);
|
||||
minerContainer.capacity = 15.0;
|
||||
minerContainer.add(ee_economy::RESOURCE_TYPE::COAL, 15.0);
|
||||
|
||||
storage_container.capacity = 15.0;
|
||||
storageContainer.capacity = 15.0;
|
||||
|
||||
ee_economy::delivering(registry);
|
||||
|
||||
ASSERT_DOUBLE_EQ(miner_container.total, 5.0);
|
||||
ASSERT_DOUBLE_EQ(miner_container.content[ee_economy::RESOURCE_TYPE::COAL], 5.0);
|
||||
ASSERT_DOUBLE_EQ(storage_container.total, 10.0);
|
||||
ASSERT_DOUBLE_EQ(storage_container.content[ee_economy::RESOURCE_TYPE::COAL], 10.0);
|
||||
ASSERT_EQ(deliverer_deliverer.contracts.size(), 1);
|
||||
ASSERT_EQ(deliverer_deliverer.contracts[0].from, miner);
|
||||
ASSERT_DOUBLE_EQ(minerContainer.total, 5.0);
|
||||
ASSERT_DOUBLE_EQ(minerContainer.content[ee_economy::RESOURCE_TYPE::COAL], 5.0);
|
||||
ASSERT_DOUBLE_EQ(storageContainer.total, 10.0);
|
||||
ASSERT_DOUBLE_EQ(storageContainer.content[ee_economy::RESOURCE_TYPE::COAL], 10.0);
|
||||
ASSERT_EQ(delivererDeliverer.contracts.size(), 1);
|
||||
ASSERT_EQ(delivererDeliverer.contracts[0].from, miner);
|
||||
}
|
||||
|
||||
TEST_F(SystemsTest, DeliveryPayment)
|
||||
@ -147,12 +147,12 @@ TEST_F(SystemsTest, DeliveryPayment)
|
||||
// [Miner -> Storage] by Deliverer for $Miner
|
||||
// [Miner -> Storage] by Deliverer
|
||||
|
||||
ee_economy::enterprise &deliverer_enterprise = registry.get<ee_economy::enterprise>(deliverer);
|
||||
ee_economy::deliverer &deliverer_deliverer = registry.get<ee_economy::deliverer>(deliverer);
|
||||
ee_economy::Enterprise &delivererEnterprise = registry.get<ee_economy::Enterprise>(deliverer);
|
||||
ee_economy::Deliverer &delivererDeliverer = registry.get<ee_economy::Deliverer>(deliverer);
|
||||
|
||||
deliverer_deliverer.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
deliverer_enterprise.set_base_efficiency(10.0);
|
||||
deliverer_deliverer.contracts.push_back({
|
||||
delivererDeliverer.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
delivererEnterprise.setBaseEfficiency(10.0);
|
||||
delivererDeliverer.contracts.push_back({
|
||||
.from = miner,
|
||||
.to = storage,
|
||||
.sponsor = miner,
|
||||
@ -160,26 +160,26 @@ TEST_F(SystemsTest, DeliveryPayment)
|
||||
.cost = 100.0
|
||||
});
|
||||
|
||||
ee_economy::container &from_container = registry.get<ee_economy::container>(miner);
|
||||
ee_economy::enterprise &from_enterprise = registry.get<ee_economy::enterprise>(miner);
|
||||
ee_economy::container &to_container = registry.get<ee_economy::container>(storage);
|
||||
ee_economy::Container &fromContainer = registry.get<ee_economy::Container>(miner);
|
||||
ee_economy::Enterprise &fromEnterprise = registry.get<ee_economy::Enterprise>(miner);
|
||||
ee_economy::Container &toContainer = registry.get<ee_economy::Container>(storage);
|
||||
|
||||
from_container.capacity = 10.0;
|
||||
from_container.add(ee_economy::RESOURCE_TYPE::COAL, 10.0);
|
||||
from_enterprise.set_money(95.0);
|
||||
fromContainer.capacity = 10.0;
|
||||
fromContainer.add(ee_economy::RESOURCE_TYPE::COAL, 10.0);
|
||||
fromEnterprise.setMoney(95.0);
|
||||
|
||||
to_container.capacity = 10.0;
|
||||
toContainer.capacity = 10.0;
|
||||
|
||||
ee_economy::delivering(registry);
|
||||
|
||||
ASSERT_DOUBLE_EQ(from_container.total, 1.0);
|
||||
ASSERT_DOUBLE_EQ(from_container.content[ee_economy::RESOURCE_TYPE::COAL], 1.0);
|
||||
ASSERT_DOUBLE_EQ(to_container.total, 9.0);
|
||||
ASSERT_DOUBLE_EQ(to_container.content[ee_economy::RESOURCE_TYPE::COAL], 9.0);
|
||||
ASSERT_DOUBLE_EQ(from_enterprise.total_money, 5.0);
|
||||
ASSERT_DOUBLE_EQ(deliverer_enterprise.total_money, 90.0);
|
||||
ASSERT_DOUBLE_EQ(fromContainer.total, 1.0);
|
||||
ASSERT_DOUBLE_EQ(fromContainer.content[ee_economy::RESOURCE_TYPE::COAL], 1.0);
|
||||
ASSERT_DOUBLE_EQ(toContainer.total, 9.0);
|
||||
ASSERT_DOUBLE_EQ(toContainer.content[ee_economy::RESOURCE_TYPE::COAL], 9.0);
|
||||
ASSERT_DOUBLE_EQ(fromEnterprise.totalMoney, 5.0);
|
||||
ASSERT_DOUBLE_EQ(delivererEnterprise.totalMoney, 90.0);
|
||||
|
||||
ee_economy::deliver_contract contract = deliverer_deliverer.contracts[0];
|
||||
ee_economy::DeliverContract contract = delivererDeliverer.contracts[0];
|
||||
ASSERT_DOUBLE_EQ(contract.cost, 10.0);
|
||||
ASSERT_DOUBLE_EQ(contract.amount, 1.0);
|
||||
}
|
||||
@ -188,27 +188,27 @@ TEST_F(SystemsTest, DeliveryBankrupt)
|
||||
{
|
||||
// [Miner -> Storage] by Deliverer
|
||||
|
||||
ee_economy::enterprise &deliverer_enterprise = registry.get<ee_economy::enterprise>(deliverer);
|
||||
ee_economy::deliverer &deliverer_deliverer = registry.get<ee_economy::deliverer>(deliverer);
|
||||
ee_economy::Enterprise &delivererEnterprise = registry.get<ee_economy::Enterprise>(deliverer);
|
||||
ee_economy::Deliverer &delivererDeliverer = registry.get<ee_economy::Deliverer>(deliverer);
|
||||
|
||||
deliverer_deliverer.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
deliverer_deliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0});
|
||||
deliverer_enterprise.set_base_efficiency(1.0);
|
||||
deliverer_enterprise.is_bankrupt = true;
|
||||
delivererDeliverer.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
delivererDeliverer.contracts.push_back({.from = miner, .to = storage, .amount = 10.0});
|
||||
delivererEnterprise.setBaseEfficiency(1.0);
|
||||
delivererEnterprise.isBankrupt = true;
|
||||
|
||||
ee_economy::container &from_container = registry.get<ee_economy::container>(miner);
|
||||
ee_economy::container &to_container = registry.get<ee_economy::container>(storage);
|
||||
ee_economy::Container &fromContainer = registry.get<ee_economy::Container>(miner);
|
||||
ee_economy::Container &toContainer = registry.get<ee_economy::Container>(storage);
|
||||
|
||||
from_container.capacity = 15.0;
|
||||
from_container.add(ee_economy::RESOURCE_TYPE::COAL, 15.0);
|
||||
fromContainer.capacity = 15.0;
|
||||
fromContainer.add(ee_economy::RESOURCE_TYPE::COAL, 15.0);
|
||||
|
||||
to_container.capacity = 15.0;
|
||||
toContainer.capacity = 15.0;
|
||||
|
||||
ee_economy::delivering(registry);
|
||||
|
||||
ASSERT_DOUBLE_EQ(from_container.total, 15.0);
|
||||
ASSERT_DOUBLE_EQ(from_container.content[ee_economy::RESOURCE_TYPE::COAL], 15.0);
|
||||
ASSERT_DOUBLE_EQ(to_container.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(to_container.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
ASSERT_EQ(deliverer_deliverer.contracts.size(), 1);
|
||||
ASSERT_DOUBLE_EQ(fromContainer.total, 15.0);
|
||||
ASSERT_DOUBLE_EQ(fromContainer.content[ee_economy::RESOURCE_TYPE::COAL], 15.0);
|
||||
ASSERT_DOUBLE_EQ(toContainer.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(toContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
ASSERT_EQ(delivererDeliverer.contracts.size(), 1);
|
||||
}
|
||||
@ -4,26 +4,26 @@
|
||||
|
||||
TEST_F(SystemsTest, RoutineNormal)
|
||||
{
|
||||
ee_economy::enterprise &miner_enterprise = registry.get<ee_economy::enterprise>(miner);
|
||||
miner_enterprise.set_money(1000000000.0);
|
||||
miner_enterprise.salary = 100000.0;
|
||||
miner_enterprise.staff_size = 10;
|
||||
ee_economy::Enterprise &minerEnterprise = registry.get<ee_economy::Enterprise>(miner);
|
||||
minerEnterprise.setMoney(1000000000.0);
|
||||
minerEnterprise.salary = 100000.0;
|
||||
minerEnterprise.staffSize = 10;
|
||||
|
||||
ee_economy::enterprise_routine(registry);
|
||||
ee_economy::enterpriseRoutine(registry);
|
||||
|
||||
ASSERT_DOUBLE_EQ(miner_enterprise.total_money, 999000000.0);
|
||||
ASSERT_FALSE(miner_enterprise.is_bankrupt);
|
||||
ASSERT_DOUBLE_EQ(minerEnterprise.totalMoney, 999000000.0);
|
||||
ASSERT_FALSE(minerEnterprise.isBankrupt);
|
||||
}
|
||||
|
||||
TEST_F(SystemsTest, RoutineBankruptcy)
|
||||
{
|
||||
ee_economy::enterprise &miner_enterprise = registry.get<ee_economy::enterprise>(miner);
|
||||
miner_enterprise.set_money(1000000.0);
|
||||
miner_enterprise.salary = 100000.0;
|
||||
miner_enterprise.staff_size = 11;
|
||||
ee_economy::Enterprise &minerEnterprise = registry.get<ee_economy::Enterprise>(miner);
|
||||
minerEnterprise.setMoney(1000000.0);
|
||||
minerEnterprise.salary = 100000.0;
|
||||
minerEnterprise.staffSize = 11;
|
||||
|
||||
ee_economy::enterprise_routine(registry);
|
||||
ee_economy::enterpriseRoutine(registry);
|
||||
|
||||
ASSERT_DOUBLE_EQ(miner_enterprise.total_money, 0.0);
|
||||
ASSERT_TRUE(miner_enterprise.is_bankrupt);
|
||||
ASSERT_DOUBLE_EQ(minerEnterprise.totalMoney, 0.0);
|
||||
ASSERT_TRUE(minerEnterprise.isBankrupt);
|
||||
}
|
||||
@ -4,110 +4,110 @@
|
||||
|
||||
TEST_F(SystemsTest, MiningNormal)
|
||||
{
|
||||
ee_economy::container &state_container = registry.get<ee_economy::container>(state);
|
||||
ee_economy::container &miner_container = registry.get<ee_economy::container>(miner);
|
||||
ee_economy::enterprise &miner_enterprise = registry.get<ee_economy::enterprise>(miner);
|
||||
ee_economy::miner &miner_miner = registry.get<ee_economy::miner>(miner);
|
||||
ee_economy::Container &stateContainer = registry.get<ee_economy::Container>(state);
|
||||
ee_economy::Container &minerContainer = registry.get<ee_economy::Container>(miner);
|
||||
ee_economy::Enterprise &minerEnterprise = registry.get<ee_economy::Enterprise>(miner);
|
||||
ee_economy::Miner &minerMiner = registry.get<ee_economy::Miner>(miner);
|
||||
|
||||
state_container.capacity = 15.0;
|
||||
state_container.add(ee_economy::RESOURCE_TYPE::COAL, 10.0);
|
||||
stateContainer.capacity = 15.0;
|
||||
stateContainer.add(ee_economy::RESOURCE_TYPE::COAL, 10.0);
|
||||
|
||||
miner_container.capacity = 5.0;
|
||||
miner_miner.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
miner_enterprise.set_base_efficiency(0.1);
|
||||
minerContainer.capacity = 5.0;
|
||||
minerMiner.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
minerEnterprise.setBaseEfficiency(0.1);
|
||||
|
||||
ee_economy::mining(registry);
|
||||
|
||||
ASSERT_DOUBLE_EQ(state_container.total, 9.9);
|
||||
ASSERT_DOUBLE_EQ(state_container.content[ee_economy::RESOURCE_TYPE::COAL], 9.9);
|
||||
ASSERT_DOUBLE_EQ(miner_container.total, 0.1);
|
||||
ASSERT_DOUBLE_EQ(miner_container.content[ee_economy::RESOURCE_TYPE::COAL], 0.1);
|
||||
ASSERT_DOUBLE_EQ(stateContainer.total, 9.9);
|
||||
ASSERT_DOUBLE_EQ(stateContainer.content[ee_economy::RESOURCE_TYPE::COAL], 9.9);
|
||||
ASSERT_DOUBLE_EQ(minerContainer.total, 0.1);
|
||||
ASSERT_DOUBLE_EQ(minerContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.1);
|
||||
}
|
||||
|
||||
TEST_F(SystemsTest, MiningEmptyState)
|
||||
{
|
||||
ee_economy::container &state_container = registry.get<ee_economy::container>(state);
|
||||
ee_economy::container &miner_container = registry.get<ee_economy::container>(miner);
|
||||
ee_economy::enterprise &miner_enterprise = registry.get<ee_economy::enterprise>(miner);
|
||||
ee_economy::miner &miner_miner = registry.get<ee_economy::miner>(miner);
|
||||
ee_economy::Container &stateContainer = registry.get<ee_economy::Container>(state);
|
||||
ee_economy::Container &minerContainer = registry.get<ee_economy::Container>(miner);
|
||||
ee_economy::Enterprise &minerEnterprise = registry.get<ee_economy::Enterprise>(miner);
|
||||
ee_economy::Miner &minerMiner = registry.get<ee_economy::Miner>(miner);
|
||||
|
||||
state_container.capacity = 15.0;
|
||||
stateContainer.capacity = 15.0;
|
||||
|
||||
miner_container.capacity = 5.0;
|
||||
miner_miner.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
miner_enterprise.set_base_efficiency(0.1);
|
||||
minerContainer.capacity = 5.0;
|
||||
minerMiner.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
minerEnterprise.setBaseEfficiency(0.1);
|
||||
|
||||
ee_economy::mining(registry);
|
||||
|
||||
ASSERT_DOUBLE_EQ(state_container.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(state_container.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
ASSERT_DOUBLE_EQ(miner_container.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(miner_container.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
ASSERT_DOUBLE_EQ(stateContainer.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(stateContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
ASSERT_DOUBLE_EQ(minerContainer.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(minerContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
}
|
||||
|
||||
TEST_F(SystemsTest, MiningPoorState)
|
||||
{
|
||||
ee_economy::container &state_container = registry.get<ee_economy::container>(state);
|
||||
ee_economy::container &miner_container = registry.get<ee_economy::container>(miner);
|
||||
ee_economy::enterprise &miner_enterprise = registry.get<ee_economy::enterprise>(miner);
|
||||
ee_economy::miner &miner_miner = registry.get<ee_economy::miner>(miner);
|
||||
ee_economy::Container &stateContainer = registry.get<ee_economy::Container>(state);
|
||||
ee_economy::Container &minerContainer = registry.get<ee_economy::Container>(miner);
|
||||
ee_economy::Enterprise &minerEnterprise = registry.get<ee_economy::Enterprise>(miner);
|
||||
ee_economy::Miner &minerMiner = registry.get<ee_economy::Miner>(miner);
|
||||
|
||||
state_container.capacity = 15.0;
|
||||
state_container.add(ee_economy::RESOURCE_TYPE::COAL, 0.05);
|
||||
stateContainer.capacity = 15.0;
|
||||
stateContainer.add(ee_economy::RESOURCE_TYPE::COAL, 0.05);
|
||||
|
||||
miner_container.capacity = 5.0;
|
||||
miner_miner.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
miner_enterprise.set_base_efficiency(0.1);
|
||||
minerContainer.capacity = 5.0;
|
||||
minerMiner.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
minerEnterprise.setBaseEfficiency(0.1);
|
||||
|
||||
ee_economy::mining(registry);
|
||||
|
||||
ASSERT_DOUBLE_EQ(state_container.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(state_container.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
ASSERT_DOUBLE_EQ(miner_container.total, 0.05);
|
||||
ASSERT_DOUBLE_EQ(miner_container.content[ee_economy::RESOURCE_TYPE::COAL], 0.05);
|
||||
ASSERT_DOUBLE_EQ(stateContainer.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(stateContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
ASSERT_DOUBLE_EQ(minerContainer.total, 0.05);
|
||||
ASSERT_DOUBLE_EQ(minerContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.05);
|
||||
}
|
||||
|
||||
TEST_F(SystemsTest, MiningReachCap)
|
||||
{
|
||||
ee_economy::container &state_container = registry.get<ee_economy::container>(state);
|
||||
ee_economy::container &miner_container = registry.get<ee_economy::container>(miner);
|
||||
ee_economy::enterprise &miner_enterprise = registry.get<ee_economy::enterprise>(miner);
|
||||
ee_economy::miner &miner_miner = registry.get<ee_economy::miner>(miner);
|
||||
ee_economy::Container &stateContainer = registry.get<ee_economy::Container>(state);
|
||||
ee_economy::Container &minerContainer = registry.get<ee_economy::Container>(miner);
|
||||
ee_economy::Enterprise &minerEnterprise = registry.get<ee_economy::Enterprise>(miner);
|
||||
ee_economy::Miner &minerMiner = registry.get<ee_economy::Miner>(miner);
|
||||
|
||||
state_container.capacity = 15.0;
|
||||
state_container.add(ee_economy::RESOURCE_TYPE::COAL, 10.0);
|
||||
stateContainer.capacity = 15.0;
|
||||
stateContainer.add(ee_economy::RESOURCE_TYPE::COAL, 10.0);
|
||||
|
||||
miner_container.capacity = 0.05;
|
||||
miner_miner.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
miner_enterprise.set_base_efficiency(0.1);
|
||||
minerContainer.capacity = 0.05;
|
||||
minerMiner.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
minerEnterprise.setBaseEfficiency(0.1);
|
||||
|
||||
ee_economy::mining(registry);
|
||||
|
||||
ASSERT_DOUBLE_EQ(state_container.total, 9.95);
|
||||
ASSERT_DOUBLE_EQ(state_container.content[ee_economy::RESOURCE_TYPE::COAL], 9.95);
|
||||
ASSERT_DOUBLE_EQ(miner_container.total, 0.05);
|
||||
ASSERT_DOUBLE_EQ(miner_container.content[ee_economy::RESOURCE_TYPE::COAL], 0.05);
|
||||
ASSERT_DOUBLE_EQ(stateContainer.total, 9.95);
|
||||
ASSERT_DOUBLE_EQ(stateContainer.content[ee_economy::RESOURCE_TYPE::COAL], 9.95);
|
||||
ASSERT_DOUBLE_EQ(minerContainer.total, 0.05);
|
||||
ASSERT_DOUBLE_EQ(minerContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.05);
|
||||
}
|
||||
|
||||
TEST_F(SystemsTest, MiningBankrupt)
|
||||
{
|
||||
ee_economy::container &state_container = registry.get<ee_economy::container>(state);
|
||||
ee_economy::container &miner_container = registry.get<ee_economy::container>(miner);
|
||||
ee_economy::enterprise &miner_enterprise = registry.get<ee_economy::enterprise>(miner);
|
||||
ee_economy::miner &miner_miner = registry.get<ee_economy::miner>(miner);
|
||||
ee_economy::Container &stateContainer = registry.get<ee_economy::Container>(state);
|
||||
ee_economy::Container &minerContainer = registry.get<ee_economy::Container>(miner);
|
||||
ee_economy::Enterprise &minerEnterprise = registry.get<ee_economy::Enterprise>(miner);
|
||||
ee_economy::Miner &minerMiner = registry.get<ee_economy::Miner>(miner);
|
||||
|
||||
state_container.capacity = 15.0;
|
||||
state_container.add(ee_economy::RESOURCE_TYPE::COAL, 10.0);
|
||||
stateContainer.capacity = 15.0;
|
||||
stateContainer.add(ee_economy::RESOURCE_TYPE::COAL, 10.0);
|
||||
|
||||
miner_container.capacity = 5.0;
|
||||
miner_miner.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
miner_enterprise.set_base_efficiency(0.1);
|
||||
miner_enterprise.is_bankrupt = true;
|
||||
minerContainer.capacity = 5.0;
|
||||
minerMiner.resource = ee_economy::RESOURCE_TYPE::COAL;
|
||||
minerEnterprise.setBaseEfficiency(0.1);
|
||||
minerEnterprise.isBankrupt = true;
|
||||
|
||||
ee_economy::mining(registry);
|
||||
|
||||
ASSERT_DOUBLE_EQ(state_container.total, 10.0);
|
||||
ASSERT_DOUBLE_EQ(state_container.content[ee_economy::RESOURCE_TYPE::COAL], 10.0);
|
||||
ASSERT_DOUBLE_EQ(miner_container.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(miner_container.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
ASSERT_DOUBLE_EQ(stateContainer.total, 10.0);
|
||||
ASSERT_DOUBLE_EQ(stateContainer.content[ee_economy::RESOURCE_TYPE::COAL], 10.0);
|
||||
ASSERT_DOUBLE_EQ(minerContainer.total, 0.0);
|
||||
ASSERT_DOUBLE_EQ(minerContainer.content[ee_economy::RESOURCE_TYPE::COAL], 0.0);
|
||||
}
|
||||
@ -18,25 +18,25 @@ struct SystemsTest : testing::Test
|
||||
{
|
||||
// Create state
|
||||
state = registry.create();
|
||||
registry.emplace<ee_economy::state>(state);
|
||||
registry.emplace<ee_economy::container>(state);
|
||||
registry.emplace<ee_economy::State>(state);
|
||||
registry.emplace<ee_economy::Container>(state);
|
||||
|
||||
// Create miner enterprise
|
||||
miner = registry.create();
|
||||
registry.emplace<ee_economy::enterprise>(miner, false, state);
|
||||
registry.emplace<ee_economy::miner>(miner);
|
||||
registry.emplace<ee_economy::container>(miner);
|
||||
registry.emplace<ee_economy::Enterprise>(miner, false, state);
|
||||
registry.emplace<ee_economy::Miner>(miner);
|
||||
registry.emplace<ee_economy::Container>(miner);
|
||||
|
||||
// Create storage enterprise
|
||||
storage = registry.create();
|
||||
registry.emplace<ee_economy::enterprise>(storage, false, state);
|
||||
registry.emplace<ee_economy::container>(storage);
|
||||
registry.emplace<ee_economy::Enterprise>(storage, false, state);
|
||||
registry.emplace<ee_economy::Container>(storage);
|
||||
|
||||
// Create delivering enterprise
|
||||
deliverer = registry.create();
|
||||
registry.emplace<ee_economy::enterprise>(deliverer, false, state);
|
||||
registry.emplace<ee_economy::deliverer>(deliverer);
|
||||
registry.emplace<ee_economy::container>(deliverer);
|
||||
registry.emplace<ee_economy::Enterprise>(deliverer, false, state);
|
||||
registry.emplace<ee_economy::Deliverer>(deliverer);
|
||||
registry.emplace<ee_economy::Container>(deliverer);
|
||||
}
|
||||
|
||||
void TearDown()
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
{
|
||||
"dependencies": [
|
||||
"entt",
|
||||
"gtest"
|
||||
]
|
||||
}
|
||||
12
frontend/.vscode/launch.json
vendored
Normal file
12
frontend/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"type": "cmake",
|
||||
"request": "launch",
|
||||
"name": "Debug portfile(s)",
|
||||
"cmakeDebugType": "external",
|
||||
"pipeName": "\\\\.\\pipe\\vcpkg_ext_portfile_dbg",
|
||||
"preLaunchTask": "Debug vcpkg commands"
|
||||
}
|
||||
]
|
||||
}
|
||||
59
frontend/CMakeLists.txt
Normal file
59
frontend/CMakeLists.txt
Normal file
@ -0,0 +1,59 @@
|
||||
cmake_minimum_required (VERSION 3.8)
|
||||
|
||||
if (POLICY CMP0141)
|
||||
cmake_policy(SET CMP0141 NEW)
|
||||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
|
||||
endif()
|
||||
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
project (EEfrontend)
|
||||
|
||||
|
||||
# List sources
|
||||
|
||||
#set(HEADERS "RmlVulkanInterface.hpp")
|
||||
set(SOURCES "main.cpp")
|
||||
|
||||
#list(TRANSFORM HEADERS PREPEND "include/")
|
||||
list(TRANSFORM SOURCES PREPEND "src/")
|
||||
|
||||
# Find dependencies
|
||||
|
||||
find_package(SDL2 CONFIG REQUIRED)
|
||||
find_package(Vulkan REQUIRED)
|
||||
find_package(RmlUi CONFIG REQUIRED)
|
||||
|
||||
# Link library
|
||||
|
||||
add_executable(${PROJECT_NAME} ${HEADERS} ${SOURCES})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE p7)
|
||||
target_link_libraries(
|
||||
${PROJECT_NAME}
|
||||
PRIVATE
|
||||
$<TARGET_NAME_IF_EXISTS:SDL2::SDL2main>
|
||||
$<IF:$<TARGET_EXISTS:SDL2::SDL2>,SDL2::SDL2,SDL2::SDL2-static>
|
||||
)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Vulkan::Vulkan)
|
||||
|
||||
set(RMLUI_BACKEND_PATH ${RmlUi_SOURCE_DIR}/Backends) # Link SDL Vulkan backend for RmlUi
|
||||
add_library(rmlui_backend_SDL_VK INTERFACE)
|
||||
target_sources(rmlui_backend_SDL_VK INTERFACE
|
||||
${RMLUI_BACKEND_PATH}/RmlUi_Platform_SDL.cpp
|
||||
${RMLUI_BACKEND_PATH}/RmlUi_Renderer_VK.cpp
|
||||
)
|
||||
target_include_directories(rmlui_backend_SDL_VK INTERFACE ${RMLUI_BACKEND_PATH})
|
||||
target_compile_definitions(rmlui_backend_SDL_VK INTERFACE
|
||||
RMLUI_SDL_VERSION_MAJOR=2
|
||||
RMLUI_NUM_MSAA_SAMPLES=4
|
||||
RMLUI_VK_CUSTOM_LOADER=<vulkan/vulkan.h>
|
||||
)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE RmlUi::RmlUi)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC include/)
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
|
||||
endif()
|
||||
120
frontend/src/main.cpp
Normal file
120
frontend/src/main.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
#ifdef _DEBUG
|
||||
#define P7_SINK L"/P7.Sink=Console"
|
||||
#else
|
||||
#define P7_SINK L"/P7.Sink=FileTxt"
|
||||
#endif
|
||||
|
||||
#include "P7_Client.h"
|
||||
#include "P7_Trace.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_vulkan.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <RmlUi/Core.h>
|
||||
|
||||
int SDL_main(int argc, char **argv)
|
||||
{
|
||||
// Setup P7 logger
|
||||
IP7_Client *p7client = P7_Create_Client(P7_SINK);
|
||||
P7_Set_Crash_Handler();
|
||||
IP7_Trace *logger = P7_Create_Trace(p7client, L"TC 1");
|
||||
logger->Register_Thread(L"MainThread", 0);
|
||||
|
||||
// Setup SDL
|
||||
bool quit = false;
|
||||
SDL_Event event;
|
||||
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
|
||||
SDL_Window *window = SDL_CreateWindow(
|
||||
"Etredia Empires",
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
800,
|
||||
600,
|
||||
SDL_WINDOW_VULKAN
|
||||
);
|
||||
|
||||
if (!window)
|
||||
{
|
||||
quit = true;
|
||||
LOG(logger, CRITICAL, "SDL Window fails: %hs", SDL_GetError());
|
||||
}
|
||||
else LOG(logger, INFO, "SDL Window created");
|
||||
|
||||
// Setup Vulkan
|
||||
VkInstance vulkan;
|
||||
|
||||
uint32_t sdlExtensionsCount = 0;
|
||||
if ( !SDL_Vulkan_GetInstanceExtensions(window, &sdlExtensionsCount, nullptr) )
|
||||
LOG(logger, CRITICAL, "Fail to get SDL Vulkan extensions number! %hs", SDL_GetError());
|
||||
|
||||
const char **sdlExtentions = new const char*[sdlExtensionsCount]();
|
||||
|
||||
if ( !SDL_Vulkan_GetInstanceExtensions(window, &sdlExtensionsCount, sdlExtentions) )
|
||||
LOG(logger, CRITICAL, "Fail to load SDL Vulkan extentions! %hs", SDL_GetError());
|
||||
else LOG(logger, INFO, "Load %d SDL Vulkan extenstions", sdlExtensionsCount);
|
||||
|
||||
VkInstanceCreateInfo vkCreateConfig = {
|
||||
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
.enabledLayerCount = 0,
|
||||
.enabledExtensionCount = sdlExtensionsCount,
|
||||
.ppEnabledExtensionNames = sdlExtentions
|
||||
};
|
||||
|
||||
VkResult vkCreateResult = vkCreateInstance(&vkCreateConfig, nullptr, &vulkan);
|
||||
if (vkCreateResult != VK_SUCCESS)
|
||||
LOG(logger, CRITICAL, "Vulkan is not instantiated! Code: %d", vkCreateResult);
|
||||
else LOG(logger, INFO, "Vulkan is instantiated");
|
||||
|
||||
delete[] sdlExtentions;
|
||||
|
||||
//Setup RmlUi
|
||||
if (!Rml::Initialise())
|
||||
LOG(logger, CRITICAL, "RmlUi initialization failed!");
|
||||
else LOG(logger, INFO, "RmlUi initialized");
|
||||
|
||||
int32_t screenWidth, screenHeight;
|
||||
SDL_GetWindowSize(window, &screenWidth, &screenHeight);
|
||||
Rml::Context *uiContext = Rml::CreateContext("default", Rml::Vector2i(screenWidth, screenHeight));
|
||||
|
||||
// Process SDL events
|
||||
while(!quit)
|
||||
{
|
||||
SDL_WaitEvent(&event);
|
||||
|
||||
switch(event.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
{
|
||||
quit = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
{
|
||||
switch (event.window.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
{
|
||||
uiContext->SetDimensions(Rml::Vector2i(event.window.data1, event.window.data2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Free memory
|
||||
LOG(logger, INFO, "Exit...");
|
||||
Rml::Shutdown();
|
||||
vkDestroyInstance(vulkan, nullptr);
|
||||
SDL_Quit();
|
||||
logger->Unregister_Thread(0);
|
||||
logger->Release();
|
||||
p7client->Release();
|
||||
|
||||
return 0;
|
||||
}
|
||||
69
p7lib/CMakeLists.txt
Normal file
69
p7lib/CMakeLists.txt
Normal file
@ -0,0 +1,69 @@
|
||||
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
|
||||
|
||||
#project(p7lib)
|
||||
|
||||
#>>Build options **********************************************************************
|
||||
option(P7_TESTS_BUILD "Build test" OFF)
|
||||
set(P7_BUILD_SHARED OFF CACHE INTERNAL "Build shared library")
|
||||
#<<Build options **********************************************************************
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
function(enable_cxx_compiler_flag_if_supported flag)
|
||||
string(FIND "${CMAKE_CXX_FLAGS}" "${flag}" flag_already_set)
|
||||
if(flag_already_set EQUAL -1)
|
||||
check_cxx_compiler_flag("${flag}" flag_supported)
|
||||
if(flag_supported)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}" PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
if(NOT DEFINED ROOT_P7_PATH)
|
||||
set(ROOT_P7_PATH ${PROJECT_SOURCE_DIR} CACHE INTERNAL "")
|
||||
set(PATH_P7 ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "")
|
||||
set(PATH_P7_API "${PROJECT_SOURCE_DIR}/Headers" CACHE INTERNAL "")
|
||||
else(expression)
|
||||
endif(NOT DEFINED ROOT_P7_PATH)
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(-D_UNICODE)
|
||||
add_definitions(-DUNICODE)
|
||||
|
||||
if(NOT COMMAND set_ide_folder)
|
||||
macro(set_ide_folder _project_name)
|
||||
string(LENGTH ${ROOT_P7_PATH} ROOT_P7_PATH_LEN)
|
||||
string(LENGTH ${CMAKE_CURRENT_SOURCE_DIR} CURRENT_SOURCE_DIR_LEN)
|
||||
MATH(EXPR ROOT_P7_PATH_LEN "${ROOT_P7_PATH_LEN}+1")
|
||||
MATH(EXPR CURRENT_SOURCE_DIR_LEN "${CURRENT_SOURCE_DIR_LEN} - ${ROOT_P7_PATH_LEN}")
|
||||
|
||||
string(SUBSTRING ${CMAKE_CURRENT_SOURCE_DIR} ${ROOT_P7_PATH_LEN} ${CURRENT_SOURCE_DIR_LEN} IDE_SUBFOLDER)
|
||||
set_property(TARGET ${_project_name} PROPERTY FOLDER ${IDE_SUBFOLDER})
|
||||
endmacro()
|
||||
endif()
|
||||
else()
|
||||
enable_cxx_compiler_flag_if_supported("-Wall")
|
||||
enable_cxx_compiler_flag_if_supported("-Wextra")
|
||||
enable_cxx_compiler_flag_if_supported("-pedantic")
|
||||
enable_cxx_compiler_flag_if_supported("-D_FILE_OFFSET_BITS=64")
|
||||
enable_cxx_compiler_flag_if_supported("-D_LARGEFILE64_SOURCE")
|
||||
enable_cxx_compiler_flag_if_supported("-fvisibility=hidden")
|
||||
enable_cxx_compiler_flag_if_supported("-Wno-variadic-macros")
|
||||
enable_cxx_compiler_flag_if_supported("-Wno-long-long")
|
||||
enable_cxx_compiler_flag_if_supported("-Wno-missing-field-initializers")
|
||||
enable_cxx_compiler_flag_if_supported("-Wno-unknown-pragmas")
|
||||
enable_cxx_compiler_flag_if_supported("-fPIC")
|
||||
|
||||
macro(set_ide_folder _project_name)
|
||||
endmacro()
|
||||
endif()
|
||||
|
||||
|
||||
add_subdirectory(Headers)
|
||||
add_subdirectory(Shared)
|
||||
add_subdirectory(Sources)
|
||||
|
||||
if(P7_TESTS_BUILD)
|
||||
add_subdirectory(Tests)
|
||||
endif()
|
||||
3
p7lib/Headers/CMakeLists.txt
Normal file
3
p7lib/Headers/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
|
||||
|
||||
set(PATH_P7_API ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "")
|
||||
151
p7lib/Headers/GTypes.h
Normal file
151
p7lib/Headers/GTypes.h
Normal file
@ -0,0 +1,151 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef GTYPE_H
|
||||
#define GTYPE_H
|
||||
|
||||
#if defined(_M_X64)\
|
||||
|| defined(__amd64__)\
|
||||
|| defined(__amd64)\
|
||||
|| defined(_WIN64)\
|
||||
|| defined(_WIN64_)\
|
||||
|| defined(WIN64)\
|
||||
|| defined(__LP64__)\
|
||||
|| defined(_LP64)\
|
||||
|| defined(__x86_64__)\
|
||||
|| defined(__ppc64__)\
|
||||
|| defined(__aarch64__)
|
||||
#define GTX64
|
||||
#else
|
||||
#define GTX32
|
||||
#endif
|
||||
|
||||
#define CONCATENATE_DETAIL(x, y) x##y
|
||||
#define CONCATENATE(x, y) CONCATENATE_DETAIL(x, y)
|
||||
#define MAKE_UNIQUE(x) CONCATENATE(x, __COUNTER__)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//WINDOWS specific definitions & types
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
#define G_OS_WINDOWS
|
||||
|
||||
#if !defined(_WINSOCKAPI_)
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
//Text marco, allow to use wchar_t automatically
|
||||
#define TM(i_pStr) L##i_pStr
|
||||
|
||||
#define XCHAR wchar_t
|
||||
typedef wchar_t tWCHAR;
|
||||
|
||||
#define WND_HANDLE HWND
|
||||
|
||||
#define SHARED_EXT L"dll"
|
||||
|
||||
#define P7_EXPORT __declspec(dllexport)
|
||||
|
||||
#define OS_PATH_SEPARATOR TM("\\")
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//LINUX specific definitions & types
|
||||
#elif defined(__linux__)
|
||||
#define UTF8_ENCODING
|
||||
#define G_OS_LINUX
|
||||
|
||||
//Text marco, allow to use char automatically
|
||||
#define TM(i_pStr) i_pStr
|
||||
|
||||
#define XCHAR char
|
||||
typedef unsigned short tWCHAR;
|
||||
#define WND_HANDLE void*
|
||||
|
||||
#define SHARED_EXT "so"
|
||||
|
||||
typedef struct _GUID
|
||||
{
|
||||
unsigned int Data1;
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[ 8 ];
|
||||
} GUID;
|
||||
|
||||
#define __stdcall
|
||||
#define __cdecl
|
||||
|
||||
#ifndef __forceinline
|
||||
#if defined(GTX64) || defined(__PIC__)
|
||||
#define __forceinline
|
||||
#else
|
||||
#define __forceinline __attribute__((always_inline))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define P7_EXPORT __attribute__ ((visibility ("default")))
|
||||
|
||||
#define OS_PATH_SEPARATOR TM("/")
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define PRAGMA_PACK_ENTER(x) __pragma(pack(push, x))
|
||||
#define PRAGMA_PACK_EXIT() __pragma(pack(pop))
|
||||
#define ATTR_PACK(x)
|
||||
#define ATTR_ALIGN(x)
|
||||
#define UNUSED_FUNC
|
||||
#else
|
||||
#define PRAGMA_PACK_ENTER(x)
|
||||
#define PRAGMA_PACK_EXIT(x)
|
||||
#define ATTR_PACK(x) __attribute__ ((aligned(x), packed))
|
||||
#define ATTR_ALIGN(x) __attribute__ ((aligned(x)))
|
||||
#define UNUSED_FUNC __attribute__ ((unused))
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define UNUSED_ARG(x) (void)(x)
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define TOSTR(x) STR_HELPER(x)
|
||||
|
||||
#define TMM(i_pStr) TM(i_pStr)
|
||||
|
||||
typedef unsigned long long tUINT64;
|
||||
typedef long long tINT64;
|
||||
typedef unsigned int tUINT32;
|
||||
typedef int tINT32;
|
||||
typedef unsigned short tUINT16;
|
||||
typedef short tINT16;
|
||||
typedef unsigned char tUINT8;
|
||||
typedef char tINT8;
|
||||
typedef char tACHAR;
|
||||
//platfrorm specific char, Windows - wchar_t, Linix - char,
|
||||
//XCHAR defined in PTypes.hpp specific for each platform or project.
|
||||
#define tXCHAR XCHAR
|
||||
//typedef XCHAR tXCHAR;
|
||||
typedef unsigned int tBOOL;
|
||||
typedef double tDOUBLE;
|
||||
|
||||
|
||||
#define GASSERT(cond) typedef int assert_type[(cond) ? 1 : -1]
|
||||
|
||||
#endif //GTYPE_H
|
||||
574
p7lib/Headers/P7_Client.h
Normal file
574
p7lib/Headers/P7_Client.h
Normal file
@ -0,0 +1,574 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// This header file provide client functionality /
|
||||
// /
|
||||
// +-------------------+ /
|
||||
// | Sink | /
|
||||
// | * Network (Baical)| /
|
||||
// | * FileBin | /
|
||||
// | * FileTxt | /
|
||||
// | * Console | /
|
||||
// | * Syslog | /
|
||||
// | * Auto | /
|
||||
// | * Null | /
|
||||
// +---------^---------+ /
|
||||
// | /
|
||||
// | /
|
||||
// +---------+---------+ /
|
||||
// | P7 Client | /
|
||||
// | [ Channels ] | /
|
||||
// | +-+ +-+ +--+ | /
|
||||
// | |0| |1| ...|31| | /
|
||||
// | +^+ +^+ +-^+ | /
|
||||
// +---|---|-------|---+ /
|
||||
// | | | /
|
||||
// +-----+ | +----------+ /
|
||||
// | | | /
|
||||
// | | | /
|
||||
// +---+---+ +---+--------+ +---+---+ /
|
||||
// | Trace | | Telemetry | | Trace | /
|
||||
// |Channel| | channel | ... |Channel| /
|
||||
// +-------+ +------------+ +-------+ /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Documentation is located in <P7>/Documentation/P7.pdf //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef P7_CLIENT_H
|
||||
#define P7_CLIENT_H
|
||||
|
||||
#include "GTypes.h"
|
||||
#include "P7_Version.h"
|
||||
|
||||
#define CLIENT_DEFAULT_SHARED_NAME TM("P7.Client")
|
||||
|
||||
//Values: P7 sink (logs, traces & telemetry destination)
|
||||
//There are 3 possible values:
|
||||
// * Baical - over network to Baical server directly
|
||||
// * File - to file
|
||||
// * Auto - to Baical if connection is established, otherwise to file
|
||||
// N.B.: connection timeout is 250 ms.
|
||||
// * Null - all data will be dropped
|
||||
// Default value: Baical
|
||||
#define CLIENT_COMMAND_LINE_SINK TM("/P7.Sink=")
|
||||
|
||||
#define CLIENT_SINK_BAICAL TM("Baical")
|
||||
#define CLIENT_SINK_FILE_BIN TM("FileBin")
|
||||
#define CLIENT_SINK_FILE_BIN_LEGACY TM("File")
|
||||
#define CLIENT_SINK_FILE_TXT TM("FileTxt")
|
||||
#define CLIENT_SINK_CONSOLE TM("Console")
|
||||
#define CLIENT_SINK_SYSLOG TM("Syslog")
|
||||
#define CLIENT_SINK_AUTO TM("Auto")
|
||||
#define CLIENT_SINK_NULL TM("Null")
|
||||
|
||||
|
||||
//Values: P7 client name, max length is about 96 characters, by default it is
|
||||
//name of the process. Useful in case when P7 is used from script language and
|
||||
//name of host process isn't usable - for example Python.exe
|
||||
#define CLIENT_COMMAND_LINE_NAME TM("/P7.Name=")
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Sink=Baical arguments /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Values: server address
|
||||
//IPV4 address : XXX.XXX.XXX.XXX
|
||||
//IPV6 address : ::1, etc.
|
||||
//NetBios Name : any name
|
||||
#define CLIENT_COMMAND_LINE_BAICAL_ADDRESS TM("/P7.Addr=")
|
||||
|
||||
//Values: server specified port
|
||||
//default: 9009
|
||||
#define CLIENT_COMMAND_LINE_BAICAL_PORT TM("/P7.Port=")
|
||||
|
||||
//Values: size of the data packet
|
||||
// Min: 512
|
||||
// Max: 65535
|
||||
// Recommended: your network MTU size
|
||||
// default: 1472
|
||||
#define CLIENT_COMMAND_PACKET_BAICAL_SIZE TM("/P7.PSize=")
|
||||
|
||||
//size of the transmission window in packets. Sometimes is useful to manage it
|
||||
//if server aggressively loose incoming packets, this parameter is for precise
|
||||
//tuning, in most of the cases stay untouched and protocol manage it
|
||||
//Min = 1
|
||||
//max = ((pool size / packet size) / 2)
|
||||
#define CLIENT_COMMAND_WINDOW_BAICAL_SIZE TM("/P7.Window=")
|
||||
|
||||
//specifies exit timeout in seconds, used to deliver last data chunks to server
|
||||
//max value is 15 seconds
|
||||
#define CLIENT_COMMAND_LINE_BAICAL_EXIT_TIMEOUT TM("/P7.Eto=")
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Sink=File arguments /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Value: path to destination file
|
||||
//default: <current process dir>/P7logs
|
||||
#define CLIENT_COMMAND_LINE_DIR TM("/P7.Dir=")
|
||||
|
||||
//Value: define rolling type
|
||||
// Xmb - rolling every X megabytes, for example /P7.Roll=10mb
|
||||
// Xhr - rolling every X hours, for example /P7.Roll=24hr, max = 1000hr
|
||||
// HH:MMtm - rolling by time (00:00 -> 23:59), for example:
|
||||
// * rolling at 12:00 -> P7.Roll=12:00tm
|
||||
// * rolling at 12:00 and 00:00 -> P7.Roll=00:00,12:00tm
|
||||
//default: rolling is off
|
||||
#define CLIENT_COMMAND_LINE_FILE_ROLLING TM("/P7.Roll=")
|
||||
|
||||
//Value: define maximum P7 logs files in destination folder /P7.Dir="MyDir"
|
||||
//in case if count of files is larger than specified value - oldest files will
|
||||
//be removed
|
||||
//default : off (0)
|
||||
//min : 1
|
||||
//max : 4096
|
||||
#define CLIENT_COMMAND_LINE_FILES_COUNT_MAX TM("/P7.Files=")
|
||||
|
||||
|
||||
//Value: define maximum P7 logs files cumulative size in MB at destination
|
||||
//folder /P7.Dir="MyDir" in case if size of files is larger than specified
|
||||
//value - oldest files will be removed
|
||||
//default : off (0)
|
||||
//min : 1
|
||||
//max : 4294967296
|
||||
#define CLIENT_COMMAND_LINE_FILES_SIZE_MAX TM("/P7.FSize=")
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// general settings /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Values:
|
||||
// 0 : Debug
|
||||
// 1 : Info
|
||||
// 2 : Warnings
|
||||
// 3 : Errors
|
||||
// 4 : Critical
|
||||
// default: logging is off
|
||||
#define CLIENT_COMMAND_LOG_VERBOSITY TM("/P7.Verb=")
|
||||
|
||||
//Manage internal logging
|
||||
//Values:
|
||||
// 0 : Off
|
||||
// 1 : On
|
||||
//default: On(1)
|
||||
#define CLIENT_COMMAND_LOG_ON TM("/P7.On=")
|
||||
|
||||
//size of the internal buffers pool in kilobytes. Minimal 16(kb), max is not
|
||||
//specified
|
||||
//default value = 1mb
|
||||
#define CLIENT_COMMAND_POOL_SIZE TM("/P7.Pool=")
|
||||
|
||||
|
||||
//specify do we need to flush channels inside P7_Exceptional_Flush call
|
||||
//Values: 1 = yes, 0 = no
|
||||
//default value = 1
|
||||
#define CLIENT_COMMAND_FLUSH_CHANNELS TM("/P7.FlashChannels=")
|
||||
|
||||
|
||||
//specifies log message format for such sinks like: FileTxt, Console, SysLog
|
||||
//format example:
|
||||
// /P7.Format="%cn #%ix [%tf] %lv Tr:#%ti:%tn CPU:%cc Md:%mn {%fs:%fl:%fn} %ms"
|
||||
|
||||
#define CLIENT_COMMAND_FORMAT TM("/P7.Format=")
|
||||
|
||||
#define CLIENT_FMT_CHANNEL TM("cn")
|
||||
|
||||
#define CLIENT_FMT_MSG_ID TM("id")
|
||||
#define CLIENT_FMT_MSG_INDEX TM("ix")
|
||||
|
||||
#define CLIENT_FMT_TIME_FULL TM("tf")
|
||||
#define CLIENT_FMT_TIME_MEDIUM TM("tm")
|
||||
#define CLIENT_FMT_TIME_SHORT TM("ts")
|
||||
#define CLIENT_FMT_TIME_DIFF TM("td")
|
||||
#define CLIENT_FMT_TIME_COUNT TM("tc")
|
||||
|
||||
#define CLIENT_FMT_LEVEL TM("lv")
|
||||
|
||||
#define CLIENT_FMT_THREAD_ID TM("ti")
|
||||
#define CLIENT_FMT_THREAD_NAME TM("tn")
|
||||
|
||||
#define CLIENT_FMT_CPU_CORE TM("cc")
|
||||
|
||||
#define CLIENT_FMT_MODULE_ID TM("mi")
|
||||
#define CLIENT_FMT_MODULE_NAME TM("mn")
|
||||
|
||||
#define CLIENT_FMT_FILE_FULL TM("ff")
|
||||
#define CLIENT_FMT_FILE_SHORT TM("fs")
|
||||
#define CLIENT_FMT_FILE_LINE TM("fl")
|
||||
#define CLIENT_FMT_FUNCTION TM("fn")
|
||||
|
||||
#define CLIENT_FMT_MSG TM("ms")
|
||||
|
||||
|
||||
//Syslog facility digit https://tools.ietf.org/html/rfc3164#page-8
|
||||
#define CLIENT_COMMAND_SYSLOG_FACILITY TM("/P7.Facility=")
|
||||
|
||||
|
||||
//Values: No values
|
||||
#define CLIENT_COMMAND_LOG_HELP TM("/P7.Help")
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Trace settings /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//Override verbosity for all trace streams and modules
|
||||
//Values:
|
||||
//0 = EP7TRACE_LEVEL_TRACE
|
||||
//1 = EP7TRACE_LEVEL_DEBUG
|
||||
//2 = EP7TRACE_LEVEL_INFO
|
||||
//3 = EP7TRACE_LEVEL_WARNING
|
||||
//4 = EP7TRACE_LEVEL_ERROR
|
||||
//5 = EP7TRACE_LEVEL_CRITICAL
|
||||
//Example: /P7.Trc.Verb=5
|
||||
#define CLIENT_COMMAND_TRACE_VERBOSITY TM("/P7.Trc.Verb=")
|
||||
|
||||
|
||||
#define CLIENT_HELP_STRING\
|
||||
TM("P7 arguments:\n")\
|
||||
TM(" -General arguments: \n")\
|
||||
TM(" /P7.Sink - Select data flow direction, there are few values:\n")\
|
||||
TM(" * Baical - to Baical server over network(fast and efficient)\n")\
|
||||
TM(" * FileBin - to local binary file (fast and efficient)\n")\
|
||||
TM(" * FileTxt - to local text file (slow comparing to FileBin/Baical)\n")\
|
||||
TM(" * Syslog - to syslog server (slow comparing to FileBin/Baical)\n")\
|
||||
TM(" * Console - to console (slow comparing to FileBin/Baical)\n")\
|
||||
TM(" * Auto - to Baical server if connection is istablished, otherwise to file\n")\
|
||||
TM(" N.B.: connection timeout is 250 ms !\n")\
|
||||
TM(" * Null - drop all incoming data\n")\
|
||||
TM(" Examples:\n")\
|
||||
TM(" /P7.Sink=Baical\n")\
|
||||
TM(" /P7.Sink=File\n")\
|
||||
TM(" /P7.Sink=Null\n")\
|
||||
TM(" /P7.Name - P7 client name, max length is about 96 characters, by default it is\n")\
|
||||
TM(" name of the host process. Useful in case when P7 is used from scrip\n")\
|
||||
TM(" language and name of host process is not suitable - for example Python.exe\n")\
|
||||
TM(" Example:\n")\
|
||||
TM(" /P7.Name=Client\n")\
|
||||
TM(" /P7.On - Enable/Disable P7 network engine, By default P7 is on\n")\
|
||||
TM(" Examples:\n")\
|
||||
TM(" /P7.On=1\n")\
|
||||
TM(" /P7.On=0\n")\
|
||||
TM(" /P7.Verb - Set logging verbosity level. This option allow to write\n")\
|
||||
TM(" to text log file or stdout all internal engine messages.\n")\
|
||||
TM(" Do not specify /P7.Verb parameter to switch off the logging\n")\
|
||||
TM(" P7 internal logging has next verbosity levels:\n")\
|
||||
TM(" 0 : Info\n")\
|
||||
TM(" 1 : Debug\n")\
|
||||
TM(" 2 : Warnings\n")\
|
||||
TM(" 3 : Errors\n")\
|
||||
TM(" 4 : Critical\n")\
|
||||
TM(" Example: /P7.Verb=4\n")\
|
||||
TM(" /P7.Trc.Verb- Set verbosity level for all trace streams and associated modules\n")\
|
||||
TM(" Has next verbosity levels:\n")\
|
||||
TM(" 0 : Trace\n")\
|
||||
TM(" 1 : Debug\n")\
|
||||
TM(" 2 : Info\n")\
|
||||
TM(" 3 : Warnings\n")\
|
||||
TM(" 4 : Errors\n")\
|
||||
TM(" 5 : Critical\n")\
|
||||
TM(" Example: /P7.Trc.Verb=4\n")\
|
||||
TM(" /P7.Pool - Set size of the internal buffers pool in kilobytes. Minimal 16(kb)\n")\
|
||||
TM(" maximal is limited by your OS and HW. Default value = 4mb\n")\
|
||||
TM(" Example, 1 Mb allocation: /P7.Pool=1024\n")\
|
||||
TM(" -Sink=Baical, -Sink=Syslog : \n")\
|
||||
TM(" /P7.Addr - Set server address (IPV4, IPV6, NetBios name)\n")\
|
||||
TM(" Examples:\n")\
|
||||
TM(" /P7.Addr=127.0.0.1\n")\
|
||||
TM(" /P7.Addr=::1\n")\
|
||||
TM(" /P7.Addr=MyPC\n")\
|
||||
TM(" Default address is 127.0.0.1\n")\
|
||||
TM(" /P7.Port - Set server port, default port is 9009\n")\
|
||||
TM(" Example: /P7.Port=9010\n")\
|
||||
TM(" /P7.PSize - Set packet size. Min value 512 bytes, Max - 65535, Default - 512\n")\
|
||||
TM(" You should specify optimum packet size\n")\
|
||||
TM(" for your network, usually it is MTU.\n")\
|
||||
TM(" Example: /P7.PSize=1476\n")\
|
||||
TM(" -Sink=FileBin, -Sink=FileTxt: \n")\
|
||||
TM(" /P7.Dir - Directory where P7 files will be created, if it is not specified\n")\
|
||||
TM(" process directory will be used.\n")\
|
||||
TM(" Examples:\n")\
|
||||
TM(" /P7.Dir=/home/user/logs/\n")\
|
||||
TM(" /P7.Dir=C:\\Logs\\\n")\
|
||||
TM(" /P7.Files - defines maximum P7 logs files in destination folder\n")\
|
||||
TM(" in case if count of files is larger than specified value\n")\
|
||||
TM(" oldest files will be removed\n")\
|
||||
TM(" /P7.Roll - use it to specify files rolling value & type. There are 2 rolling types:\n")\
|
||||
TM(" * Rolling by file size, measured in megabytes\n")\
|
||||
TM(" * Rolling by time, measured in hours, 1000 hours max\n")\
|
||||
TM(" Rolling value consists of 2 parts:\n")\
|
||||
TM(" * digit\n")\
|
||||
TM(" * postfix: hr, mb\n")\
|
||||
TM(" Examples:\n")\
|
||||
TM(" /P7.Roll=100mb\n")\
|
||||
TM(" /P7.Roll=24hr\n")\
|
||||
TM(" -Sink=FileTxt, -Sink=Console, -Sink=Syslog: \n")\
|
||||
TM(" /P7.Format - log message format sting, example: /P7.Format=\"{%%cn} [%%tf] %%lv %%ms\"\n")\
|
||||
TM(" * cn - channel name \n")\
|
||||
TM(" * id - message ID\n")\
|
||||
TM(" * ix - message index\n")\
|
||||
TM(" * tf - full time YY.MM.DD HH.MM.SS.mils.mics.nans\n")\
|
||||
TM(" * tm - time medium HH.MM.SS.mils.mics.nans\n")\
|
||||
TM(" * ts - time short MM.SS.mils.mics.nans\n")\
|
||||
TM(" * td - time difference between current and prev. one +SS.mils.mics.nans\n")\
|
||||
TM(" * tc - time stamp in 100 nanoseconds intervals\n")\
|
||||
TM(" * lv - level (error, warning, etc)\n")\
|
||||
TM(" * ti - thread ID\n")\
|
||||
TM(" * tn - thread name\n")\
|
||||
TM(" * cc - CPU core\n")\
|
||||
TM(" * mi - module ID\n")\
|
||||
TM(" * mn - module name\n")\
|
||||
TM(" * ff - file path + name\n")\
|
||||
TM(" * fs - file name\n")\
|
||||
TM(" * fl - file line\n")\
|
||||
TM(" * fn - function name\n")\
|
||||
TM(" * ms - message\n")\
|
||||
TM(" -Sink=Null: \n")\
|
||||
TM(" there is no arguments\n")\
|
||||
|
||||
|
||||
//Error codes of P7 library, if you want to get extended information about error code please activate internal
|
||||
//console(Linux)/file(Windows) logging. To activate it add parameter to client "/P7.Verb=0"
|
||||
enum eP7_Error
|
||||
{
|
||||
eP7_Error_None = 0,
|
||||
eP7_Error_SharedObjectInvalid,
|
||||
eP7_Error_MemoryAllocation,
|
||||
eP7_Error_Network,
|
||||
eP7_Error_OS,
|
||||
eP7_Error_UserSettings,
|
||||
eP7_Error_FolderCreation,
|
||||
eP7_Error_FileCreation,
|
||||
eP7_Error_NoClient,
|
||||
eP7_Error_NoFreeChannels,
|
||||
|
||||
eP7_Error_Max
|
||||
};
|
||||
|
||||
enum eClient_Status
|
||||
{
|
||||
//Regular statuses
|
||||
ECLIENT_STATUS_OK = 0,
|
||||
ECLIENT_STATUS_OFF ,
|
||||
ECLIENT_STATUS_INTERNAL_ERROR ,
|
||||
|
||||
//Temporary statuses
|
||||
ECLIENT_STATUS_DISCONNECTED ,
|
||||
ECLIENT_STATUS_NO_FREE_BUFFERS ,
|
||||
ECLIENT_STATUS_NOT_ALLOWED ,
|
||||
ECLIENT_STATUS_WRONG_PARAMETERS ,
|
||||
ECLIENT_STATUS_WRONG_FORMAT
|
||||
};
|
||||
|
||||
PRAGMA_PACK_ENTER(4) //alignment is now 4, MS Only//////////////////////////////
|
||||
|
||||
struct sP7C_Status
|
||||
{
|
||||
tBOOL bConnected;
|
||||
//count of the connection drops, when connection has been reinitialized
|
||||
tUINT32 dwResets;
|
||||
}ATTR_PACK(4);
|
||||
|
||||
|
||||
struct sP7C_Data_Chunk
|
||||
{
|
||||
void *pData;
|
||||
tUINT32 dwSize;
|
||||
}ATTR_PACK(4);
|
||||
|
||||
|
||||
struct sP7C_Channel_Info
|
||||
{
|
||||
tUINT32 dwID;
|
||||
}ATTR_PACK(4);
|
||||
|
||||
struct sP7C_Info
|
||||
{
|
||||
//sockaddr_storage sServer;
|
||||
tUINT32 dwMem_Used;
|
||||
tUINT32 dwMem_Free;
|
||||
tUINT32 dwMem_Alloc;
|
||||
tUINT32 dwReject_Mem; //chunks rejected counter - no memory
|
||||
tUINT32 dwReject_Con; //chunks rejected counter - no connection
|
||||
tUINT32 dwReject_Int; //chunks rejected counter - internal errors
|
||||
}ATTR_PACK(4);
|
||||
|
||||
PRAGMA_PACK_EXIT()//4///////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class /*__declspec(novtable)*/ IP7C_Channel
|
||||
{
|
||||
public:
|
||||
enum eType
|
||||
{
|
||||
eTrace,
|
||||
eTelemetry,
|
||||
eCount
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Type - get channel type, depending on type cast to IP7_Telemetry or
|
||||
// IP7_Trace is available
|
||||
virtual IP7C_Channel::eType Get_Type() = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Add_Ref - increase object's reference count
|
||||
// See documentation for details.
|
||||
virtual tINT32 Add_Ref() = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Release - decrease object's reference count. If reference count less or
|
||||
// equal to 0 - object will be destroyed
|
||||
// See documentation for details.
|
||||
virtual tINT32 Release() = 0;
|
||||
|
||||
|
||||
virtual void On_Init(sP7C_Channel_Info *i_pInfo) = 0;
|
||||
virtual void On_Receive(tUINT32 i_dwChannel,
|
||||
tUINT8 *i_pBuffer,
|
||||
tUINT32 i_dwSize,
|
||||
tBOOL i_bBigEndian
|
||||
) = 0;
|
||||
|
||||
virtual void On_Status(tUINT32 i_dwChannel, const sP7C_Status *i_pStatus)=0;
|
||||
|
||||
virtual void On_Flush(tUINT32 i_dwChannel, tBOOL *io_pCrash) = 0;
|
||||
};
|
||||
|
||||
|
||||
//Define the max channels count, and max packet size for IP7_Client::Sent(...)
|
||||
#define USER_PACKET_CHANNEL_ID_BITS_COUNT (5)
|
||||
#define USER_PACKET_SIZE_BITS_COUNT (32-USER_PACKET_CHANNEL_ID_BITS_COUNT)
|
||||
#define USER_PACKET_MAX_SIZE (1 << USER_PACKET_SIZE_BITS_COUNT)
|
||||
#define USER_PACKET_CHANNEL_ID_MAX_SIZE (1 << USER_PACKET_CHANNEL_ID_BITS_COUNT)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
class IP7_Client
|
||||
{
|
||||
public:
|
||||
enum eType
|
||||
{
|
||||
eBaical,
|
||||
eFileBin,
|
||||
eAuto,
|
||||
eNull,
|
||||
eText,
|
||||
eCount
|
||||
};
|
||||
virtual IP7_Client::eType Get_Type() = 0;
|
||||
|
||||
virtual tINT32 Add_Ref() = 0;
|
||||
virtual tINT32 Release() = 0;
|
||||
|
||||
virtual eClient_Status Get_Status() = 0;
|
||||
virtual tBOOL Get_Status(sP7C_Status *o_pStatus) = 0;
|
||||
virtual tBOOL Get_Info(sP7C_Info *o_pInfo) = 0;
|
||||
//N.B. If you use Baikal server to receive data - please do not mix
|
||||
// different packets formats (Trace + Telemetry for example) on the same
|
||||
// channel, in this case one data format will be dropped by server
|
||||
virtual eClient_Status Register_Channel(IP7C_Channel *i_pChannel) = 0;
|
||||
virtual eClient_Status Unregister_Channel(tUINT32 i_dwID) = 0;
|
||||
|
||||
virtual eClient_Status Sent(tUINT32 i_dwChannel_ID,
|
||||
sP7C_Data_Chunk *i_pChunks,
|
||||
tUINT32 i_dwCount,
|
||||
tUINT32 i_dwSize) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Share - function to share current P7 object in address space of
|
||||
// the current process, see documentation for details
|
||||
virtual tBOOL Share(const tXCHAR *i_pName) = 0;
|
||||
|
||||
virtual const tXCHAR *Get_Argument(const tXCHAR *i_pName) = 0;
|
||||
|
||||
virtual size_t Get_Channels_Count() = 0;
|
||||
virtual IP7C_Channel *Get_Channel(size_t i_szIndex) = 0;
|
||||
|
||||
virtual void Flush() = 0;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Create_Client - function creates new P7 client.
|
||||
//See documentation for details
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//N.B: P7 client in addition will analyze your application command line and
|
||||
// arguments specified through command line will have higher priority then
|
||||
// i_sArgs arguments
|
||||
extern "C" P7_EXPORT IP7_Client * __cdecl P7_Create_Client(const tXCHAR *i_pArgs);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//This functions allows you to get P7 instance if it was created by someone else
|
||||
//inside current process.
|
||||
//See documentation for details.
|
||||
extern "C" P7_EXPORT IP7_Client * __cdecl P7_Get_Shared(const tXCHAR *i_pName);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Retrieves the calling thread's last-error code value. The last-error code is
|
||||
//maintained on a per-thread basis. Multiple threads do not overwrite each other's
|
||||
//last-error code.
|
||||
//N.B.: Error code will be reset after function call
|
||||
extern "C" P7_EXPORT eP7_Error __cdecl P7_Last_Error();
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// P7 Crash processor //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//This function setup crash handler to catch and process exceptions like
|
||||
// * access violation/segmentation fault
|
||||
// * division by zero
|
||||
// * pure virtual call
|
||||
// * etc.
|
||||
//When crash occurs handler will call P7_Exceptional_Flush function automatically
|
||||
extern "C" P7_EXPORT void __cdecl P7_Set_Crash_Handler();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//This function clears crash handler
|
||||
extern "C" P7_EXPORT void __cdecl P7_Clr_Crash_Handler();
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Function allows to flush (deliver) not delivered/saved P7 buffers for all
|
||||
//opened clients and related channels owned by process in CASE OF your app/proc.
|
||||
//crash.
|
||||
//This function do not call system memory allocation functions only writes to
|
||||
//file/socket.
|
||||
//Classical scenario: your application has been crushed, you catch the moment of
|
||||
//crush and call this function once.
|
||||
//Has to be used if integrator implements own crash handling mechanism.
|
||||
//N.B.: DO NOT USE OTHER P7 FUNCTION AFTER CALLING OF THIS FUNCTION
|
||||
//See documentation for details.
|
||||
extern "C" P7_EXPORT void __cdecl P7_Exceptional_Flush();
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Function allows to flush (deliver) not delivered/saved P7 buffers for all
|
||||
//opened clients and related channels owned by process. Please do not use this
|
||||
//function often, it may reduce performance.
|
||||
extern "C" P7_EXPORT void __cdecl P7_Flush();
|
||||
|
||||
|
||||
#endif //P7_CLIENT_H
|
||||
641
p7lib/Headers/P7_Cproxy.h
Normal file
641
p7lib/Headers/P7_Cproxy.h
Normal file
@ -0,0 +1,641 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// This header file provides access to P7 library functionality from C language/
|
||||
// or from any other language using dll/so interface /
|
||||
// /
|
||||
// +-------------------+ /
|
||||
// | Sink | /
|
||||
// | * Network (Baical)| /
|
||||
// | * FileBin | /
|
||||
// | * FileTxt | /
|
||||
// | * Console | /
|
||||
// | * Syslog | /
|
||||
// | * Auto | /
|
||||
// | * Null | /
|
||||
// +---------^---------+ /
|
||||
// | /
|
||||
// | /
|
||||
// +---------+---------+ /
|
||||
// | P7 Client | /
|
||||
// | [ Channels ] | /
|
||||
// | +-+ +-+ +--+ | /
|
||||
// | |0| |1| ...|31| | /
|
||||
// | +^+ +^+ +-^+ | /
|
||||
// +---|---|-------|---+ /
|
||||
// | | | /
|
||||
// +-----+ | +----------+ /
|
||||
// | | | /
|
||||
// | | | /
|
||||
// +---+---+ +---+--------+ +---+---+ /
|
||||
// | Trace | | Telemetry | | Trace | /
|
||||
// |Channel| | channel | ... |Channel| /
|
||||
// +-------+ +------------+ +-------+ /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Documentation is located in <P7>/Documentation/P7.pdf //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef P7_PROXY_H
|
||||
#define P7_PROXY_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// P7 client //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
typedef void* hP7_Client;
|
||||
|
||||
typedef tUINT64 (__cdecl *fnGet_Time_Stamp)(void *i_pContext);
|
||||
typedef void (__cdecl *fnConnect)(void *i_pContext, tBOOL i_bConnected);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Client_Create - function creates new P7 client, client is used as transport
|
||||
//engine for telemetry & trace channels, every client can handle up to 32
|
||||
//channels.
|
||||
//See documentation for details.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//N.B: P7 client in addition will analyze your application command line and
|
||||
// arguments specified through command line will have higher priority then
|
||||
// i_sArgs arguments
|
||||
extern P7_EXPORT hP7_Client __cdecl P7_Client_Create(const tXCHAR *i_pArgs);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef hP7_Client (__cdecl *fnP7_Client_Create)(const tXCHAR *i_pArgs);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//This functions allows you to get P7 client instance if it was created by
|
||||
//someone else inside current process and shared using P7_Client_Share() func.
|
||||
//If no instance was registered inside current process - function will return
|
||||
//NULL. Do not forget to call P7_Client_Free() when you finish your work.
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT hP7_Client __cdecl P7_Client_Get_Shared(const tXCHAR *i_pName);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef hP7_Client (__cdecl *fnP7_Client_Get_Shared)(const tXCHAR *i_pName);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Client_Share - function to share current P7 client object in address space
|
||||
//of the current process, to get shared client use function P7_Client_Get_Shared
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tBOOL __cdecl P7_Client_Share(hP7_Client i_hClient,
|
||||
const tXCHAR *i_pName
|
||||
);
|
||||
//dll/so function prototype
|
||||
typedef tBOOL (__cdecl *fnP7_Client_Share)(hP7_Client i_hClient,
|
||||
const tXCHAR *i_pName
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Client_Flush - function allows to flush (deliver) not delivered/saved P7
|
||||
//buffers for current client. Please do not use this function often, it may
|
||||
//reduce performance.
|
||||
|
||||
extern P7_EXPORT void __cdecl P7_Client_Flush(hP7_Client i_hClient);
|
||||
//dll/so function prototype
|
||||
typedef void (__cdecl *fnP7_Client_Flush)(hP7_Client i_hClient);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Client_Add_Ref - increase reference counter for the client
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tINT32 __cdecl P7_Client_Add_Ref(hP7_Client i_hClient);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tINT32 (__cdecl *fnP7_Client_Add_Ref)(hP7_Client i_hClient);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Client_Release - function release the client, reference counter technology
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tINT32 __cdecl P7_Client_Release(hP7_Client i_hClient);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tINT32 (__cdecl *fnP7_Client_Release)(hP7_Client i_hClient);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// P7 Crash processor //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//This function setup crash handler to catch and process exceptions like
|
||||
// * access violation/segmentation fault
|
||||
// * division by zero
|
||||
// * pure virtual call
|
||||
// * etc.
|
||||
//When crash occurs handler will call P7_Exceptional_Flush function automatically
|
||||
extern P7_EXPORT void __cdecl P7_Set_Crash_Handler();
|
||||
|
||||
//dll/so function prototype
|
||||
typedef void (__cdecl *fnP7_Set_Crash_Handler)();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//This function clears crash handler
|
||||
extern P7_EXPORT void __cdecl P7_Clr_Crash_Handler();
|
||||
|
||||
//dll/so function prototype
|
||||
typedef void (__cdecl *fnP7_Clr_Crash_Handler)();
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Function allows to flush (deliver) not delivered/saved P7 buffers for all
|
||||
//opened clients and related channels owned by process in CASE OF your app/proc.
|
||||
//crash.
|
||||
//This function do not call system memory allocation functions only writes to
|
||||
//file/socket.
|
||||
//Classical scenario: your application has been crushed, you catch the moment of
|
||||
//crush and call this function once.
|
||||
//Has to be used if integrator implements own crash handling mechanism.
|
||||
//N.B.: DO NOT USE OTHER P7 FUNCTION AFTER CALLING OF THIS FUNCTION
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT void __cdecl P7_Exceptional_Flush();
|
||||
|
||||
//dll/so function prototype
|
||||
typedef void (__cdecl *fnP7_Exceptional_Flush)();
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Function allows to flush (deliver) not delivered/saved P7 buffers for all
|
||||
//opened clients and related channels owned by process. Please do not use this
|
||||
//function offten, it may reduce performance.
|
||||
extern P7_EXPORT void __cdecl P7_Flush();
|
||||
|
||||
//dll/so function prototype
|
||||
typedef void (__cdecl *fnP7_Flush)();
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// P7 Telemetry //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef void* hP7_Telemetry;
|
||||
|
||||
typedef void (__cdecl *fnTelemetry_Enable)(void *i_pContext, tUINT16 i_wId, tBOOL i_bEnable);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *pContext; //context to be passed back to callbacks
|
||||
tUINT64 qwTimestamp_Frequency; //count ticks per second, works in cooperation with pTimestamp_Callback
|
||||
fnGet_Time_Stamp pTimestamp_Callback; //callback for getting user timestamps, works in cooperation with qwTimestamp_Frequency
|
||||
fnTelemetry_Enable pEnable_Callback; //Callback to notify user when counter has been enables/disabled remotely
|
||||
fnConnect pConnect_Callback; //Callback notifies user when connection with Baical is established/closed
|
||||
} stTelemetry_Conf;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Telemetry_Create - function create new instance of IP7_Telemetry object
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT hP7_Telemetry __cdecl P7_Telemetry_Create(hP7_Client i_hClient,
|
||||
const tXCHAR *i_pName,
|
||||
const stTelemetry_Conf *i_pConf
|
||||
);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef hP7_Telemetry (__cdecl *fnP7_Telemetry_Create)(hP7_Client i_hClient,
|
||||
const tXCHAR *i_pName,
|
||||
const stTelemetry_Conf *i_pConf
|
||||
);
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Telemetry_Share - function to share current P7 telemetry object in address
|
||||
//space of the current process, to get shared client use function
|
||||
//P7_Telemetry_Get_Shared
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tBOOL __cdecl P7_Telemetry_Share(hP7_Telemetry i_hTelemetry,
|
||||
const tXCHAR *i_pName
|
||||
);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tBOOL (__cdecl *fnP7_Telemetry_Share)(hP7_Telemetry i_hTelemetry,
|
||||
const tXCHAR *i_pName
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//This functions allow you to get P7 telemetry instance if it was created by
|
||||
//someone other inside current process. If no instance was registered inside
|
||||
//current process - function will return NULL. Do not forget to call Release
|
||||
//on interface when you finish your work
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT hP7_Telemetry __cdecl P7_Telemetry_Get_Shared(const tXCHAR *i_pName);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef hP7_Telemetry (__cdecl *fnP7_Telemetry_Get_Shared)(const tXCHAR *i_pName);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Telemetry_Create_Counter - create new telemetry counter, max amount of
|
||||
//counters - 256, if you need more - we recommends you to create another telem.
|
||||
//channel using P7_Telemetry_Create() function
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tBOOL __cdecl P7_Telemetry_Create_Counter(hP7_Telemetry i_hTelemetry,
|
||||
const tXCHAR *i_pName,
|
||||
tDOUBLE i_dbMin,
|
||||
tDOUBLE i_dbAlarmMin,
|
||||
tDOUBLE i_dbMax,
|
||||
tDOUBLE i_dbAlarmMax,
|
||||
tBOOL i_bOn,
|
||||
tUINT16 *o_pID
|
||||
);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tBOOL (__cdecl *fnP7_Telemetry_Create_Counter)(hP7_Telemetry i_hTelemetry,
|
||||
const tXCHAR *i_pName,
|
||||
tDOUBLE i_dbMin,
|
||||
tDOUBLE i_dbAlarmMin,
|
||||
tDOUBLE i_dbMax,
|
||||
tDOUBLE i_dbAlarmMax,
|
||||
tBOOL i_bOn,
|
||||
tUINT16 *o_pID
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Telemetry_Put_Value - add counter smaple value
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tBOOL __cdecl P7_Telemetry_Put_Value(hP7_Telemetry i_hTelemetry,
|
||||
tUINT16 i_wCounter_ID,
|
||||
tDOUBLE i_dbValue
|
||||
);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tBOOL (__cdecl *fnP7_Telemetry_Put_Value)(hP7_Telemetry i_hTelemetry,
|
||||
tUINT16 i_wCounter_ID,
|
||||
tDOUBLE i_dbValue
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Telemetry_Find_Counter - find counter ID by name
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tBOOL __cdecl P7_Telemetry_Find_Counter(hP7_Telemetry i_hTelemetry,
|
||||
const tXCHAR *i_pName,
|
||||
tUINT16 *o_pCounter_ID
|
||||
);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tBOOL (__cdecl *fnP7_Telemetry_Find_Counter)(hP7_Telemetry i_hTelemetry,
|
||||
const tXCHAR *i_pName,
|
||||
tUINT16 *o_pCounter_ID
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Telemetry_Add_Ref - increase reference counter for the telemetry channel
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tINT32 __cdecl P7_Telemetry_Add_Ref(hP7_Telemetry i_hTelemetry);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tINT32 (__cdecl *fnP7_Telemetry_Add_Ref)(hP7_Telemetry i_hTelemetry);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Telemetry_Release - function releases the telemetry, reference counter
|
||||
//technology is used, it mean the same client instance can be used from few
|
||||
//program parts, and every instance has to be released to completely destroy the
|
||||
//P7 telemetry object
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tINT32 __cdecl P7_Telemetry_Release(hP7_Telemetry i_hTelemetry);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tINT32 (__cdecl *fnP7_Telemetry_Release)(hP7_Telemetry i_hTelemetry);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// P7 Trace //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef void* hP7_Trace;
|
||||
typedef void* hP7_Trace_Module;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Trace levels:
|
||||
#define P7_TRACE_LEVEL_TRACE 0
|
||||
#define P7_TRACE_LEVEL_DEBUG 1
|
||||
#define P7_TRACE_LEVEL_INFO 2
|
||||
#define P7_TRACE_LEVEL_WARNING 3
|
||||
#define P7_TRACE_LEVEL_ERROR 4
|
||||
#define P7_TRACE_LEVEL_CRITICAL 5
|
||||
|
||||
|
||||
typedef void (__cdecl *fnTrace_Verbosity)(void *i_pContext,
|
||||
hP7_Trace_Module i_hModule,
|
||||
tUINT32 i_dwVerbosity);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *pContext; //context to be passed back to callbacks
|
||||
tUINT64 qwTimestamp_Frequency; //count ticks per second, works in cooperation with pTimestamp_Callback
|
||||
fnGet_Time_Stamp pTimestamp_Callback; //callback for getting user timestamps, works in cooperation with qwTimestamp_Frequency
|
||||
fnTrace_Verbosity pVerbosity_Callback; //Callback to notify user when verbosity has been changed
|
||||
fnConnect pConnect_Callback; //Callback notifies user when connection with Baical is established/closed
|
||||
} stTrace_Conf;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_TRACE_ADD macro for trace function calling simplification
|
||||
#define P7_TRACE_ADD(i_hTrace,\
|
||||
i_wID,\
|
||||
i_eLevel,\
|
||||
i_dwModuleID,\
|
||||
i_pFormat,\
|
||||
...)\
|
||||
P7_Trace_Add(i_hTrace,\
|
||||
i_wID,\
|
||||
i_eLevel,\
|
||||
i_dwModuleID,\
|
||||
(tUINT16)__LINE__,\
|
||||
__FILE__,\
|
||||
__FUNCTION__,\
|
||||
i_pFormat,\
|
||||
__VA_ARGS__)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Trace_Create_Trace - function create new instance of IP7_Trace object
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT hP7_Trace __cdecl P7_Trace_Create(hP7_Client i_hClient,
|
||||
const tXCHAR *i_pName,
|
||||
const stTrace_Conf *i_pConf
|
||||
);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef hP7_Trace (__cdecl *fnP7_Trace_Create)(hP7_Client i_hClient,
|
||||
const tXCHAR *i_pName,
|
||||
const stTrace_Conf *i_pConf
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//This functions allow you to get P7 trace instance if it was created by someone
|
||||
//other inside current process. If no instance was registered inside current
|
||||
//process - function will return NULL. Do not forget to call Release
|
||||
//on interface when you finish your work
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT hP7_Trace __cdecl P7_Trace_Get_Shared(const tXCHAR *i_pName);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef hP7_Trace (__cdecl *fnP7_Trace_Get_Shared)(const tXCHAR *i_pName);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Trace_Share - function to share current P7 trace object in address space of
|
||||
//the current process, to get shared trace channel use function
|
||||
//P7_Trace_Get_Shared()
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tBOOL __cdecl P7_Trace_Share(hP7_Trace i_hTrace,
|
||||
const tXCHAR *i_pName
|
||||
);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tBOOL (__cdecl *fnP7_Trace_Share)(hP7_Trace i_hTrace,
|
||||
const tXCHAR *i_pName
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Trace_Set_Verbosity - function to set minimal trace verbosity, all traces
|
||||
//with less priority will be rejected by channel. You may set verbosity online
|
||||
//from Baical server
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT void __cdecl P7_Trace_Set_Verbosity(hP7_Trace i_hTrace,
|
||||
hP7_Trace_Module i_hModule,
|
||||
tUINT32 i_dwVerbosity
|
||||
);
|
||||
|
||||
|
||||
//dll/so function prototype
|
||||
typedef void (__cdecl *fnP7_Trace_Set_Verbosity)(hP7_Trace i_hTrace,
|
||||
hP7_Trace_Module i_hModule,
|
||||
tUINT32 i_dwVerbosity
|
||||
);
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Trace_Get_Verbosity - function to get minimal trace verbosity
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tUINT32 __cdecl P7_Trace_Get_Verbosity(hP7_Trace i_hTrace,
|
||||
hP7_Trace_Module i_hModule
|
||||
);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tUINT32 (__cdecl *fnP7_Trace_Get_Verbosity)(hP7_Trace i_hTrace,
|
||||
hP7_Trace_Module i_hModule);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Trace_Register_Thread - function used to specify name for current/special
|
||||
//thread.
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tBOOL __cdecl P7_Trace_Register_Thread(hP7_Trace i_hTrace,
|
||||
const tXCHAR *i_pName,
|
||||
tUINT32 i_dwThreadId
|
||||
);
|
||||
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tBOOL (__cdecl *fnP7_Trace_Register_Thread)(hP7_Trace i_hTrace,
|
||||
const tXCHAR *i_pName,
|
||||
tUINT32 i_dwThreadId
|
||||
);
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Trace_Unregister_Thread - function used to unregister current/special thread.
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tBOOL __cdecl P7_Trace_Unregister_Thread(hP7_Trace i_hTrace,
|
||||
tUINT32 i_dwThreadId
|
||||
);
|
||||
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tBOOL (__cdecl *fnP7_Trace_Unregister_Thread)(hP7_Trace i_hTrace,
|
||||
tUINT32 i_dwThreadId
|
||||
);
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Trace_Register_Module - function used to register module for following usage
|
||||
//by P7_Trace_Add/P7_Trace_Embedded/P7_Trace_Managed functions
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT hP7_Trace_Module __cdecl P7_Trace_Register_Module(hP7_Trace i_hTrace,
|
||||
const tXCHAR *i_pName
|
||||
);
|
||||
|
||||
|
||||
//dll/so function prototype
|
||||
typedef hP7_Trace_Module (__cdecl *fnP7_Trace_Register_Module)(hP7_Trace i_hTrace,
|
||||
const tXCHAR *i_pName
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Trace_Add - send trace message to Baical server.
|
||||
//You may use macro P7_TRACE_ADD to simplify calling of this function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//N.B.: DO NOT USE VARIABLE for format string! You should always use CONSTANT
|
||||
// TEXT like L"My Format %d, %s"
|
||||
// USE THIS FUNCTION ONLY FROM C/C++ LANGUAGES! If you want to use trace
|
||||
// functionality from other languages please call Trace_Managed() function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tBOOL __cdecl P7_Trace_Add(hP7_Trace i_hTrace,
|
||||
tUINT16 i_wTrace_ID,
|
||||
tUINT32 i_dwLevel,
|
||||
hP7_Trace_Module i_hModule,
|
||||
tUINT16 i_wLine,
|
||||
const char *i_pFile,
|
||||
const char *i_pFunction,
|
||||
const tXCHAR *i_pFormat,
|
||||
...
|
||||
);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tBOOL (__cdecl *fnP7_Trace_Add)(hP7_Trace i_hTrace,
|
||||
tUINT16 i_wTrace_ID,
|
||||
tUINT32 i_dwLevel,
|
||||
hP7_Trace_Module i_hModule,
|
||||
tUINT16 i_wLine,
|
||||
const char *i_pFile,
|
||||
const char *i_pFunction,
|
||||
const tXCHAR *i_pFormat,
|
||||
...
|
||||
);
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Trace_Embedded - send trace message to Baical server.
|
||||
//this function is a copy of P7_Trace_Add function, but it is dedicated for
|
||||
//embedding into your log function with variable arguments list:
|
||||
//Usage scenario: you already have function with variable arguments, but body of
|
||||
//your function may be replaced by Trace_Embedded.
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tBOOL __cdecl P7_Trace_Embedded(hP7_Trace i_hTrace,
|
||||
tUINT16 i_wTrace_ID,
|
||||
tUINT32 i_dwLevel,
|
||||
hP7_Trace_Module i_hModule,
|
||||
tUINT16 i_wLine,
|
||||
const char *i_pFile,
|
||||
const char *i_pFunction,
|
||||
const tXCHAR **i_ppFormat,
|
||||
va_list *i_pVa_List
|
||||
);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tBOOL (__cdecl *fnP7_Trace_Embedded)(hP7_Trace i_hTrace,
|
||||
tUINT16 i_wTrace_ID,
|
||||
tUINT32 i_dwLevel,
|
||||
hP7_Trace_Module i_hModule,
|
||||
tUINT16 i_wLine,
|
||||
const char *i_pFile,
|
||||
const char *i_pFunction,
|
||||
const tXCHAR **i_ppFormat,
|
||||
va_list *i_pVa_List
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Trace_Managed - send trace message to Baical server.
|
||||
//This function is intended for use by MANAGED languages like C#, Python, etc
|
||||
//It is slightly slower than P7_Trace_Add.
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tBOOL __cdecl P7_Trace_Managed(hP7_Trace i_hTrace,
|
||||
tUINT16 i_wTrace_ID,
|
||||
tUINT32 i_dwLevel,
|
||||
hP7_Trace_Module i_hModule,
|
||||
tUINT16 i_wLine,
|
||||
const tXCHAR *i_pFile,
|
||||
const tXCHAR *i_pFunction,
|
||||
const tXCHAR *i_pMessage
|
||||
);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tBOOL (__cdecl *fnP7_Trace_Managed)(hP7_Trace i_hTrace,
|
||||
tUINT16 i_wTrace_ID,
|
||||
tUINT32 i_dwLevel,
|
||||
hP7_Trace_Module i_hModule,
|
||||
tUINT16 i_wLine,
|
||||
const tXCHAR *i_pFile,
|
||||
const tXCHAR *i_pFunction,
|
||||
const tXCHAR *i_pMessage
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Trace_Add_Ref - increase reference counter for the telemetry channel
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tINT32 __cdecl P7_Trace_Add_Ref(hP7_Trace i_hTrace);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tINT32 (__cdecl *fnP7_Trace_Add_Ref)(hP7_Trace i_hTrace);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Trace_Release - function releases the trace object, reference counter
|
||||
//technology is used, it mean the same trace instance can be used from few
|
||||
//program parts, and every instance has to be released to completely destroy the
|
||||
//P7 trace object
|
||||
//See documentation for details.
|
||||
extern P7_EXPORT tINT32 __cdecl P7_Trace_Release(hP7_Trace i_hTrace);
|
||||
|
||||
//dll/so function prototype
|
||||
typedef tINT32 (__cdecl *fnP7_Trace_Release)(hP7_Trace i_hTrace);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //P7_PROXY_H
|
||||
490
p7lib/Headers/P7_Extensions.h
Normal file
490
p7lib/Headers/P7_Extensions.h
Normal file
@ -0,0 +1,490 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// P7 extensions - interfaces to some additional functionality /
|
||||
// - IP7_Trace : traces formatting and delivery to Baical server /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef P7_EXTENSIONS_H
|
||||
#define P7_EXTENSIONS_H
|
||||
|
||||
|
||||
#define P7_EXTENSION_TYPE_BITS_COUNT (5)
|
||||
#define P7_EXTENSION_SUB_TYPE_BITS_COUNT (5)
|
||||
#define P7_EXTENSION_PACKET_SIZE_BITS_COUNT (22)
|
||||
|
||||
#define P7_EXTENSION_MAX_TYPES (1 << P7_EXTENSION_TYPE_BITS_COUNT)
|
||||
|
||||
#define P7TRACE_NAME_LENGTH (64)
|
||||
#define P7TRACE_THREAD_NAME_LENGTH (48)
|
||||
#define P7TRACE_MODULE_NAME_LENGTH (54)
|
||||
#define P7TELEMETRY_NAME_LENGTH (64)
|
||||
|
||||
#define P7TELEMETRY_COUNTER_NAME_LENGTH_V1 (64)
|
||||
#define P7TELEMETRY_COUNTERS_MAX_COUNT_V1 ((tUINT8)~((tUINT8)0))
|
||||
#define P7TELEMETRY_INVALID_ID_V1 (P7TELEMETRY_COUNTERS_MAX_COUNT_V1 - 1)
|
||||
|
||||
#define P7TELEMETRY_INVALID_ID_V2 ((tUINT16)~((tUINT16)0))
|
||||
#define P7TELEMETRY_COUNTERS_MAX_COUNT_V2 ((tUINT16)~((tUINT16)0))
|
||||
#define P7TELEMETRY_COUNTER_NAME_MIN_LENGTH_V2 (2)
|
||||
|
||||
|
||||
#define P7TRACE_INFO_FLAG_BIG_ENDIAN (0x0001)
|
||||
#define P7TRACE_INFO_FLAG_UNSORTED (0x0002)
|
||||
#define P7TRACE_INFO_FLAG_EXTENTION (0x0004)
|
||||
#define P7TRACE_INFO_FLAG_TIME_ZONE (0x0008)
|
||||
|
||||
#define P7TELEMETRY_FLAG_EXTENTION (0x0001)
|
||||
#define P7TELEMETRY_FLAG_TIME_ZONE (0x0002)
|
||||
|
||||
|
||||
enum eTrace_Arg_Type
|
||||
{
|
||||
P7TRACE_ARG_TYPE_UNK = 0x00,
|
||||
P7TRACE_ARG_TYPE_CHAR = 0x01,
|
||||
P7TRACE_ARG_TYPE_INT8 = 0x01,
|
||||
P7TRACE_ARG_TYPE_CHAR16 ,//(0x02)
|
||||
P7TRACE_ARG_TYPE_INT16 ,//(0x03)
|
||||
P7TRACE_ARG_TYPE_INT32 ,//(0x04)
|
||||
P7TRACE_ARG_TYPE_INT64 ,//(0x05)
|
||||
P7TRACE_ARG_TYPE_DOUBLE ,//(0x06)
|
||||
P7TRACE_ARG_TYPE_PVOID ,//(0x07)
|
||||
P7TRACE_ARG_TYPE_USTR16 ,//(0x08) //unicode - UTF16 string
|
||||
P7TRACE_ARG_TYPE_STRA ,//(0x09) //ASCII string
|
||||
P7TRACE_ARG_TYPE_USTR8 ,//(0x0A) //unicode - UTF8 string
|
||||
P7TRACE_ARG_TYPE_USTR32 ,//(0x0B) //unicode - UTF32 string
|
||||
P7TRACE_ARG_TYPE_CHAR32 ,//(0x0C)
|
||||
P7TRACE_ARG_TYPE_INTMAX ,//(0x0D)
|
||||
|
||||
P7TRACE_ARGS_COUNT
|
||||
};
|
||||
|
||||
|
||||
#if defined(GTX64)
|
||||
#define SIZE_OF_ARG(t) ( (sizeof(t) + 8 - 1) & ~(8 - 1) )
|
||||
|
||||
typedef tUINT64 tKeyType;
|
||||
#else
|
||||
#define SIZE_OF_ARG(t) ( (sizeof(t) + 4 - 1) & ~(4 - 1) )
|
||||
|
||||
typedef tUINT32 tKeyType;
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Data types, we can transmit different packets types, here are the list
|
||||
// of all supported for the moment packet types
|
||||
enum eP7User_Type
|
||||
{
|
||||
EP7USER_TYPE_TRACE = 0,
|
||||
EP7USER_TYPE_TELEMETRY_V1 ,
|
||||
EP7USER_TYPE_TELEMETRY_V2 ,
|
||||
|
||||
EP7USER_TYPE_MAX = P7_EXTENSION_MAX_TYPES
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
enum eP7Trace_Type
|
||||
{
|
||||
EP7TRACE_TYPE_INFO = 0, //Client->Server
|
||||
EP7TRACE_TYPE_DESC , //Client->Server
|
||||
EP7TRACE_TYPE_DATA , //Client->Server
|
||||
EP7TRACE_TYPE_VERB , //Client->Server->Client
|
||||
EP7TRACE_TYPE_CLOSE , //Client->Server
|
||||
EP7TRACE_TYPE_THREAD_START , //Client->Server
|
||||
EP7TRACE_TYPE_THREAD_STOP , //Client->Server
|
||||
EP7TRACE_TYPE_MODULE , //Client->Server
|
||||
EP7TRACE_TYPE_DELETE , //Server->Client
|
||||
EP7TRACE_TYPE_UTC_OFFS , //Client->Server
|
||||
|
||||
EP7TRACE_TYPE_MAX = 32
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
enum eP7Trace_Ext
|
||||
{
|
||||
EP7TRACE_EXT_MODULE_ID = 0,
|
||||
EP7TRACE_EXT_MAX = 256
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
enum eP7Tel_Type
|
||||
{
|
||||
EP7TEL_TYPE_INFO = 0, //Client->Server
|
||||
EP7TEL_TYPE_COUNTER , //Client->Server
|
||||
EP7TEL_TYPE_VALUE , //Client->Server
|
||||
EP7TEL_TYPE_ENABLE , //Server->Client
|
||||
EP7TEL_TYPE_CLOSE , //Client->Server
|
||||
EP7TEL_TYPE_DELETE , //Server->Client
|
||||
EP7TEL_TYPE_UTC_OFFS , //Client->Server
|
||||
|
||||
EP7TEL_TYPE_MAX = 32
|
||||
};
|
||||
|
||||
|
||||
PRAGMA_PACK_ENTER(4) //alignment is now 4, MS Only//////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// common user header for extensions (like trace or telemetry)
|
||||
|
||||
#define INIT_EXT_HEADER(iHeaderRaw, iType, iSubType, iSize)\
|
||||
iHeaderRaw.dwBits = \
|
||||
(((iType) & ((1 << P7_EXTENSION_TYPE_BITS_COUNT) - 1)) |\
|
||||
(((iSubType) & ((1 << P7_EXTENSION_SUB_TYPE_BITS_COUNT) - 1)) << P7_EXTENSION_TYPE_BITS_COUNT) |\
|
||||
(((iSize) & ((1 << P7_EXTENSION_PACKET_SIZE_BITS_COUNT) - 1)) << (P7_EXTENSION_TYPE_BITS_COUNT + P7_EXTENSION_SUB_TYPE_BITS_COUNT)))
|
||||
|
||||
#define GET_EXT_HEADER_SIZE(iHeaderRaw)\
|
||||
(iHeaderRaw.dwBits >> (P7_EXTENSION_TYPE_BITS_COUNT + P7_EXTENSION_SUB_TYPE_BITS_COUNT))
|
||||
|
||||
#define GET_EXT_HEADER_TYPE(iHeaderRaw)\
|
||||
(iHeaderRaw.dwBits & ((1 << P7_EXTENSION_TYPE_BITS_COUNT) - 1))
|
||||
|
||||
#define GET_EXT_HEADER_SUBTYPE(iHeaderRaw)\
|
||||
((iHeaderRaw.dwBits >> P7_EXTENSION_TYPE_BITS_COUNT) & ((1 << P7_EXTENSION_SUB_TYPE_BITS_COUNT) - 1))
|
||||
|
||||
#define SET_EXT_HEADER_SIZE(iHeaderRaw, iSize)\
|
||||
iHeaderRaw.dwBits = \
|
||||
(iHeaderRaw.dwBits & ((1 << (P7_EXTENSION_TYPE_BITS_COUNT + P7_EXTENSION_SUB_TYPE_BITS_COUNT)) - 1)) |\
|
||||
(((iSize) & ((1 << P7_EXTENSION_PACKET_SIZE_BITS_COUNT) - 1)) << (P7_EXTENSION_TYPE_BITS_COUNT + P7_EXTENSION_SUB_TYPE_BITS_COUNT))
|
||||
|
||||
struct sP7Ext_Header
|
||||
{
|
||||
tUINT32 dwType :P7_EXTENSION_TYPE_BITS_COUNT; //eP7User_Type
|
||||
tUINT32 dwSubType:P7_EXTENSION_SUB_TYPE_BITS_COUNT;
|
||||
//max 4 mb, value should include size of this header
|
||||
tUINT32 dwSize :P7_EXTENSION_PACKET_SIZE_BITS_COUNT;
|
||||
//At the end of structure we put serialized data
|
||||
} ATTR_PACK(4);
|
||||
|
||||
struct sP7Ext_Raw //mapping of sP7Ext_Header
|
||||
{
|
||||
tUINT32 dwBits;
|
||||
} ATTR_PACK(4);
|
||||
|
||||
GASSERT(sizeof(sP7Ext_Header) == sizeof(sP7Ext_Raw));
|
||||
|
||||
//N.B.: extension packets can follow one by one in data packets.
|
||||
PRAGMA_PACK_EXIT()//4///////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
PRAGMA_PACK_ENTER(2) //alignment is now 2, MS Only//////////////////////////////
|
||||
|
||||
#define P7_DAMP_FILE_MARKER_V1 (0x45D2AC71ECF32CA6ULL)
|
||||
#define P7_DAMP_FILE_HOST_LENGTH (256)
|
||||
#define P7_DAMP_FILE_PROCESS_LENGTH (256)
|
||||
|
||||
//P7 damp file header
|
||||
struct sP7File_Header
|
||||
{
|
||||
tUINT64 qwMarker;
|
||||
tUINT32 dwProcess_ID;
|
||||
tUINT32 dwProcess_Start_Time_Hi;
|
||||
tUINT32 dwProcess_Start_Time_Lo;
|
||||
tWCHAR pProcess_Name[P7_DAMP_FILE_PROCESS_LENGTH];
|
||||
tWCHAR pHost_Name[P7_DAMP_FILE_HOST_LENGTH];
|
||||
} ATTR_PACK(2);
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Trace //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//trace info header
|
||||
struct sP7Trace_Info
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
//Contains a 64-bit value representing the number of 100-nanosecond intervals
|
||||
//since January 1, 1601 (UTC). In windows we use FILETIME structure for
|
||||
//representing
|
||||
tUINT32 dwTime_Hi;
|
||||
tUINT32 dwTime_Lo;
|
||||
//Hi resolution timer value, we get this value when we retrieve current time.
|
||||
//using difference between this value and timer value for every trace we can
|
||||
//calculate time of the trace event with hi resolution
|
||||
tUINT64 qwTimer_Value;
|
||||
//timer's count heartbeats in second
|
||||
tUINT64 qwTimer_Frequency;
|
||||
tUINT64 qwFlags;
|
||||
tWCHAR pName[P7TRACE_NAME_LENGTH];
|
||||
} ATTR_PACK(2);
|
||||
|
||||
|
||||
//this structure describe each argument inside variable arguments list
|
||||
//all arguments are serialized data block
|
||||
struct sP7Trace_Arg
|
||||
{
|
||||
//argument's type - one of P7TRACE_ARG_TYPE_XXX
|
||||
tUINT8 bType;
|
||||
//Size - how many bytes is used by argument inside block, this value is not
|
||||
// directly depend on type, usually it depend on processor architecture
|
||||
// for example "char" on WIN32 this is 4 bytes, but for EventTrace
|
||||
// engine this is only 1 byte.
|
||||
// N.B.: All strings has 0 size.
|
||||
tUINT8 bSize;
|
||||
} ATTR_PACK(2);
|
||||
|
||||
//trace description header
|
||||
struct sP7Trace_Format
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
tUINT16 wID;
|
||||
tUINT16 wLine;
|
||||
tUINT16 wModuleID; //Module ID, who send trace
|
||||
tUINT16 wArgs_Len; //arguments count
|
||||
//At the end of structure we put serialized data:
|
||||
//sP7Trace_Arg [dwArgs_Len] - array of arguments
|
||||
//wchar_t Format[] - null terminated string
|
||||
//char FileName[] - null terminated string
|
||||
//char FunctionName[] - null terminated string
|
||||
} ATTR_PACK(2);
|
||||
|
||||
//trace data header
|
||||
struct sP7Trace_Data
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
tUINT16 wID; //trace ID
|
||||
tUINT8 bLevel; //eP7Trace_Level
|
||||
tUINT8 bProcessor; //Processor number
|
||||
tUINT32 dwThreadID; //Thread ID
|
||||
tUINT32 dwSequence; //sequence number
|
||||
tUINT64 qwTimer; //High resolution timer value
|
||||
//At the end of structure we put serialized data:
|
||||
// - trace variable arguments values
|
||||
// - extensions [data X bits][type 8 bits], [data X bits][type 8 bits], ... [count 8 bits]
|
||||
} ATTR_PACK(2);
|
||||
|
||||
//trace ext header for Module ID
|
||||
struct sP7Trace_Ext_Mid
|
||||
{
|
||||
tUINT16 wMID;
|
||||
} ATTR_PACK(2);
|
||||
|
||||
|
||||
//trace verbosity header
|
||||
struct sP7Trace_Verb
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
eP7Trace_Level eVerbosity;
|
||||
tUINT16 wModuleID;
|
||||
} ATTR_PACK(2);
|
||||
|
||||
|
||||
//Thread start info
|
||||
struct sP7Trace_Thread_Start
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
tUINT32 dwThreadID; //Thread ID
|
||||
tUINT64 qwTimer; //High resolution timer value
|
||||
char pName[P7TRACE_THREAD_NAME_LENGTH]; //Thread name (UTF-8)
|
||||
} ATTR_PACK(2);
|
||||
|
||||
//Thread stop info
|
||||
struct sP7Trace_Thread_Stop
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
tUINT32 dwThreadID; //Thread ID
|
||||
tUINT64 qwTimer; //High resolution timer value
|
||||
} ATTR_PACK(2);
|
||||
|
||||
//Module info
|
||||
struct sP7Trace_Module
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
tUINT16 wModuleID;
|
||||
eP7Trace_Level eVerbosity;
|
||||
char pName[P7TRACE_MODULE_NAME_LENGTH]; //name (UTF-8)
|
||||
} ATTR_PACK(2);
|
||||
|
||||
|
||||
//Time zone description
|
||||
struct sP7Trace_Utc_Offs
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
tINT32 iUtcOffsetSec;
|
||||
} ATTR_PACK(2);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Telemetry //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//telemetry info header
|
||||
struct sP7Tel_Info
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
//Contains a 64-bit value representing the number of 100-nanosecond intervals
|
||||
//since January 1, 1601 (UTC). In windows we use FILETIME structure for
|
||||
//representing
|
||||
tUINT32 dwTime_Hi;
|
||||
tUINT32 dwTime_Lo;
|
||||
//Hi resolution timer value, we get this value when we retrieve current time.
|
||||
//using difference between this value and timer value for every trace we can
|
||||
//calculate time of the trace event with hi resolution
|
||||
tUINT64 qwTimer_Value;
|
||||
//timer's count heartbeats in second
|
||||
tUINT64 qwTimer_Frequency;
|
||||
tUINT64 qwFlags;
|
||||
tWCHAR pName[P7TELEMETRY_NAME_LENGTH];
|
||||
} ATTR_PACK(2);
|
||||
|
||||
|
||||
//Telemetry counter description
|
||||
struct sP7Tel_Counter_v1
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
tUINT8 bID;
|
||||
tUINT8 bOn;
|
||||
tINT64 llMin;
|
||||
tINT64 llMax;
|
||||
tINT64 llAlarm;
|
||||
tWCHAR pName[P7TELEMETRY_COUNTER_NAME_LENGTH_V1];
|
||||
} ATTR_PACK(2);
|
||||
|
||||
|
||||
//Telemetry counter description
|
||||
struct sP7Tel_Counter_v2
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
|
||||
tUINT16 wID;
|
||||
tUINT16 bOn;
|
||||
tDOUBLE dbMin;
|
||||
tDOUBLE dbAlarmMin;
|
||||
tDOUBLE dbMax;
|
||||
tDOUBLE dbAlarmMax;
|
||||
tWCHAR pName[P7TELEMETRY_COUNTER_NAME_MIN_LENGTH_V2];
|
||||
} ATTR_PACK(2);
|
||||
|
||||
//telemetry counter On/Off verbosity header
|
||||
struct sP7Tel_Enable_v1
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
tUINT8 bID;
|
||||
tUINT8 bOn;
|
||||
} ATTR_PACK(2);
|
||||
|
||||
|
||||
//telemetry counter On/Off verbosity header
|
||||
struct sP7Tel_Enable_v2
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
tUINT16 wID;
|
||||
tUINT16 bOn;
|
||||
} ATTR_PACK(2);
|
||||
|
||||
|
||||
//Telemetry counter value
|
||||
struct sP7Tel_Value_v1
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
tUINT8 bID;
|
||||
tUINT8 bSeqN;
|
||||
tUINT64 qwTimer; //High resolution timer value
|
||||
tINT64 llValue;
|
||||
} ATTR_PACK(2);
|
||||
|
||||
//Telemetry counter value
|
||||
struct sP7Tel_Value_v2
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
tUINT16 wID;
|
||||
tUINT16 wSeqN;
|
||||
tUINT64 qwTimer; //High resolution timer value
|
||||
tDOUBLE dbValue;
|
||||
} ATTR_PACK(2);
|
||||
|
||||
|
||||
//Time zone description
|
||||
struct sP7Tel_Utc_Offs_V2
|
||||
{
|
||||
union
|
||||
{
|
||||
sP7Ext_Header sCommon;
|
||||
sP7Ext_Raw sCommonRaw;
|
||||
};
|
||||
tINT32 iUtcOffsetSec;
|
||||
} ATTR_PACK(2);
|
||||
|
||||
|
||||
PRAGMA_PACK_EXIT()//2///////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#endif //P7_EXTENSIONS_H
|
||||
118
p7lib/Headers/P7_Telemetry.h
Normal file
118
p7lib/Headers/P7_Telemetry.h
Normal file
@ -0,0 +1,118 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// P7.Telemetry //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Documentation is located in <P7>/Documentation/P7.pdf //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef P7_TELEMETRY_H
|
||||
#define P7_TELEMETRY_H
|
||||
|
||||
#include "P7_Client.h"
|
||||
#include "P7_Cproxy.h"
|
||||
|
||||
#define TELEMETRY_DEFAULT_SHARED_NAME TM("P7.Telemetry")
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////IP7_Telemetry////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class IP7_Telemetry
|
||||
: public IP7C_Channel
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Create - creates new telemetry counter, max amount of counters per
|
||||
// telemetry instance - 256
|
||||
// See documentation for details.
|
||||
virtual tBOOL Create(const tXCHAR *i_pName,
|
||||
tDOUBLE i_dbMin,
|
||||
tDOUBLE i_dbAlarmMin,
|
||||
tDOUBLE i_dbMax,
|
||||
tDOUBLE i_dbAlarmMax,
|
||||
tBOOL i_bOn,
|
||||
tUINT16 *o_pID
|
||||
) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Add - add counter sample
|
||||
// See documentation for details.
|
||||
virtual tBOOL Add(tUINT16 i_bID, tDOUBLE i_llValue) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Find - find counter ID by name (case sensitive)
|
||||
// See documentation for details.
|
||||
virtual tBOOL Find(const tXCHAR *i_pName, tUINT16 *o_pID) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Set_Enable - enable or disable counter
|
||||
virtual tBOOL Set_Enable(tUINT16 i_wID, tBOOL i_bEnable) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Enable - get enable flag
|
||||
virtual tBOOL Get_Enable(tUINT16 i_wID) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Min - get min value
|
||||
virtual tDOUBLE Get_Min(tUINT16 i_wID) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Max - get max value
|
||||
virtual tDOUBLE Get_Max(tUINT16 i_wID) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Name - get name
|
||||
virtual const tXCHAR *Get_Name(tUINT16 i_wID) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Count - get amount of counters
|
||||
virtual tUINT16 Get_Count() = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Share - function to share current P7.Telemetry object in address space of
|
||||
// the current process, to get shared instance use function
|
||||
// P7_Get_Shared_Telemetry(tXCHAR *i_pName)
|
||||
// See documentation for details.
|
||||
virtual tBOOL Share(const tXCHAR *i_pName) = 0;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Create_Telemetry - function creates new instance of IP7_Telemetry object
|
||||
// See documentation for details.
|
||||
extern "C" P7_EXPORT IP7_Telemetry* __cdecl P7_Create_Telemetry(IP7_Client *i_pClient,
|
||||
const tXCHAR *i_pName,
|
||||
const stTelemetry_Conf *i_pConf = NULL
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//This functions allows you to get P7 telemetry instance if it was created by
|
||||
//someone else inside current process. If no instance was registered inside
|
||||
//current process - function will return NULL. Do not forget to call Release on
|
||||
//interface when you finish your work
|
||||
//See documentation for details.
|
||||
extern "C" P7_EXPORT IP7_Telemetry* __cdecl P7_Get_Shared_Telemetry(const tXCHAR *i_pName);
|
||||
|
||||
|
||||
#endif //P7_TELEMETRY_H
|
||||
281
p7lib/Headers/P7_Trace.h
Normal file
281
p7lib/Headers/P7_Trace.h
Normal file
@ -0,0 +1,281 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// P7.Tace //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Documentation is located in <P7>/Documentation/P7.pdf //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef P7_TRACE_H
|
||||
#define P7_TRACE_H
|
||||
|
||||
#include "P7_Client.h"
|
||||
#include "P7_Cproxy.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#define TRACE_DEFAULT_SHARED_NAME TM("P7.Trace")
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7.Trace uses optimization to read variable arguments directly from the stack/
|
||||
//but some systems optimizes storing of var.args and uses processor resistors/
|
||||
//stack re-ordering, extra-padding and other techniques, so if you detect than /
|
||||
//library print wrong values - please activate this macro manually for your /
|
||||
//platform/project /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//#define P7TRACE_NO_VA_ARG_OPTIMIZATION
|
||||
|
||||
//disable va_arg optimization for Linux, too many ways how GCC + Linux uses
|
||||
//stack and registers to store va_arg
|
||||
#if defined(__linux__)
|
||||
#define P7TRACE_NO_VA_ARG_OPTIMIZATION
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//in some platforms access to 64 not aligned variable is illegal, if it the/
|
||||
//case please active the macro /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//#define P7TRACE_64BITS_ALIGNED_ACCESS
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
enum eP7Trace_Level
|
||||
{
|
||||
EP7TRACE_LEVEL_TRACE = 0,
|
||||
EP7TRACE_LEVEL_DEBUG ,
|
||||
EP7TRACE_LEVEL_INFO ,
|
||||
EP7TRACE_LEVEL_WARNING ,
|
||||
EP7TRACE_LEVEL_ERROR ,
|
||||
EP7TRACE_LEVEL_CRITICAL ,
|
||||
|
||||
EP7TRACE_LEVEL_COUNT
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define P7_DELIVER(i_wID, i_eLevel, i_hModule, ...) Trace(i_wID,\
|
||||
i_eLevel,\
|
||||
i_hModule,\
|
||||
(tUINT16)__LINE__,\
|
||||
__FILE__,\
|
||||
__FUNCTION__,\
|
||||
__VA_ARGS__)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define P7_QTRACE(i_wID, i_hModule, ...) P7_DELIVER(i_wID,\
|
||||
EP7TRACE_LEVEL_TRACE,\
|
||||
i_hModule,\
|
||||
__VA_ARGS__)
|
||||
|
||||
#define P7_TRACE(i_hModule, ...) P7_QTRACE(0,\
|
||||
i_hModule,\
|
||||
__VA_ARGS__)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define P7_QDEBUG(i_wID, i_hModule, ...) P7_DELIVER(i_wID,\
|
||||
EP7TRACE_LEVEL_DEBUG,\
|
||||
i_hModule,\
|
||||
__VA_ARGS__)
|
||||
|
||||
#define P7_DEBUG(i_hModule, ...) P7_QDEBUG(0,\
|
||||
i_hModule,\
|
||||
__VA_ARGS__)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define P7_QINFO(i_wID, i_hModule, ...) P7_DELIVER(i_wID,\
|
||||
EP7TRACE_LEVEL_INFO,\
|
||||
i_hModule,\
|
||||
__VA_ARGS__)
|
||||
|
||||
#define P7_INFO(i_hModule, ...) P7_QINFO(0,\
|
||||
i_hModule,\
|
||||
__VA_ARGS__)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define P7_QWARNING(i_wID, i_hModule, ...) P7_DELIVER(i_wID,\
|
||||
EP7TRACE_LEVEL_WARNING,\
|
||||
i_hModule,\
|
||||
__VA_ARGS__)
|
||||
|
||||
#define P7_WARNING(i_hModule, ...) P7_QWARNING(0,\
|
||||
i_hModule,\
|
||||
__VA_ARGS__)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define P7_QERROR(i_wID, i_hModule, ...) P7_DELIVER(i_wID,\
|
||||
EP7TRACE_LEVEL_ERROR,\
|
||||
i_hModule,\
|
||||
__VA_ARGS__)
|
||||
|
||||
#define P7_ERROR(i_hModule, ...) P7_QERROR(0,\
|
||||
i_hModule,\
|
||||
__VA_ARGS__)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define P7_QCRITICAL(i_wID, i_hModule, ...) P7_DELIVER(i_wID,\
|
||||
EP7TRACE_LEVEL_CRITICAL,\
|
||||
i_hModule,\
|
||||
__VA_ARGS__)
|
||||
|
||||
#define P7_CRITICAL(i_hModule, ...) P7_QCRITICAL(0,\
|
||||
i_hModule,\
|
||||
__VA_ARGS__)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define LOG(logger, level, format, ...) logger->P7_DELIVER(0, EP7TRACE_LEVEL_##level, NULL, TM(format), __VA_ARGS__)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////IP7_Trace//////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class IP7_Trace
|
||||
: public IP7C_Channel
|
||||
{
|
||||
public:
|
||||
typedef void* hModule;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Set_Verbosity - function to set trace verbosity, traces with less priority
|
||||
// will be rejected. You may set verbosity online from Baical
|
||||
// server. See documentation for details.
|
||||
virtual void Set_Verbosity(IP7_Trace::hModule i_hModule,
|
||||
eP7Trace_Level i_eVerbosity
|
||||
) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Verbosity - function to get trace verbosity.
|
||||
// See documentation for details.
|
||||
virtual eP7Trace_Level Get_Verbosity(IP7_Trace::hModule i_hModule) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Register_Thread - function used to specify name for current thread. Allows
|
||||
// you to have nice trace message formatting on Baical side
|
||||
// and in addition to ThreadId get Thread Name.
|
||||
// Call the function from the newly created thread & call
|
||||
// Unregister_Thread() right before exiting from thread
|
||||
// body function.
|
||||
//N.B.: If internally your application creates & destroys thousands of
|
||||
// threads - usage of this functions is not good choice due to server
|
||||
// overhead to store & manage this information - all threads info will
|
||||
// be stored in RAM and may consume CPU to organize them in RB tree.
|
||||
virtual tBOOL Register_Thread(const tXCHAR *i_pName,
|
||||
tUINT32 i_dwThreadId
|
||||
) = 0;
|
||||
virtual tBOOL Unregister_Thread(tUINT32 i_dwThreadId) = 0;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Register_Module - function is used register application module for using
|
||||
// it by trace messages, if module with such name is
|
||||
// already registered - existing handle will be returned
|
||||
virtual tBOOL Register_Module(const tXCHAR *i_pName,
|
||||
IP7_Trace::hModule *o_hModule
|
||||
) = 0;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Share - function to share current P7.Trace object in address space of the
|
||||
// current process, to get shared instance use function
|
||||
// P7_Get_Shared_Trace(tXCHAR *i_pName).
|
||||
// See documentation for details.
|
||||
virtual tBOOL Share(const tXCHAR *i_pName) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Trace - send trace message to Baical server. See documentation for details
|
||||
//N.B.: USE THIS FUNCTION ONLY FROM C/C++ LANGUAGES ! if you want to use
|
||||
// trace functionality from other languages please call Trace_Managed()
|
||||
virtual tBOOL Trace(tUINT16 i_wTrace_ID,
|
||||
eP7Trace_Level i_eLevel,
|
||||
IP7_Trace::hModule i_hModule,
|
||||
tUINT16 i_wLine,
|
||||
const char *i_pFile,
|
||||
const char *i_pFunction,
|
||||
const tXCHAR *i_pFormat,
|
||||
...
|
||||
) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//N.B: FUNCTION IS OBSOLETE, //
|
||||
// Please use instead function Trace_Embedded(..., va_list*) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Trace_Embedded - send trace message
|
||||
//this function is a copy of Trace function, but it is dedicated to embedded
|
||||
//usage (you already have function with variable arguments, but body of your
|
||||
//function may be replaced by Trace_Embedded).
|
||||
//See documentation for details.
|
||||
virtual tBOOL Trace_Embedded(tUINT16 i_wTrace_ID,
|
||||
eP7Trace_Level i_eLevel,
|
||||
IP7_Trace::hModule i_hModule,
|
||||
tUINT16 i_wLine,
|
||||
const char *i_pFile,
|
||||
const char *i_pFunction,
|
||||
const tXCHAR **i_ppFormat
|
||||
) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Trace_Embedded - send trace message
|
||||
//this function is a copy of Trace function, but it is dedicated to embedded
|
||||
//usage (you already have function with variable arguments, but body of your
|
||||
//function may be replaced by Trace_Embedded).
|
||||
//See documentation for details.
|
||||
virtual tBOOL Trace_Embedded(tUINT16 i_wTrace_ID,
|
||||
eP7Trace_Level i_eLevel,
|
||||
IP7_Trace::hModule i_hModule,
|
||||
tUINT16 i_wLine,
|
||||
const char *i_pFile,
|
||||
const char *i_pFunction,
|
||||
const tXCHAR **i_ppFormat,
|
||||
va_list *i_pVa_List
|
||||
) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Trace_Managed - send trace message
|
||||
//this function is intended for use by MANAGED languages like C#,python, etc
|
||||
//See documentation for details.
|
||||
virtual tBOOL Trace_Managed(tUINT16 i_wTrace_ID,
|
||||
eP7Trace_Level i_eLevel,
|
||||
IP7_Trace::hModule i_hModule,
|
||||
tUINT16 i_wLine,
|
||||
const tXCHAR *i_pFile,
|
||||
const tXCHAR *i_pFunction,
|
||||
const tXCHAR *i_pMessage
|
||||
) = 0;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//P7_Create_Trace - function create new instance of IP7_Trace object
|
||||
//See documentation for details.
|
||||
extern "C" P7_EXPORT IP7_Trace * __cdecl P7_Create_Trace(IP7_Client *i_pClient,
|
||||
const tXCHAR *i_pName,
|
||||
const stTrace_Conf *i_pConf = 0
|
||||
);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//This functions allow you to get P7 trace instance if it was created by
|
||||
//someone other inside current process. If no instance was registered inside
|
||||
//current process - function will return NULL. Do not forget to call Release
|
||||
//on interface when you finish your work.
|
||||
//See documentation for details.
|
||||
extern "C" P7_EXPORT IP7_Trace * __cdecl P7_Get_Shared_Trace(const tXCHAR *i_pName);
|
||||
|
||||
#endif //P7_TRACE_H
|
||||
26
p7lib/Headers/P7_Version.h
Normal file
26
p7lib/Headers/P7_Version.h
Normal file
@ -0,0 +1,26 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef P7_VERSION_H
|
||||
#define P7_VERSION_H
|
||||
//-----------------------------------------
|
||||
#define P7_VERSION 00050006
|
||||
#define P7_VERSION_MAJOR 5
|
||||
#define P7_VERSION_MINOR 6
|
||||
//-----------------------------------------
|
||||
#endif //P7_VERSION_H
|
||||
57
p7lib/License.txt
Normal file
57
p7lib/License.txt
Normal file
@ -0,0 +1,57 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below.
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, “this License” refers to version 3 of the GNU Lesser General Public License, and the “GNU GPL” refers to version 3 of the GNU General Public License.
|
||||
|
||||
“The Library” refers to a covered work governed by this License, other than an Application or a Combined Work as defined below.
|
||||
|
||||
An “Application” is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library.
|
||||
|
||||
A “Combined Work” is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the “Linked Version”.
|
||||
|
||||
The “Minimal Corresponding Source” for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version.
|
||||
|
||||
The “Corresponding Application Code” for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work.
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL.
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version:
|
||||
a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or
|
||||
b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy.
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following:
|
||||
a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License.
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license document.
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following:
|
||||
a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License.
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license document.
|
||||
c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document.
|
||||
d) Do one of the following:
|
||||
0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.
|
||||
1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version.
|
||||
e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.)
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following:
|
||||
a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License.
|
||||
b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.
|
||||
826
p7lib/Shared/AList.h
Normal file
826
p7lib/Shared/AList.h
Normal file
@ -0,0 +1,826 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//******************************************************************************
|
||||
// This header file contains simple template lists *
|
||||
// 1. List with customizable memory manager (CListBase) *
|
||||
// 2. List with pooling of internal elements (CListPool) *
|
||||
//******************************************************************************
|
||||
#ifndef ALIST_H
|
||||
#define ALIST_H
|
||||
|
||||
typedef void *pAList_Cell;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase
|
||||
template <typename tData_Type>
|
||||
class CListBase
|
||||
{
|
||||
protected:
|
||||
struct tCell
|
||||
{
|
||||
tData_Type m_pData;
|
||||
tCell *m_pNext;
|
||||
tCell *m_pPrev;
|
||||
};
|
||||
|
||||
typedef tCell* pIndex_Cell;
|
||||
|
||||
tCell *m_pFirst;
|
||||
tCell *m_pLast;
|
||||
|
||||
tUINT32 m_dwCount;
|
||||
//HANDLE m_hLock_Mutex;
|
||||
|
||||
pIndex_Cell *m_pIndex;
|
||||
tBOOL m_bBrokenIndex;
|
||||
tUINT32 m_dwIndexCount;
|
||||
|
||||
tBOOL m_bInitialized;
|
||||
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::CListBase
|
||||
CListBase()
|
||||
{
|
||||
m_bInitialized = TRUE;
|
||||
m_pFirst = NULL;
|
||||
m_pLast = NULL;
|
||||
m_dwCount = 0;
|
||||
m_pIndex = NULL;
|
||||
m_bBrokenIndex = TRUE;
|
||||
m_dwIndexCount = 0;
|
||||
//m_hLock_Mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
|
||||
//if (NULL == m_hLock_Mutex)
|
||||
//{
|
||||
// m_bInitialized = FALSE;
|
||||
//}
|
||||
}//CListBase::AList
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::~CListBase
|
||||
virtual ~CListBase()
|
||||
{
|
||||
Index_Release();
|
||||
|
||||
//if (m_hLock_Mutex)
|
||||
//{
|
||||
// CloseHandle(m_hLock_Mutex);
|
||||
// m_hLock_Mutex = NULL;
|
||||
//}
|
||||
|
||||
if (m_dwCount)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
OutputDebugStringW(L"Warning: List is not empty\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}//CListBase::~CListBase
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Get_Initialized
|
||||
inline tBOOL Get_Initialized()
|
||||
{
|
||||
return m_bInitialized;
|
||||
}//CListBase::Get_Initialized
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Del
|
||||
inline tBOOL Del(pAList_Cell i_pCell, tBOOL i_bFree_Data)
|
||||
{
|
||||
tCell *l_pCell = static_cast<tCell*>(i_pCell);
|
||||
tBOOL l_bResult = TRUE;
|
||||
|
||||
if (l_pCell)
|
||||
{
|
||||
l_bResult = Cell_Release(l_pCell, TRUE, i_bFree_Data);
|
||||
}
|
||||
|
||||
return l_bResult;
|
||||
}//CListBase::Del
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Extract
|
||||
inline tBOOL Extract(pAList_Cell i_pCell)
|
||||
{
|
||||
tCell *l_pCell = static_cast<tCell*>(i_pCell);
|
||||
tBOOL l_bResult = TRUE;
|
||||
|
||||
if (l_pCell)
|
||||
{
|
||||
l_bResult = Cell_Release(l_pCell, FALSE, FALSE);
|
||||
l_pCell->m_pNext = NULL;
|
||||
l_pCell->m_pPrev = NULL;
|
||||
}
|
||||
|
||||
return l_bResult;
|
||||
}//CListBase::Extract
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Pull_First
|
||||
inline tData_Type Pull_First()
|
||||
{
|
||||
tData_Type l_pReturn = m_pFirst->m_pData;
|
||||
Cell_Release(m_pFirst, TRUE, FALSE);
|
||||
return l_pReturn;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Pull_Last
|
||||
inline tData_Type Pull_Last()
|
||||
{
|
||||
tData_Type l_pReturn = m_pLast->m_pData;
|
||||
Cell_Release(m_pLast, TRUE, FALSE);
|
||||
return l_pReturn;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Push_First
|
||||
inline pAList_Cell Push_First(tData_Type i_pData)
|
||||
{
|
||||
return Add_After(NULL, i_pData);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Push_Last
|
||||
inline pAList_Cell Push_Last(tData_Type i_pData)
|
||||
{
|
||||
return Add_After(m_pLast, i_pData);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Add_After
|
||||
inline pAList_Cell Add_After(pAList_Cell i_pCell, tData_Type i_pData)
|
||||
{
|
||||
tCell *l_pNew_Cell = NULL;
|
||||
tCell *l_pList_Cell = static_cast<tCell *>(i_pCell);
|
||||
|
||||
l_pNew_Cell = Cell_Allocate();
|
||||
|
||||
if (l_pNew_Cell)
|
||||
{
|
||||
memset(l_pNew_Cell, 0, sizeof(tCell));
|
||||
l_pNew_Cell->m_pData = i_pData;
|
||||
l_pNew_Cell->m_pNext = NULL;
|
||||
l_pNew_Cell->m_pPrev = NULL;
|
||||
|
||||
Put_After(l_pList_Cell, l_pNew_Cell);
|
||||
}
|
||||
|
||||
return static_cast<pAList_Cell>(l_pNew_Cell);
|
||||
}//CListBase::Add_After
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Put_After
|
||||
inline tBOOL Put_After(pAList_Cell i_pList_Cell, pAList_Cell i_pExt_Cell)
|
||||
{
|
||||
tCell *l_pList_Cell = static_cast<tCell*>(i_pList_Cell);
|
||||
tCell *l_pExt_Cell = static_cast<tCell*>(i_pExt_Cell);
|
||||
tBOOL l_bResult = TRUE;
|
||||
|
||||
if (NULL == l_pExt_Cell)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_dwCount++;
|
||||
|
||||
if (l_pList_Cell)
|
||||
{
|
||||
l_pExt_Cell->m_pNext = l_pList_Cell->m_pNext;
|
||||
l_pExt_Cell->m_pPrev = l_pList_Cell;
|
||||
if (l_pList_Cell->m_pNext)
|
||||
{
|
||||
l_pList_Cell->m_pNext->m_pPrev = l_pExt_Cell;
|
||||
}
|
||||
l_pList_Cell->m_pNext = l_pExt_Cell;
|
||||
}
|
||||
|
||||
|
||||
if ((NULL == l_pList_Cell) && (m_pFirst))
|
||||
{
|
||||
m_pFirst->m_pPrev = l_pExt_Cell;
|
||||
l_pExt_Cell->m_pNext = m_pFirst;
|
||||
m_pFirst = l_pExt_Cell;
|
||||
}
|
||||
|
||||
if ((m_pLast) && (m_pLast == l_pList_Cell))
|
||||
{
|
||||
m_pLast = l_pExt_Cell;
|
||||
}
|
||||
|
||||
if (!m_pFirst)
|
||||
{
|
||||
m_pFirst = l_pExt_Cell;
|
||||
m_pLast = l_pExt_Cell;
|
||||
}
|
||||
|
||||
m_bBrokenIndex = TRUE;
|
||||
|
||||
return l_bResult;
|
||||
}//CListBase::Put_After
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Get_Prev
|
||||
inline pAList_Cell Get_Prev(pAList_Cell i_pCell)
|
||||
{
|
||||
tCell *l_pCell = static_cast<tCell*>(i_pCell);
|
||||
pAList_Cell l_pResult = NULL;
|
||||
|
||||
if (l_pCell)
|
||||
{
|
||||
l_pResult = static_cast<pAList_Cell>(l_pCell->m_pPrev);
|
||||
}
|
||||
else
|
||||
{
|
||||
l_pResult = static_cast<pAList_Cell>(m_pLast);
|
||||
}
|
||||
|
||||
return l_pResult;
|
||||
}//CListBase::Get_Prev
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Get_Next
|
||||
inline pAList_Cell Get_Next(pAList_Cell i_pCell)
|
||||
{
|
||||
tCell *l_pCell = static_cast<tCell *>(i_pCell);
|
||||
pAList_Cell l_pResult = NULL;
|
||||
|
||||
if (l_pCell)
|
||||
{
|
||||
l_pResult = static_cast<pAList_Cell>(l_pCell->m_pNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
l_pResult = static_cast<pAList_Cell>(m_pFirst);
|
||||
}
|
||||
|
||||
return l_pResult;
|
||||
}//CListBase::Get_Next
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Get_Data
|
||||
inline tData_Type Get_Data(pAList_Cell i_pCell)
|
||||
{
|
||||
tCell *l_pCell = static_cast<tCell*>(i_pCell);
|
||||
tData_Type l_pResult = 0;
|
||||
if (l_pCell)
|
||||
{
|
||||
l_pResult = l_pCell->m_pData;
|
||||
}
|
||||
|
||||
return l_pResult;
|
||||
}//CListBase::Get_Data
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Set_Data
|
||||
inline tBOOL Set_Data(pAList_Cell i_pCell, tBOOL i_bFree_Old_Data, tData_Type i_pData)
|
||||
{
|
||||
tCell *l_pCell = static_cast<tCell*>(i_pCell);
|
||||
tData_Type l_pResult = NULL;
|
||||
if (l_pCell)
|
||||
{
|
||||
if (i_bFree_Old_Data)
|
||||
{
|
||||
Data_Release(l_pCell->m_pData);
|
||||
}
|
||||
|
||||
l_pCell->m_pData = i_pData;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}//CListBase::Set_Data
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Get_ByIndex
|
||||
inline pAList_Cell Get_ByIndex(tUINT32 i_dwIDX)
|
||||
{
|
||||
tCell *l_pReturn = NULL;
|
||||
tUINT32 l_dwI;
|
||||
|
||||
if (m_bBrokenIndex)
|
||||
{
|
||||
Index_Build();
|
||||
}
|
||||
|
||||
if (i_dwIDX < m_dwCount)
|
||||
{
|
||||
if ( (FALSE == m_bBrokenIndex)
|
||||
&& (m_pIndex)
|
||||
)
|
||||
{
|
||||
l_pReturn = m_pIndex[i_dwIDX];
|
||||
}
|
||||
else
|
||||
{
|
||||
l_pReturn = m_pFirst;
|
||||
for (l_dwI = 0; l_dwI < i_dwIDX; l_dwI++)
|
||||
{
|
||||
if (l_pReturn)
|
||||
{
|
||||
l_pReturn = l_pReturn->m_pNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return l_pReturn;
|
||||
}//CListBase::Get_ByIndex
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::operator[]
|
||||
inline tData_Type operator[](tUINT32 i_dwIDX)
|
||||
{
|
||||
tCell *l_pReturn = static_cast<tCell*>(Get_ByIndex(i_dwIDX));
|
||||
|
||||
return (l_pReturn) ? l_pReturn->m_pData : NULL;
|
||||
}//CListBase::operator[]
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Put_Data
|
||||
inline tBOOL Put_Data(pAList_Cell i_pCell, tData_Type i_pData, tBOOL i_bFree_Old_Data)
|
||||
{
|
||||
tBOOL l_bResult = TRUE;
|
||||
tCell *l_pCell = static_cast<tCell*>(i_pCell);
|
||||
if (l_pCell)
|
||||
{
|
||||
if ( i_bFree_Old_Data )
|
||||
{
|
||||
Data_Release(l_pCell->m_pData);
|
||||
l_pCell->m_pData = NULL;
|
||||
}
|
||||
|
||||
l_pCell->m_pData = i_pData;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
}
|
||||
|
||||
|
||||
return l_bResult;
|
||||
}//CListBase::Put_Data
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Lock
|
||||
//void Lock()
|
||||
//{
|
||||
// WaitForSingleObject(m_hLock_Mutex, INFINITE);
|
||||
//}//CListBase::Lock
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::UnLock
|
||||
//void UnLock()
|
||||
//{
|
||||
// ReleaseMutex(m_hLock_Mutex);
|
||||
//}//CListBase::UnLock
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Clear
|
||||
inline void Clear(tBOOL i_bClearData)
|
||||
{
|
||||
while (NULL != m_pFirst)
|
||||
{
|
||||
if (TRUE != Cell_Release(m_pFirst, TRUE, i_bClearData))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}//CListBase::Clear
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Get_First
|
||||
inline pAList_Cell Get_First()
|
||||
{
|
||||
return static_cast<pAList_Cell>(m_pFirst);
|
||||
}//CListBase::Get_First
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Get_Last
|
||||
inline pAList_Cell Get_Last()
|
||||
{
|
||||
return static_cast<pAList_Cell>(m_pLast);
|
||||
}//CListBase::Get_Last
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Count
|
||||
inline tUINT32 Count()
|
||||
{
|
||||
return m_dwCount;
|
||||
}//CListBase::Count
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Cell_Release
|
||||
inline tBOOL Cell_Release(tCell *i_pCell, tBOOL i_bFree_Cell, tBOOL i_bFree_Data)
|
||||
{
|
||||
tBOOL l_bResult = TRUE;
|
||||
|
||||
if (NULL == i_pCell)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((NULL != i_pCell->m_pPrev) && (NULL != i_pCell->m_pNext))
|
||||
{
|
||||
i_pCell->m_pPrev->m_pNext = i_pCell->m_pNext;
|
||||
i_pCell->m_pNext->m_pPrev = i_pCell->m_pPrev;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
|
||||
if (i_pCell == m_pFirst)
|
||||
{
|
||||
m_pFirst = i_pCell->m_pNext;
|
||||
|
||||
if (m_pFirst != 0)
|
||||
{
|
||||
m_pFirst->m_pPrev = 0;
|
||||
}
|
||||
|
||||
l_bResult = TRUE;
|
||||
}
|
||||
|
||||
if (i_pCell == m_pLast)
|
||||
{
|
||||
m_pLast = i_pCell->m_pPrev;
|
||||
if (m_pLast != 0)
|
||||
{
|
||||
m_pLast->m_pNext = 0;
|
||||
}
|
||||
|
||||
l_bResult = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (TRUE == l_bResult)
|
||||
{
|
||||
if (i_bFree_Data)
|
||||
{
|
||||
Data_Release(i_pCell->m_pData);
|
||||
i_pCell->m_pData = 0;
|
||||
}
|
||||
|
||||
if (i_bFree_Cell)
|
||||
{
|
||||
Cell_Free(i_pCell);
|
||||
}
|
||||
}
|
||||
|
||||
m_bBrokenIndex = TRUE;
|
||||
|
||||
m_dwCount--;
|
||||
|
||||
return l_bResult;
|
||||
}//CListBase::Cell_Release
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Index_Build
|
||||
inline tBOOL Index_Build()
|
||||
{
|
||||
tBOOL l_bResult = TRUE;
|
||||
|
||||
if ( (m_pIndex) && (m_dwCount > m_dwIndexCount) )
|
||||
{
|
||||
Index_Release();
|
||||
}
|
||||
|
||||
if (NULL == m_pIndex)
|
||||
{
|
||||
m_dwIndexCount = m_dwCount + 128;
|
||||
m_pIndex = (pIndex_Cell*)this->MemAlloc(sizeof(pIndex_Cell) * m_dwIndexCount);
|
||||
}
|
||||
|
||||
if (NULL == m_pIndex)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
m_dwIndexCount = 0;
|
||||
}
|
||||
|
||||
if (TRUE == l_bResult)
|
||||
{
|
||||
pAList_Cell l_pEl = NULL;
|
||||
|
||||
memset(m_pIndex, 0, m_dwIndexCount * sizeof(pIndex_Cell));
|
||||
|
||||
pIndex_Cell *l_pIndexLocal = m_pIndex;
|
||||
|
||||
while ((l_pEl = Get_Next(l_pEl)) != NULL)
|
||||
{
|
||||
*l_pIndexLocal = static_cast<tCell*>(l_pEl);
|
||||
l_pIndexLocal ++;
|
||||
}
|
||||
|
||||
m_bBrokenIndex = FALSE;
|
||||
}
|
||||
|
||||
return l_bResult;
|
||||
}//CListBase::Index_Build
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Index_Release
|
||||
inline tBOOL Index_Release()
|
||||
{
|
||||
if (m_pIndex)
|
||||
{
|
||||
this->MemFree(m_pIndex);
|
||||
m_pIndex = NULL;
|
||||
}
|
||||
|
||||
m_dwIndexCount = 0;
|
||||
m_bBrokenIndex = TRUE;
|
||||
return TRUE;
|
||||
}//CListBase::Index_Release
|
||||
|
||||
protected:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Data_Release
|
||||
// override this function in derived class to implement specific data
|
||||
// destructor(structures as example)
|
||||
virtual tBOOL Data_Release(tData_Type i_pData) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::MemAlloc
|
||||
//override this function in derived class to implement own memory allocation
|
||||
//mechanism, it will be used everywhere in this class
|
||||
virtual void *MemAlloc(size_t i_szSize)
|
||||
{
|
||||
return new tUINT8[i_szSize];
|
||||
}//CListBase::MemAlloc
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::MemFree
|
||||
//override this function in derived class to implement own memory deallocation
|
||||
//mechanism, it will be used everywhere in this class
|
||||
virtual void MemFree(void * i_pMemory)
|
||||
{
|
||||
delete [] ((tUINT8*)i_pMemory);
|
||||
}//CListBase::MemFree
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Cell_Allocate
|
||||
virtual tCell *Cell_Allocate()
|
||||
{
|
||||
return (tCell*)this->MemAlloc(sizeof(tCell));
|
||||
}//Cell_Allocate
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Cell_Free
|
||||
virtual void Cell_Free(tCell *i_pCell)
|
||||
{
|
||||
this->MemFree(i_pCell);
|
||||
}//Cell_Free
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CAList
|
||||
template <typename tData_Type>
|
||||
class CAList
|
||||
: public CListBase<tData_Type>
|
||||
{
|
||||
protected:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Data_Release
|
||||
// override this function in derived class to implement specific data
|
||||
// destructor(structures as example)
|
||||
virtual tBOOL Data_Release(tData_Type i_pData)
|
||||
{
|
||||
if (NULL == i_pData)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
delete i_pData;
|
||||
return TRUE;
|
||||
}//CListBase::Data_Release
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//This list has pool for list's cells, this technology speedup allocation and
|
||||
//deallocation of new list's elements (6-10 times).
|
||||
//List intended for situation when you has very intensive adding & deleting
|
||||
//process, but it will use a lot of memory if you will add 1 million items and
|
||||
//then delete 999 thousands, after that all 999 thousands internal list cells
|
||||
//will be stored in internal pool, for the time being mechanism of pool packing
|
||||
//is not developed.
|
||||
//N.B.: be careful with list, use it only when you absolutely sure in what are
|
||||
// you doing.
|
||||
template <typename tData_Type>
|
||||
class CListPool:
|
||||
public CListBase<tData_Type>
|
||||
{
|
||||
private:
|
||||
#define TCELL typename CListBase<tData_Type>::tCell
|
||||
|
||||
struct tPool_Segment
|
||||
{
|
||||
TCELL *m_pCells;
|
||||
tUINT32 m_dwCount;
|
||||
tPool_Segment *m_pNext;
|
||||
};
|
||||
|
||||
tPool_Segment *m_pPool_First;
|
||||
TCELL *m_pPool_Cell_First;
|
||||
|
||||
//count of cell allocated for every pool segment
|
||||
tUINT32 m_dwPool_Size;
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListPool::CListPool
|
||||
CListPool(tUINT32 i_dwPool_Size = 128)
|
||||
: CListBase<tData_Type>()
|
||||
, m_dwPool_Size(i_dwPool_Size)
|
||||
{
|
||||
m_pPool_First = NULL;
|
||||
m_pPool_Cell_First = NULL;
|
||||
}//CListPool::CListPool
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListPool::~CListPool
|
||||
virtual ~CListPool()
|
||||
{
|
||||
tPool_Segment *l_pPool_Tmp = NULL;
|
||||
while (m_pPool_First)
|
||||
{
|
||||
l_pPool_Tmp = m_pPool_First;
|
||||
m_pPool_First = m_pPool_First->m_pNext;
|
||||
|
||||
Free_Pool_Segment(l_pPool_Tmp);
|
||||
}
|
||||
}//CListPool::~CListPool
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListPool::Create_Pool_Segment
|
||||
inline tBOOL Create_Pool_Segment()
|
||||
{
|
||||
tBOOL l_bReturn = FALSE;
|
||||
|
||||
tPool_Segment *l_pPool = (tPool_Segment*)CListBase<tData_Type>::MemAlloc(sizeof(tPool_Segment));
|
||||
|
||||
if (l_pPool)
|
||||
{
|
||||
memset(l_pPool, 0, sizeof(tPool_Segment));
|
||||
l_pPool->m_dwCount = m_dwPool_Size;
|
||||
l_pPool->m_pCells = (TCELL*)this->MemAlloc(sizeof(TCELL) * l_pPool->m_dwCount);
|
||||
|
||||
if (l_pPool->m_pCells)
|
||||
{
|
||||
TCELL *l_pCell = NULL;
|
||||
|
||||
memset(l_pPool->m_pCells,
|
||||
0,
|
||||
sizeof(tPool_Segment) * l_pPool->m_dwCount
|
||||
);
|
||||
|
||||
l_pCell = l_pPool->m_pCells;
|
||||
|
||||
for (tUINT32 l_dwIDX = 1; l_dwIDX < l_pPool->m_dwCount; l_dwIDX++)
|
||||
{
|
||||
l_pCell->m_pNext = (l_pCell + 1);
|
||||
l_pCell ++;
|
||||
}
|
||||
|
||||
l_bReturn = TRUE;
|
||||
l_pPool->m_pNext = m_pPool_First;
|
||||
m_pPool_First = l_pPool;
|
||||
l_pCell->m_pNext = m_pPool_Cell_First;
|
||||
m_pPool_Cell_First = l_pPool->m_pCells;
|
||||
}
|
||||
}
|
||||
|
||||
if (FALSE == l_bReturn)
|
||||
{
|
||||
Free_Pool_Segment(l_pPool);
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}//CListPool::Create_Pool_Segment
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListPool::Free_Pool_Segment
|
||||
inline void Free_Pool_Segment(tPool_Segment *io_pPool)
|
||||
{
|
||||
if (io_pPool)
|
||||
{
|
||||
if (io_pPool->m_pCells)
|
||||
{
|
||||
this->MemFree(io_pPool->m_pCells);
|
||||
io_pPool->m_pCells = NULL;
|
||||
}
|
||||
this->MemFree(io_pPool);
|
||||
}
|
||||
}//CListPool::Free_Pool_Segment
|
||||
|
||||
protected:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListPool::Cell_Allocate
|
||||
virtual TCELL *Cell_Allocate()
|
||||
{
|
||||
TCELL *l_pReturn = NULL;
|
||||
if (NULL == m_pPool_Cell_First)
|
||||
{
|
||||
Create_Pool_Segment();
|
||||
}
|
||||
|
||||
l_pReturn = m_pPool_Cell_First;
|
||||
|
||||
if (m_pPool_Cell_First)
|
||||
{
|
||||
m_pPool_Cell_First = m_pPool_Cell_First->m_pNext;
|
||||
}
|
||||
|
||||
return l_pReturn;
|
||||
}//CListPool::Cell_Allocate
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListPool::Cell_Free
|
||||
virtual void Cell_Free(TCELL *i_pCell)
|
||||
{
|
||||
memset(i_pCell, 0, sizeof(TCELL));
|
||||
i_pCell->m_pNext = m_pPool_Cell_First;
|
||||
m_pPool_Cell_First = i_pCell;
|
||||
}//CListPool::Cell_Free
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CBList
|
||||
template <typename tData_Type>
|
||||
class CBList
|
||||
: public CListPool<tData_Type>
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListPool::CListPool
|
||||
CBList(tUINT32 i_dwPool_Size = 128)
|
||||
: CListPool<tData_Type>(i_dwPool_Size)
|
||||
{
|
||||
}//CBList::CBList
|
||||
|
||||
protected:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CListBase::Data_Release
|
||||
// override this function in derived class to implement specific data
|
||||
// destructor(structures as example)
|
||||
virtual tBOOL Data_Release(tData_Type i_pData)
|
||||
{
|
||||
if (NULL == i_pData)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
delete i_pData;
|
||||
return TRUE;
|
||||
}//CListBase::Data_Release
|
||||
};
|
||||
|
||||
#endif //ALIST_H
|
||||
11
p7lib/Shared/CMakeLists.txt
Normal file
11
p7lib/Shared/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
|
||||
|
||||
set(PATH_SHARED ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "")
|
||||
set(PATH_SHARED_CRYPTO ${CMAKE_CURRENT_SOURCE_DIR}/Crypto CACHE INTERNAL "")
|
||||
set(PATH_SHARED_XML ${CMAKE_CURRENT_SOURCE_DIR}/XML CACHE INTERNAL "")
|
||||
|
||||
if(WIN32)
|
||||
set(PATH_SHARED_PLATFORM ${CMAKE_CURRENT_SOURCE_DIR}/Platforms/Windows_x86 CACHE INTERNAL "")
|
||||
else()
|
||||
set(PATH_SHARED_PLATFORM ${CMAKE_CURRENT_SOURCE_DIR}/Platforms/Linux_x86 CACHE INTERNAL "")
|
||||
endif()
|
||||
122
p7lib/Shared/CRC32.h
Normal file
122
p7lib/Shared/CRC32.h
Normal file
@ -0,0 +1,122 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//******************************************************************************
|
||||
// This header file provide CRC32 functions *
|
||||
//******************************************************************************
|
||||
#ifndef CRC32_H
|
||||
#define CRC32_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "GTypes.h"
|
||||
|
||||
static tUINT32 g_pCRC32_Table[] =
|
||||
{
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL,
|
||||
0x990951baL, 0x076dc419L, 0x706af48fL,
|
||||
0xe963a535L, 0x9e6495a3L, 0x0edb8832L,
|
||||
0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
|
||||
0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L,
|
||||
0xf3b97148L, 0x84be41deL, 0x1adad47dL,
|
||||
0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
|
||||
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL,
|
||||
0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||||
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L,
|
||||
0x4c69105eL, 0xd56041e4L, 0xa2677172L,
|
||||
0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL,
|
||||
0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL,
|
||||
0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||||
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
|
||||
0x26d930acL, 0x51de003aL, 0xc8d75180L,
|
||||
0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L,
|
||||
0xcfba9599L, 0xb8bda50fL, 0x2802b89eL,
|
||||
0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL,
|
||||
0xb6662d3dL, 0x76dc4190L, 0x01db7106L,
|
||||
0x98d220bcL, 0xefd5102aL, 0x71b18589L,
|
||||
0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
|
||||
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||||
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL,
|
||||
0x91646c97L, 0xe6635c01L, 0x6b6b51f4L,
|
||||
0x1c6c6162L, 0x856530d8L, 0xf262004eL,
|
||||
0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L,
|
||||
0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||||
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL,
|
||||
0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
|
||||
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L,
|
||||
0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L,
|
||||
0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||||
0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
|
||||
0x44042d73L, 0x33031de5L, 0xaa0a4c5fL,
|
||||
0xdd0d7cc9L, 0x5005713cL, 0x270241aaL,
|
||||
0xbe0b1010L, 0xc90c2086L, 0x5768b525L,
|
||||
0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L,
|
||||
0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L,
|
||||
0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L,
|
||||
0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
|
||||
0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||||
0x73dc1683L, 0xe3630b12L, 0x94643b84L,
|
||||
0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL,
|
||||
0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
|
||||
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L,
|
||||
0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||||
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L,
|
||||
0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
|
||||
0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L,
|
||||
0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL,
|
||||
0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||||
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
|
||||
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L,
|
||||
0x41047a60L, 0xdf60efc3L, 0xa867df55L,
|
||||
0x316e8eefL, 0x4669be79L, 0xcb61b38cL,
|
||||
0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L,
|
||||
0x5505262fL, 0xc5ba3bbeL, 0xb2bd0b28L,
|
||||
0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L,
|
||||
0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
|
||||
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||||
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL,
|
||||
0x72076785L, 0x05005713L, 0x95bf4a82L,
|
||||
0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
|
||||
0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L,
|
||||
0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||||
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL,
|
||||
0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
|
||||
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL,
|
||||
0x11010b5cL, 0x8f659effL, 0xf862ae69L,
|
||||
0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||||
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
|
||||
0xa7672661L, 0xd06016f7L, 0x4969474dL,
|
||||
0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL,
|
||||
0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L,
|
||||
0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L,
|
||||
0x24b4a3a6L, 0xbad03605L, 0xcdd70693L,
|
||||
0x54de5729L, 0x23d967bfL, 0xb3667a2eL,
|
||||
0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
|
||||
0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||||
0x2d02ef8dL
|
||||
};
|
||||
|
||||
static tUINT32 *g_ppCRC32_Table = &g_pCRC32_Table[0];
|
||||
|
||||
#include "PCRC32.h"
|
||||
|
||||
#endif //CRC32_H
|
||||
519
p7lib/Shared/DnsResolver.h
Normal file
519
p7lib/Shared/DnsResolver.h
Normal file
@ -0,0 +1,519 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef DNS_RESOLVER_H
|
||||
#define DNS_RESOLVER_H
|
||||
|
||||
#include "AList.h"
|
||||
#include "RBTree.h"
|
||||
#include "PSocket.h"
|
||||
#include "PAtomic.h"
|
||||
#include "PLock.h"
|
||||
#include "IMEvent.h"
|
||||
#include "PMEvent.h"
|
||||
#include "PThreadShell.h"
|
||||
#include "PTime.h"
|
||||
|
||||
#if !defined(NI_MAXHOST)
|
||||
#define NI_MAXHOST 1025 /* Max size of a fully-qualified domain name */
|
||||
#endif
|
||||
|
||||
#define DNS_RESOLVE_TIME_OUT_MIN (50)
|
||||
#define DNS_RESOLVE_TIME_OUT_MAX (500)
|
||||
|
||||
#define DNS_RESOLVER_EXIT_EVENT (MEVENT_SIGNAL_0)
|
||||
#define DNS_RESOLVER_EVENT (MEVENT_SIGNAL_0 + 1)
|
||||
|
||||
#define DNS_NAME_EVENT (MEVENT_SIGNAL_0)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CDNS_Item
|
||||
class CDNS_Item
|
||||
{
|
||||
tXCHAR *m_pName; //host name
|
||||
tXCHAR m_pIP[96];
|
||||
size_t m_szName_Max; //host name max length
|
||||
size_t m_szName; //host name current length
|
||||
sockaddr_storage m_sSAS; //host Socket address V4/V6
|
||||
CMEvent m_cEvent;
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CDNS_Item
|
||||
CDNS_Item(sockaddr *i_pSA)
|
||||
: m_pName(NULL)
|
||||
, m_szName_Max(0)
|
||||
, m_szName(0)
|
||||
{
|
||||
if (AF_INET == i_pSA->sa_family)
|
||||
{
|
||||
memcpy(&m_sSAS, i_pSA, sizeof(sockaddr_in));
|
||||
((sockaddr_in*)&m_sSAS)->sin_port = 0;
|
||||
}
|
||||
else if (AF_INET6 == i_pSA->sa_family)
|
||||
{
|
||||
memcpy(&m_sSAS, i_pSA, sizeof(sockaddr_in6));
|
||||
((sockaddr_in6*)&m_sSAS)->sin6_port = 0;
|
||||
}
|
||||
|
||||
if (Print_SAddr((sockaddr*)&m_sSAS, m_pIP, LENGTH(m_pIP)))
|
||||
{
|
||||
size_t l_szIP = PStrLen(m_pIP);
|
||||
|
||||
for (size_t l_szI = 0; l_szI < l_szIP; l_szI ++)
|
||||
{
|
||||
if (TM(':') == m_pIP[l_szI])
|
||||
{
|
||||
m_pIP[l_szI] = TM('x');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PStrCpy(m_pIP, LENGTH(m_pIP), TM("Unknown"));
|
||||
}
|
||||
|
||||
m_cEvent.Init(1, EMEVENT_SINGLE_AUTO);
|
||||
}//CDNS_Item
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//~CDNS_Item
|
||||
~CDNS_Item()
|
||||
{
|
||||
if (m_pName)
|
||||
{
|
||||
delete [] m_pName;
|
||||
m_pName = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_SA
|
||||
const sockaddr *Get_SA()
|
||||
{
|
||||
return (sockaddr*)&m_sSAS;
|
||||
}//Get_SA
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Event
|
||||
CMEvent *Get_Event()
|
||||
{
|
||||
return &m_cEvent;
|
||||
}//Get_Event
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Update
|
||||
tBOOL Update(tXCHAR *i_pName)
|
||||
{
|
||||
tXCHAR *l_pName = (i_pName) ? i_pName : m_pIP;
|
||||
size_t l_szName = PStrLen(l_pName);
|
||||
|
||||
if (l_szName > m_szName_Max)
|
||||
{
|
||||
if (m_pName)
|
||||
{
|
||||
delete [] m_pName;
|
||||
m_pName = NULL;
|
||||
}
|
||||
|
||||
m_szName_Max = (l_szName + 1 + 15) & (~15UL);
|
||||
m_pName = new tXCHAR[m_szName_Max];
|
||||
}
|
||||
|
||||
if (NULL != m_pName)
|
||||
{
|
||||
m_szName = l_szName;
|
||||
PStrCpy(m_pName, m_szName_Max, l_pName);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_szName = 0;
|
||||
m_szName_Max = 0;
|
||||
}
|
||||
|
||||
return (m_pName) ? TRUE : FALSE;
|
||||
}//Update
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Name()
|
||||
tBOOL Get_Name(tXCHAR *o_pName, size_t i_szLength_Max)
|
||||
{
|
||||
if ( (o_pName)
|
||||
&& (1 < i_szLength_Max)
|
||||
)
|
||||
{
|
||||
if (m_szName >= i_szLength_Max)
|
||||
{
|
||||
PStrNCpy(o_pName, i_szLength_Max, m_pName, i_szLength_Max - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
PStrCpy(o_pName, i_szLength_Max, m_pName);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}//Get_Name()
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Is_Greater -> (m_sSA > i_pSA) == TRUE
|
||||
tBOOL Is_Greater(sockaddr *i_pSA)
|
||||
{
|
||||
if (m_sSAS.ss_family > i_pSA->sa_family)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if (m_sSAS.ss_family < i_pSA->sa_family)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (AF_INET == i_pSA->sa_family)
|
||||
{
|
||||
return (((sockaddr_in*)&m_sSAS)->sin_addr.s_addr > ((sockaddr_in*)i_pSA)->sin_addr.s_addr);
|
||||
}
|
||||
else if (AF_INET6 == i_pSA->sa_family)
|
||||
{
|
||||
return (0 < memcmp(((sockaddr_in6*)&m_sSAS)->sin6_addr.s6_addr,
|
||||
((sockaddr_in6*)i_pSA)->sin6_addr.s6_addr,
|
||||
sizeof(in6_addr)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}//Is_Greater
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Is_Equal
|
||||
tBOOL Is_Equal(sockaddr *i_pSA)
|
||||
{
|
||||
if (m_sSAS.ss_family == i_pSA->sa_family)
|
||||
{
|
||||
if (AF_INET == i_pSA->sa_family)
|
||||
{
|
||||
return (((sockaddr_in*)&m_sSAS)->sin_addr.s_addr == ((sockaddr_in*)i_pSA)->sin_addr.s_addr);
|
||||
}
|
||||
else if (AF_INET6 == i_pSA->sa_family)
|
||||
{
|
||||
return (0 == memcmp(((sockaddr_in6*)&m_sSAS)->sin6_addr.s6_addr,
|
||||
((sockaddr_in6*)i_pSA)->sin6_addr.s6_addr,
|
||||
sizeof(in6_addr)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}//Is_Equal
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CDNS_Resolver
|
||||
class CDNS_Resolver:
|
||||
public CRBTree<CDNS_Item*, sockaddr*>
|
||||
{
|
||||
volatile tINT32 m_lTimeOut;
|
||||
tLOCK m_sCS;
|
||||
CThShell::tTHREAD m_hThread;
|
||||
tBOOL m_bIsThread;
|
||||
CMEvent m_cEvent;
|
||||
CBList<CDNS_Item*> m_cRecords;
|
||||
CBList<CDNS_Item*> m_cResolving;
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CDNS_Resolver()
|
||||
CDNS_Resolver()
|
||||
: CRBTree<CDNS_Item*, sockaddr*>(32, FALSE)
|
||||
, m_lTimeOut(DNS_RESOLVE_TIME_OUT_MAX)
|
||||
, m_bIsThread(FALSE)
|
||||
, m_cRecords(32)
|
||||
{
|
||||
LOCK_CREATE(m_sCS);
|
||||
|
||||
m_cEvent.Init(2, EMEVENT_SINGLE_AUTO, EMEVENT_MULTI);
|
||||
|
||||
if (CThShell::Create(&Static_Routine, this, &m_hThread, TM("DNSR")))
|
||||
{
|
||||
m_bIsThread = TRUE;
|
||||
}
|
||||
|
||||
}//~CDNS_Resolver()
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//~CDNS_Resolver()
|
||||
~CDNS_Resolver()
|
||||
{
|
||||
if (m_bIsThread)
|
||||
{
|
||||
m_cEvent.Set(DNS_RESOLVER_EXIT_EVENT);
|
||||
if (TRUE == CThShell::Close(m_hThread, 90000))
|
||||
{
|
||||
m_hThread = 0;//NULL;
|
||||
m_bIsThread = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
m_cResolving.Clear(FALSE);
|
||||
m_cRecords.Clear(TRUE);
|
||||
|
||||
LOCK_DESTROY(m_sCS);
|
||||
}//~CDNS_Resolver()
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Name()
|
||||
tBOOL Get_Name(sockaddr *i_pKey, tXCHAR *o_pName, size_t i_szName, tBOOL *o_pNew)
|
||||
{
|
||||
CDNS_Item *l_pRec = NULL;
|
||||
tBOOL l_bAdd = FALSE;
|
||||
|
||||
if ( (NULL == i_pKey)
|
||||
|| ( (AF_INET != i_pKey->sa_family)
|
||||
&& (AF_INET6 != i_pKey->sa_family)
|
||||
)
|
||||
|| (NULL == o_pName)
|
||||
|| (16 > i_szName)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LOCK_ENTER(m_sCS);
|
||||
l_pRec = this->Find(i_pKey);
|
||||
if (NULL == l_pRec)
|
||||
{
|
||||
l_pRec = new CDNS_Item(i_pKey);
|
||||
if (l_pRec)
|
||||
{
|
||||
this->Push(l_pRec, i_pKey);
|
||||
m_cRecords.Add_After(m_cRecords.Get_Last(), l_pRec);
|
||||
l_pRec->Update(NULL);
|
||||
l_bAdd = TRUE;
|
||||
}
|
||||
|
||||
if (o_pNew)
|
||||
{
|
||||
*o_pNew = 1;
|
||||
}
|
||||
}
|
||||
LOCK_EXIT(m_sCS);
|
||||
|
||||
if (l_bAdd)
|
||||
{
|
||||
LOCK_ENTER(m_sCS);
|
||||
m_cResolving.Add_After(m_cResolving.Get_Last(), l_pRec);
|
||||
m_cEvent.Set(DNS_RESOLVER_EVENT);
|
||||
LOCK_EXIT(m_sCS);
|
||||
|
||||
l_pRec->Get_Event()->Wait((tUINT32)m_lTimeOut);
|
||||
}//if (NULL == l_pRec)
|
||||
|
||||
LOCK_ENTER(m_sCS);
|
||||
if (l_pRec)
|
||||
{
|
||||
l_pRec->Get_Name(o_pName, i_szName);
|
||||
}
|
||||
LOCK_EXIT(m_sCS);
|
||||
|
||||
return (NULL != l_pRec);
|
||||
}//Get_Name()
|
||||
|
||||
protected:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Return
|
||||
//TRUE - if (i_pKey < i_pData::key)
|
||||
//FALSE - otherwise
|
||||
tBOOL Is_Key_Less(sockaddr *i_pKey, CDNS_Item *i_pData)
|
||||
{
|
||||
return i_pData->Is_Greater(i_pKey);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Return
|
||||
//TRUE - if (i_pKey == i_pData::key)
|
||||
//FALSE - otherwise
|
||||
tBOOL Is_Qual(sockaddr *i_pKey, CDNS_Item *i_pData)
|
||||
{
|
||||
return i_pData->Is_Equal(i_pKey);
|
||||
}
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Routine_Static
|
||||
static THSHELL_RET_TYPE THSHELL_CALL_TYPE Static_Routine(void *i_pContext)
|
||||
{
|
||||
CDNS_Resolver * l_pRoutine = (CDNS_Resolver *)i_pContext;
|
||||
if (l_pRoutine)
|
||||
{
|
||||
l_pRoutine->Routine();
|
||||
}
|
||||
|
||||
CThShell::Cleanup();
|
||||
return THSHELL_RET_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Routine
|
||||
void Routine()
|
||||
{
|
||||
tXCHAR l_pName[NI_MAXHOST];
|
||||
tBOOL l_bExit = FALSE;
|
||||
pAList_Cell l_pEl = NULL;
|
||||
CDNS_Item *l_pRec = NULL;
|
||||
tUINT32 l_dwWFMOR = 0;
|
||||
tINT32 l_lWaitMax = -1;
|
||||
tUINT32 l_dwTick = 0;
|
||||
|
||||
while (FALSE == l_bExit)
|
||||
{
|
||||
l_dwWFMOR = m_cEvent.Wait(1000);
|
||||
|
||||
if (DNS_RESOLVER_EXIT_EVENT == l_dwWFMOR)
|
||||
{
|
||||
l_bExit = TRUE;
|
||||
}
|
||||
else if (DNS_RESOLVER_EVENT == l_dwWFMOR)
|
||||
{
|
||||
LOCK_ENTER(m_sCS);
|
||||
l_pRec = m_cResolving.Get_Data(m_cResolving.Get_First());
|
||||
m_cResolving.Del(m_cResolving.Get_First(), FALSE);
|
||||
LOCK_EXIT(m_sCS);
|
||||
|
||||
if (l_pRec)
|
||||
{
|
||||
l_dwTick = GetTickCount();
|
||||
if (Resolve_SA(l_pRec->Get_SA(), l_pName, LENGTH(l_pName)))
|
||||
{
|
||||
l_dwTick = CTicks::Difference(GetTickCount(), l_dwTick);
|
||||
LOCK_ENTER(m_sCS);
|
||||
l_pRec->Update(l_pName);
|
||||
LOCK_EXIT(m_sCS);
|
||||
}
|
||||
else
|
||||
{
|
||||
l_dwTick = 0;
|
||||
|
||||
LOCK_ENTER(m_sCS);
|
||||
l_pRec->Update(NULL);
|
||||
LOCK_EXIT(m_sCS);
|
||||
}
|
||||
l_pRec->Get_Event()->Set(DNS_NAME_EVENT);
|
||||
}
|
||||
|
||||
//Update waiting timeout based on maximum waiting of response
|
||||
//from DNS server
|
||||
if ((tINT32)l_dwTick > l_lWaitMax)
|
||||
{
|
||||
//set timeout with max limit of DNS_RESOLVE_TIME_OUT
|
||||
if (l_dwTick > DNS_RESOLVE_TIME_OUT_MAX)
|
||||
{
|
||||
l_lWaitMax = DNS_RESOLVE_TIME_OUT_MAX;
|
||||
}
|
||||
else if (l_dwTick < DNS_RESOLVE_TIME_OUT_MIN)
|
||||
{
|
||||
l_lWaitMax = DNS_RESOLVE_TIME_OUT_MIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_lWaitMax = (tINT32)l_dwTick;
|
||||
}
|
||||
|
||||
if (l_lWaitMax != m_lTimeOut)
|
||||
{
|
||||
ATOMIC_SET(&m_lTimeOut, l_lWaitMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (MEVENT_TIME_OUT == l_dwWFMOR)
|
||||
{
|
||||
LOCK_ENTER(m_sCS);
|
||||
l_pEl = m_cRecords.Get_Next(l_pEl);
|
||||
l_pRec = m_cRecords.Get_Data(l_pEl);
|
||||
LOCK_EXIT(m_sCS);
|
||||
|
||||
if (l_pRec)
|
||||
{
|
||||
if (Resolve_SA(l_pRec->Get_SA(), l_pName, LENGTH(l_pName)))
|
||||
{
|
||||
LOCK_ENTER(m_sCS);
|
||||
l_pRec->Update(l_pName);
|
||||
LOCK_EXIT(m_sCS);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCK_ENTER(m_sCS);
|
||||
l_pRec->Update(NULL);
|
||||
LOCK_EXIT(m_sCS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}//Routine
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Resolve_SA
|
||||
tBOOL Resolve_SA(const sockaddr *i_pSA, tXCHAR *o_pName, tUINT32 i_dwLength)
|
||||
{
|
||||
tUINT32 l_dwIP_Size = 0;
|
||||
tBOOL l_bReturn = FALSE;
|
||||
|
||||
if (NULL == i_pSA)
|
||||
{
|
||||
return l_bReturn;
|
||||
}
|
||||
|
||||
|
||||
if (AF_INET == i_pSA->sa_family)
|
||||
{
|
||||
l_dwIP_Size = sizeof(sockaddr_in);
|
||||
}
|
||||
else if (AF_INET6 == i_pSA->sa_family)
|
||||
{
|
||||
l_dwIP_Size = sizeof(sockaddr_in6);
|
||||
}
|
||||
|
||||
#ifdef UTF8_ENCODING
|
||||
int l_iRes = getnameinfo(i_pSA, l_dwIP_Size,
|
||||
o_pName, i_dwLength,
|
||||
NULL, 0,
|
||||
NI_NAMEREQD
|
||||
);
|
||||
#else
|
||||
int l_iRes = GetNameInfoW(i_pSA, l_dwIP_Size,
|
||||
o_pName, i_dwLength,
|
||||
NULL, 0,
|
||||
NI_NAMEREQD
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
if (0 == l_iRes)
|
||||
{
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}//Resolve_SA
|
||||
};//CDNS_Resolver
|
||||
|
||||
#endif //DNS_RESOLVER_H
|
||||
929
p7lib/Shared/IConsole.h
Normal file
929
p7lib/Shared/IConsole.h
Normal file
@ -0,0 +1,929 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef ICONSOLE_H
|
||||
#define ICONSOLE_H
|
||||
|
||||
#define CON_RIGHT_ALT_PRESSED 0x0001 // the right alt key is pressed.
|
||||
#define CON_LEFT_ALT_PRESSED 0x0002 // the left alt key is pressed.
|
||||
#define CON_RIGHT_CTRL_PRESSED 0x0004 // the right ctrl key is pressed.
|
||||
#define CON_LEFT_CTRL_PRESSED 0x0008 // the left ctrl key is pressed.
|
||||
#define CON_SHIFT_PRESSED 0x0010 // the shift key is pressed.
|
||||
#define CON_NUMLOCK_ON 0x0020 // the numlock light is on.
|
||||
#define CON_SCROLLLOCK_ON 0x0040 // the scrolllock light is on.
|
||||
#define CON_CAPSLOCK_ON 0x0080 // the capslock light is on.
|
||||
#define CON_ENHANCED_KEY 0x0100 // the key is enhanced.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
class IConsole
|
||||
{
|
||||
public:
|
||||
enum eColor
|
||||
{
|
||||
eBlack = 0,
|
||||
eBlue,
|
||||
eGreen,
|
||||
eCyan,
|
||||
eRed,
|
||||
eMagenta,
|
||||
eBrown,
|
||||
eLightGray,
|
||||
eDarkGray,
|
||||
eLightBlue,
|
||||
eLightGreen,
|
||||
eLightCyan,
|
||||
eLightRed,
|
||||
eLightMagenta,
|
||||
eYellow,
|
||||
eWhite,
|
||||
eColorsMax
|
||||
};
|
||||
|
||||
enum eEvent
|
||||
{
|
||||
eSize = 0,
|
||||
eMouse,
|
||||
eKey,
|
||||
eFocus,
|
||||
eEventsMax
|
||||
};
|
||||
|
||||
enum eKey
|
||||
{
|
||||
eKeyEsc = 27,
|
||||
eKeyEnter = 13,
|
||||
eKeySpace = 32,
|
||||
|
||||
eKeyExtra = 0x100,
|
||||
eKeyArrowLeft,
|
||||
eKeyArrowRight,
|
||||
eKeyArrowDown,
|
||||
eKeyArrowUp,
|
||||
eKeyPageUp,
|
||||
eKeyPageDown,
|
||||
eKeyHome,
|
||||
eKeyEnd,
|
||||
eKeyF1,
|
||||
eKeyF2,
|
||||
eKeyF3,
|
||||
eKeyF4,
|
||||
eKeyF5,
|
||||
eKeyF6,
|
||||
eKeyF7,
|
||||
eKeyF8,
|
||||
eKeyF9,
|
||||
eKeyF10,
|
||||
eKeyF11,
|
||||
eKeyF12,
|
||||
eKeyDel,
|
||||
eKeyInsert,
|
||||
eKeyTab,
|
||||
eKeyBackSpace,
|
||||
|
||||
eKeyMax
|
||||
};
|
||||
|
||||
struct sSize
|
||||
{
|
||||
tUINT32 uW;
|
||||
tUINT32 uH;
|
||||
};
|
||||
|
||||
struct sMouse
|
||||
{
|
||||
tUINT32 uX;
|
||||
tUINT32 uY;
|
||||
tUINT32 uButton;
|
||||
};
|
||||
|
||||
struct sKey
|
||||
{
|
||||
tBOOL bDown;
|
||||
tUINT16 wKey;
|
||||
tUINT16 wCount;
|
||||
tUINT32 uControls;
|
||||
};
|
||||
|
||||
struct sFocus
|
||||
{
|
||||
tBOOL bFocus;
|
||||
};
|
||||
|
||||
struct sInput
|
||||
{
|
||||
IConsole::eEvent eEvent;
|
||||
union
|
||||
{
|
||||
sSize stSize;
|
||||
sMouse stMouse;
|
||||
sKey stKey;
|
||||
sFocus stFocus;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
virtual tBOOL SetCursor(tUINT32 i_uX, tUINT32 i_uY) = 0;
|
||||
virtual tUINT32 GetCursorX() = 0;
|
||||
virtual tUINT32 GetCursorY() = 0;
|
||||
virtual tUINT32 GetWidth() = 0;
|
||||
virtual tUINT32 GetHeight() = 0;
|
||||
virtual tBOOL SetTextAttr(IConsole::eColor i_eFg, IConsole::eColor i_eBg) = 0;
|
||||
virtual tBOOL GetInput(IConsole::sInput &o_rInput) = 0;
|
||||
virtual tBOOL Clear() = 0;
|
||||
virtual tBOOL Clear(tUINT32 i_uX, tUINT32 i_uY, tUINT32 i_uW, tUINT32 i_uH, IConsole::eColor i_eBg) = 0;
|
||||
virtual size_t WriteTextB(const tXCHAR *i_pText, size_t i_szText) = 0;
|
||||
virtual size_t WriteTextB(IConsole::eColor i_eFg,
|
||||
IConsole::eColor i_eBg,
|
||||
size_t i_szLenMin,
|
||||
size_t i_szLenMax,
|
||||
size_t i_szOffset,
|
||||
tXCHAR *i_pText,
|
||||
size_t i_szText,
|
||||
size_t i_szTextMax
|
||||
) = 0;
|
||||
|
||||
virtual size_t WriteTextO(IConsole::eColor i_eFg,
|
||||
IConsole::eColor i_eBg,
|
||||
size_t i_szLenMin,
|
||||
size_t i_szLenMax,
|
||||
size_t i_szOffset,
|
||||
const tXCHAR *i_pFormat,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list l_pVA;
|
||||
size_t l_szReturn = 0;
|
||||
|
||||
va_start(l_pVA, i_pFormat);
|
||||
l_szReturn = WriteTextF(i_eFg, i_eBg, i_szLenMin, i_szLenMax, i_szOffset, i_pFormat, l_pVA);
|
||||
va_end(l_pVA);
|
||||
return l_szReturn;
|
||||
}
|
||||
|
||||
virtual size_t WriteText(IConsole::eColor i_eFg,
|
||||
IConsole::eColor i_eBg,
|
||||
size_t i_szLenMin,
|
||||
size_t i_szLenMax,
|
||||
const tXCHAR *i_pFormat,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list l_pVA;
|
||||
size_t l_szReturn = 0;
|
||||
|
||||
va_start(l_pVA, i_pFormat);
|
||||
l_szReturn = WriteTextF(i_eFg, i_eBg, i_szLenMin, i_szLenMax, 0, i_pFormat, l_pVA);
|
||||
va_end(l_pVA);
|
||||
return l_szReturn;
|
||||
}
|
||||
|
||||
|
||||
virtual size_t WriteTextF(IConsole::eColor i_eFg,
|
||||
IConsole::eColor i_eBg,
|
||||
size_t i_szLenMin,
|
||||
size_t i_szLenMax,
|
||||
size_t i_szOffset,
|
||||
const tXCHAR *i_pFormat,
|
||||
va_list i_pVA
|
||||
) = 0;
|
||||
|
||||
virtual tBOOL Present() = 0;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
class CConsoleWnd
|
||||
{
|
||||
struct stHelp
|
||||
{
|
||||
tXCHAR *pString;
|
||||
IConsole::eColor eBgColor;
|
||||
IConsole::eColor eFgColor;
|
||||
|
||||
stHelp(const tXCHAR *i_pString, IConsole::eColor i_eBgColor, IConsole::eColor i_eFgColor)
|
||||
{
|
||||
pString = PStrDub(i_pString);
|
||||
eBgColor = i_eBgColor;
|
||||
eFgColor = i_eFgColor;
|
||||
}
|
||||
|
||||
~stHelp()
|
||||
{
|
||||
if (pString)
|
||||
{
|
||||
free(pString);
|
||||
pString = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
struct stColumn
|
||||
{
|
||||
tUINT32 uId;
|
||||
tBOOL bVisible;
|
||||
tXCHAR *pCaption;
|
||||
size_t szCaption;
|
||||
|
||||
stColumn(tUINT32 i_uId, tBOOL i_bVisible, const tXCHAR *i_pCaption)
|
||||
: pCaption(NULL)
|
||||
{
|
||||
uId = i_uId;
|
||||
bVisible = i_bVisible;
|
||||
SetCaption(i_pCaption);
|
||||
}
|
||||
|
||||
~stColumn()
|
||||
{
|
||||
if (pCaption)
|
||||
{
|
||||
PStrFreeDub(pCaption);
|
||||
pCaption = NULL;
|
||||
}
|
||||
uId = 0;
|
||||
bVisible = FALSE;
|
||||
szCaption = 0;
|
||||
}
|
||||
|
||||
void SetCaption(const tXCHAR *i_pCaption)
|
||||
{
|
||||
if (pCaption)
|
||||
{
|
||||
PStrFreeDub(pCaption);
|
||||
}
|
||||
|
||||
pCaption = PStrDub(i_pCaption);
|
||||
szCaption = PStrLen(pCaption);
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
tUINT32 m_uX;
|
||||
tUINT32 m_uY;
|
||||
tUINT32 m_uW;
|
||||
tUINT32 m_uH;
|
||||
size_t m_szLinesPerItem;
|
||||
size_t m_szItemsPerWnd;
|
||||
tUINT64 m_qwItemsCount;
|
||||
IConsole *m_pConsole;
|
||||
IConsole::eColor m_eWindowBgColor;
|
||||
|
||||
IConsole::eColor m_eItemBgColor;
|
||||
IConsole::eColor m_eItemFgColor;
|
||||
|
||||
IConsole::eColor m_eItemSlFgColor;
|
||||
IConsole::eColor m_eItemSlBgColor;
|
||||
|
||||
IConsole::eColor m_eItemClFgColor;
|
||||
IConsole::eColor m_eItemClBgColor;
|
||||
|
||||
tBOOL m_bError;
|
||||
tXCHAR *m_pCaption;
|
||||
size_t m_szOffsetX;
|
||||
size_t m_szOffsetY;
|
||||
tUINT64 m_qwOffsetWnd;
|
||||
tBOOL m_bHelp;
|
||||
CBList<stHelp*> m_cHelp;
|
||||
CBList<stColumn*>m_cColumns;
|
||||
tBOOL m_bColumns;
|
||||
tBOOL m_bUpdateColumns;
|
||||
tXCHAR *m_pColumnsText;
|
||||
size_t m_szColumnsTextMax;
|
||||
size_t m_szColumnsText;
|
||||
|
||||
public:
|
||||
struct sCfg
|
||||
{
|
||||
tUINT32 uX;
|
||||
tUINT32 uY;
|
||||
tUINT32 uW;
|
||||
tUINT32 uH;
|
||||
size_t uLinesPerItem;
|
||||
size_t szItemsCount;
|
||||
IConsole *pConsole;
|
||||
IConsole::eColor eWindowBgColor;
|
||||
IConsole::eColor eItemBgColor;
|
||||
IConsole::eColor eItemFgColor;
|
||||
IConsole::eColor eItemSlFgColor;
|
||||
IConsole::eColor eItemSlBgColor;
|
||||
IConsole::eColor eItemClFgColor;
|
||||
IConsole::eColor eItemClBgColor;
|
||||
const tXCHAR *pCaption;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
CConsoleWnd()
|
||||
: m_uX(0)
|
||||
, m_uY(0)
|
||||
, m_uW(0)
|
||||
, m_uH(0)
|
||||
, m_szLinesPerItem(0)
|
||||
, m_szItemsPerWnd(0)
|
||||
, m_qwItemsCount(0ull)
|
||||
, m_pConsole(NULL)
|
||||
, m_eWindowBgColor(IConsole::eBlack)
|
||||
, m_eItemBgColor(IConsole::eBlack)
|
||||
, m_eItemFgColor(IConsole::eGreen)
|
||||
, m_eItemSlFgColor(IConsole::eBlue)
|
||||
, m_eItemSlBgColor(IConsole::eBlack)
|
||||
, m_eItemClFgColor(IConsole::eWhite)
|
||||
, m_eItemClBgColor(IConsole::eDarkGray)
|
||||
, m_bError(FALSE)
|
||||
, m_pCaption(NULL)
|
||||
, m_szOffsetX(0)
|
||||
, m_szOffsetY(0)
|
||||
, m_qwOffsetWnd(0)
|
||||
, m_bHelp(FALSE)
|
||||
, m_bColumns(FALSE)
|
||||
, m_bUpdateColumns(FALSE)
|
||||
, m_pColumnsText(NULL)
|
||||
, m_szColumnsTextMax(0)
|
||||
, m_szColumnsText(0)
|
||||
{
|
||||
CConsoleWnd::PushHelpString(TM(" Navigation keys mapping:"), IConsole::eBlue, IConsole::eWhite);
|
||||
CConsoleWnd::PushHelpString(TM(" * Arrow Up, Down, Page Up, Page down - move cursor"), IConsole::eBlack, IConsole::eGreen);
|
||||
CConsoleWnd::PushHelpString(TM(" * Arrow Left, Right - horizontal scroll"), IConsole::eBlack, IConsole::eGreen);
|
||||
CConsoleWnd::PushHelpString(TM(" * Home - goto top"), IConsole::eBlack, IConsole::eGreen);
|
||||
CConsoleWnd::PushHelpString(TM(" * End - goto bottom"), IConsole::eBlack, IConsole::eGreen);
|
||||
CConsoleWnd::PushHelpString(TM(" * Esc - exit to upper level or quit"), IConsole::eBlack, IConsole::eGreen);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual tBOOL Init(const CConsoleWnd::sCfg &i_rConfig)
|
||||
{
|
||||
m_pConsole = i_rConfig.pConsole;
|
||||
m_eWindowBgColor = i_rConfig.eWindowBgColor;
|
||||
m_eItemBgColor = i_rConfig.eItemBgColor;
|
||||
m_eItemFgColor = i_rConfig.eItemFgColor;
|
||||
m_eItemSlFgColor = i_rConfig.eItemSlFgColor;
|
||||
m_eItemSlBgColor = i_rConfig.eItemSlBgColor;
|
||||
m_eItemClFgColor = i_rConfig.eItemClFgColor;
|
||||
m_eItemClBgColor = i_rConfig.eItemClBgColor;
|
||||
m_szLinesPerItem = i_rConfig.uLinesPerItem;
|
||||
m_qwItemsCount = i_rConfig.szItemsCount;
|
||||
|
||||
SetCaption(i_rConfig.pCaption);
|
||||
|
||||
m_pConsole->SetCursor(i_rConfig.uX, i_rConfig.uY);
|
||||
m_pConsole->Clear(i_rConfig.uX, i_rConfig.uY, i_rConfig.uW, i_rConfig.uH, m_eWindowBgColor);
|
||||
|
||||
return Resize(i_rConfig.uX, i_rConfig.uY, i_rConfig.uW, i_rConfig.uH);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetContext(void *i_pContext)
|
||||
{
|
||||
UNUSED_ARG(i_pContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual ~CConsoleWnd()
|
||||
{
|
||||
m_cHelp.Clear(TRUE);
|
||||
m_cColumns.Clear(TRUE);
|
||||
|
||||
if (m_pCaption)
|
||||
{
|
||||
PStrFreeDub(m_pCaption);
|
||||
m_pCaption = NULL;
|
||||
}
|
||||
|
||||
if (m_pColumnsText)
|
||||
{
|
||||
free(m_pColumnsText);
|
||||
m_pColumnsText = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void SetCaption(const tXCHAR *i_pCaption)
|
||||
{
|
||||
if (m_pCaption)
|
||||
{
|
||||
PStrFreeDub(m_pCaption);
|
||||
m_pCaption = NULL;
|
||||
}
|
||||
|
||||
m_pCaption = i_pCaption ? PStrDub(i_pCaption) : PStrDub(TM("?"));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual void PushHelpString(const tXCHAR *i_pString, IConsole::eColor i_eBgColor, IConsole::eColor i_eFgColor)
|
||||
{
|
||||
if (i_pString)
|
||||
{
|
||||
m_cHelp.Add_After(m_cHelp.Get_Last(), new stHelp(i_pString, i_eBgColor, i_eFgColor));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual void PushColumn(tUINT32 i_uId, tBOOL i_bVisible, const tXCHAR *i_pCaption)
|
||||
{
|
||||
if (i_pCaption)
|
||||
{
|
||||
m_cColumns.Add_After(m_cColumns.Get_Last(), new stColumn(i_uId, i_bVisible, i_pCaption));
|
||||
m_bUpdateColumns = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual void EnableColumns(tBOOL i_bEnable)
|
||||
{
|
||||
m_bUpdateColumns = TRUE;
|
||||
m_bColumns = i_bEnable;
|
||||
UpdateItemsPerWindow();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual CConsoleWnd::stColumn *GetColumn(tUINT32 i_uIndex)
|
||||
{
|
||||
return m_cColumns[i_uIndex];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual void EnableColumn(tUINT32 i_uIndex, tBOOL i_bEnable)
|
||||
{
|
||||
stColumn *l_pCol = m_cColumns[i_uIndex];
|
||||
|
||||
if (!l_pCol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
l_pCol->bVisible = i_bEnable;
|
||||
m_bUpdateColumns = TRUE;
|
||||
|
||||
if (m_bColumns)
|
||||
{
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetColumnCaption(tUINT32 i_uIndex, const tXCHAR *i_pCation)
|
||||
{
|
||||
stColumn *l_pCol = m_cColumns[i_uIndex];
|
||||
|
||||
if (!l_pCol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
l_pCol->SetCaption(i_pCation);
|
||||
m_bUpdateColumns = TRUE;
|
||||
|
||||
if (m_bColumns)
|
||||
{
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetItemsCount(tUINT64 i_qwItems)
|
||||
{
|
||||
m_qwItemsCount = i_qwItems;
|
||||
|
||||
UpdateItemsPerWindow();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual void Redraw()
|
||||
{
|
||||
if (m_bHelp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
tUINT32 l_uiOffset = 1;
|
||||
|
||||
if (m_bColumns)
|
||||
{
|
||||
l_uiOffset = 2;
|
||||
}
|
||||
|
||||
UpdateHeader();
|
||||
m_pConsole->SetCursor(m_uX, m_uY + l_uiOffset);
|
||||
size_t l_szCount = Print() + l_uiOffset;
|
||||
|
||||
if (l_szCount < (size_t)m_uH)
|
||||
{
|
||||
m_pConsole->Clear(m_uX, m_uY + (tUINT32)l_szCount, m_uW, m_uH - (tUINT32)l_szCount, m_eWindowBgColor);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual tBOOL Resize(tUINT32 i_uX, tUINT32 i_uY, tUINT32 i_uW, tUINT32 i_uH)
|
||||
{
|
||||
m_uX = i_uX;
|
||||
m_uY = i_uY;
|
||||
m_uW = i_uW;
|
||||
m_uH = i_uH;
|
||||
|
||||
UpdateItemsPerWindow();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual tBOOL ProcessKey(tUINT16 i_wChar)
|
||||
{
|
||||
if (m_bError)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tBOOL l_bReturn = FALSE;
|
||||
size_t l_szCount = (size_t)m_uH;
|
||||
tUINT32 l_uiOffset = 1;
|
||||
|
||||
if (m_bColumns)
|
||||
{
|
||||
l_uiOffset = 2;
|
||||
}
|
||||
|
||||
if (m_bHelp)
|
||||
{
|
||||
if ((tUINT16)IConsole::eKeyEsc == i_wChar)
|
||||
{
|
||||
m_bHelp = FALSE;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
else if ( ((tUINT16)IConsole::eKeyF1 == i_wChar)
|
||||
|| ((tUINT16)IConsole::eKeyF2 == i_wChar)
|
||||
)
|
||||
{
|
||||
m_bHelp = TRUE;
|
||||
|
||||
l_szCount = m_cHelp.Count() - l_uiOffset;
|
||||
m_pConsole->SetCursor(m_uX, m_uY);
|
||||
|
||||
pAList_Cell l_pEl = NULL;
|
||||
while (NULL != (l_pEl = m_cHelp.Get_Next(l_pEl)))
|
||||
{
|
||||
stHelp *l_pHelp = m_cHelp.Get_Data(l_pEl);
|
||||
if (l_pHelp)
|
||||
{
|
||||
m_pConsole->WriteText(l_pHelp->eFgColor, l_pHelp->eBgColor, m_uW, m_uW, l_pHelp->pString);
|
||||
}
|
||||
else
|
||||
{
|
||||
l_szCount --;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((tUINT16)IConsole::eKeyArrowLeft == i_wChar)
|
||||
{
|
||||
if (m_szOffsetX)
|
||||
{
|
||||
m_szOffsetX--;
|
||||
l_bReturn = TRUE;
|
||||
m_bUpdateColumns = TRUE;
|
||||
}
|
||||
}
|
||||
else if ((tUINT16)IConsole::eKeyArrowRight == i_wChar)
|
||||
{
|
||||
m_szOffsetX++;
|
||||
m_bUpdateColumns = TRUE;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
else if ((tUINT16)IConsole::eKeyArrowUp == i_wChar)
|
||||
{
|
||||
if (m_szOffsetY)
|
||||
{
|
||||
m_szOffsetY--;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
else if (m_qwOffsetWnd)
|
||||
{
|
||||
m_qwOffsetWnd--;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
}
|
||||
else if ((tUINT16)IConsole::eKeyArrowDown == i_wChar)
|
||||
{
|
||||
if ((m_szOffsetY + 1) < m_szItemsPerWnd)
|
||||
{
|
||||
m_szOffsetY++;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
else if ((m_qwOffsetWnd + (tUINT64)m_szItemsPerWnd + 1ull) <= m_qwItemsCount)
|
||||
{
|
||||
m_qwOffsetWnd++;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
}
|
||||
else if ((tUINT16)IConsole::eKeyPageUp == i_wChar)
|
||||
{
|
||||
if (m_qwOffsetWnd > (tUINT64)m_szItemsPerWnd)
|
||||
{
|
||||
m_qwOffsetWnd -= (tUINT64)m_szItemsPerWnd;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
else if (m_qwOffsetWnd)
|
||||
{
|
||||
m_qwOffsetWnd = 0;
|
||||
m_szOffsetY = 0;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
else if (m_szOffsetY)
|
||||
{
|
||||
m_szOffsetY = 0;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
}
|
||||
else if ((tUINT16)IConsole::eKeyPageDown == i_wChar)
|
||||
{
|
||||
if ((m_qwOffsetWnd + 2ull*(tUINT64)m_szItemsPerWnd) <= m_qwItemsCount)
|
||||
{
|
||||
m_qwOffsetWnd += (tUINT64)m_szItemsPerWnd;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
else if ((tUINT64)m_szItemsPerWnd <= m_qwItemsCount)
|
||||
{
|
||||
m_qwOffsetWnd = m_qwItemsCount - (tUINT64)m_szItemsPerWnd;
|
||||
m_szOffsetY = m_szItemsPerWnd - 1;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
else if (m_qwItemsCount)
|
||||
{
|
||||
m_szOffsetY = (size_t)m_qwItemsCount - 1;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
}
|
||||
else if ((tUINT16)IConsole::eKeyHome == i_wChar)
|
||||
{
|
||||
m_qwOffsetWnd = 0;
|
||||
m_szOffsetY = 0;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
else if ((tUINT16)IConsole::eKeyEnd == i_wChar)
|
||||
{
|
||||
if ((tUINT64)m_szItemsPerWnd <= m_qwItemsCount)
|
||||
{
|
||||
m_qwOffsetWnd = m_qwItemsCount - (tUINT64)m_szItemsPerWnd;
|
||||
m_szOffsetY = m_szItemsPerWnd - 1;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
else if (m_qwItemsCount)
|
||||
{
|
||||
m_szOffsetY = (size_t)m_qwItemsCount - 1;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (l_bReturn)
|
||||
{
|
||||
UpdateHeader();
|
||||
m_pConsole->SetCursor(m_uX, m_uY + l_uiOffset);
|
||||
l_szCount = Print();
|
||||
}
|
||||
|
||||
l_szCount += l_uiOffset;
|
||||
|
||||
if (l_szCount < (size_t)m_uH)
|
||||
{
|
||||
m_pConsole->Clear(m_uX, m_uY + (tUINT32)l_szCount, m_uW, m_uH - (tUINT32)l_szCount, m_eWindowBgColor);
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual size_t Print() = 0;
|
||||
|
||||
protected:
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void UpdateItemsPerWindow()
|
||||
{
|
||||
tUINT32 l_uiH = m_uH - 1;
|
||||
|
||||
if (!m_szLinesPerItem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (m_bColumns)
|
||||
&& (l_uiH)
|
||||
)
|
||||
{
|
||||
l_uiH --;
|
||||
}
|
||||
|
||||
m_szItemsPerWnd = l_uiH / m_szLinesPerItem;
|
||||
if (m_szItemsPerWnd > m_qwItemsCount)
|
||||
{
|
||||
m_szItemsPerWnd = (size_t)m_qwItemsCount;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual void UpdateHeader()
|
||||
{
|
||||
tUINT32 l_uPos = 100;
|
||||
tUINT64 l_qwOffsY = (tUINT64)m_szOffsetY;
|
||||
|
||||
if ( (l_qwOffsY)
|
||||
|| (1ull == m_qwItemsCount)
|
||||
)
|
||||
{
|
||||
l_qwOffsY++;
|
||||
}
|
||||
|
||||
if (m_qwItemsCount)
|
||||
{
|
||||
l_uPos = (tUINT32)((100ull * (m_qwOffsetWnd + l_qwOffsY)) / m_qwItemsCount);
|
||||
}
|
||||
|
||||
m_pConsole->SetCursor(m_uX, m_uY);
|
||||
m_pConsole->WriteText(IConsole::eBlack,
|
||||
IConsole::eDarkGray,
|
||||
m_uW,
|
||||
m_uW,
|
||||
TM("{%s} % 3u%% [Help = F1/F2]"),
|
||||
m_pCaption,
|
||||
l_uPos
|
||||
);
|
||||
|
||||
if (m_bColumns)
|
||||
{
|
||||
if (m_bUpdateColumns)
|
||||
{
|
||||
pAList_Cell l_pEl = NULL;
|
||||
size_t l_szLen = 0;
|
||||
|
||||
while ((l_pEl = m_cColumns.Get_Next(l_pEl))) { l_szLen += m_cColumns.Get_Data(l_pEl)->szCaption;}
|
||||
|
||||
if (l_szLen >= m_szColumnsTextMax)
|
||||
{
|
||||
if (m_pColumnsText) free(m_pColumnsText);
|
||||
m_szColumnsTextMax = l_szLen + 16;
|
||||
m_pColumnsText = (tXCHAR*)malloc(m_szColumnsTextMax * sizeof(tXCHAR));
|
||||
}
|
||||
|
||||
|
||||
m_szColumnsText = 0;
|
||||
l_pEl = NULL;
|
||||
while ((l_pEl = m_cColumns.Get_Next(l_pEl)))
|
||||
{
|
||||
stColumn *l_pCol = m_cColumns.Get_Data(l_pEl);
|
||||
|
||||
if ( (l_pCol)
|
||||
&& (l_pCol->bVisible)
|
||||
)
|
||||
{
|
||||
PStrCpy(m_pColumnsText + m_szColumnsText, m_szColumnsTextMax - m_szColumnsText, l_pCol->pCaption);
|
||||
m_szColumnsText += l_pCol->szCaption;
|
||||
}
|
||||
}
|
||||
|
||||
m_bUpdateColumns = FALSE;
|
||||
|
||||
if (!m_szColumnsText)
|
||||
{
|
||||
m_pColumnsText[0] = TM(' ');
|
||||
m_pColumnsText[1] = 0;
|
||||
m_szColumnsText = 1;
|
||||
}
|
||||
}
|
||||
|
||||
m_pConsole->WriteTextB(m_eItemClFgColor,
|
||||
m_eItemClBgColor,
|
||||
m_uW,
|
||||
m_uW,
|
||||
m_szOffsetX,
|
||||
m_pColumnsText,
|
||||
m_szColumnsText,
|
||||
m_szColumnsTextMax
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
class CConsoleInput
|
||||
{
|
||||
protected:
|
||||
tXCHAR *m_pText;
|
||||
size_t m_szText;
|
||||
size_t m_szCursor;
|
||||
tXCHAR *m_pCaption;
|
||||
tUINT32 m_uX;
|
||||
tUINT32 m_uY;
|
||||
tUINT32 m_uW;
|
||||
tUINT32 m_uH;
|
||||
|
||||
IConsole *m_pConsole;
|
||||
IConsole::eColor m_eWndFgColor;
|
||||
IConsole::eColor m_eWndBgColor;
|
||||
|
||||
IConsole::eColor m_eInpFgColor;
|
||||
IConsole::eColor m_eInpBgColor;
|
||||
|
||||
IConsole::eColor m_eCurFgColor;
|
||||
IConsole::eColor m_eCurBgColor;
|
||||
|
||||
|
||||
public:
|
||||
struct sCfg
|
||||
{
|
||||
tUINT32 uX;
|
||||
tUINT32 uY;
|
||||
tUINT32 uW;
|
||||
tUINT32 uH;
|
||||
|
||||
IConsole *pConsole;
|
||||
IConsole::eColor eWndFgColor;
|
||||
IConsole::eColor eWndBgColor;
|
||||
|
||||
IConsole::eColor eInpFgColor;
|
||||
IConsole::eColor eInpBgColor;
|
||||
|
||||
IConsole::eColor eCurFgColor;
|
||||
IConsole::eColor eCurBgColor;
|
||||
|
||||
const tXCHAR *pCaption;
|
||||
|
||||
sCfg(tUINT32 i_uX,
|
||||
tUINT32 i_uY,
|
||||
tUINT32 i_uW,
|
||||
tUINT32 i_uH,
|
||||
IConsole *i_pConsole,
|
||||
const tXCHAR *i_pCaption
|
||||
)
|
||||
: uX(i_uX)
|
||||
, uY(i_uY)
|
||||
, uW(i_uW)
|
||||
, uH(i_uH)
|
||||
, pConsole(i_pConsole)
|
||||
, eWndFgColor(IConsole::eWhite)
|
||||
, eWndBgColor(IConsole::eDarkGray)
|
||||
, eInpFgColor(IConsole::eGreen)
|
||||
, eInpBgColor(IConsole::eLightGray)
|
||||
, eCurFgColor(IConsole::eWhite)
|
||||
, eCurBgColor(IConsole::eBlue)
|
||||
, pCaption(i_pCaption)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
CConsoleInput(CConsoleInput::sCfg &i_rConfig)
|
||||
{
|
||||
UNUSED_ARG(i_rConfig);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual ~CConsoleInput()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual void Redraw()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void SetCaption(const tXCHAR *i_pCaption)
|
||||
{
|
||||
if (m_pCaption)
|
||||
{
|
||||
PStrFreeDub(m_pCaption);
|
||||
m_pCaption = NULL;
|
||||
}
|
||||
|
||||
m_pCaption = i_pCaption ? PStrDub(i_pCaption) : PStrDub(TM("?"));
|
||||
}
|
||||
|
||||
virtual tBOOL ProcessKey(tUINT16 i_wChar)
|
||||
{
|
||||
UNUSED_ARG(i_wChar);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual tBOOL Apply(const tXCHAR *i_pText) = 0;
|
||||
};
|
||||
|
||||
#endif //ICONSOLE_H
|
||||
56
p7lib/Shared/IFile.h
Normal file
56
p7lib/Shared/IFile.h
Normal file
@ -0,0 +1,56 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef IFILE_H
|
||||
#define IFILE_H
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class IFile
|
||||
{
|
||||
public:
|
||||
enum eFlags
|
||||
{
|
||||
EOPEN = 0x00000001UL,
|
||||
ECREATE = 0x00000002UL,
|
||||
EACCESS_WRITE = 0x00000004UL,
|
||||
EACCESS_READ = 0x00000008UL,
|
||||
ESHARE_WRITE = 0x00000010UL,
|
||||
ESHARE_READ = 0x00000020UL
|
||||
};
|
||||
|
||||
public:
|
||||
virtual tBOOL IsOpened() = 0;
|
||||
virtual tBOOL Open(const tXCHAR *i_pName, tUINT32 i_dwFlags) = 0;
|
||||
virtual tBOOL Close(tBOOL i_bFlush) = 0;
|
||||
virtual tBOOL Set_Position(tUINT64 i_qwOffset) = 0;
|
||||
virtual tUINT64 Get_Position() = 0;
|
||||
virtual tUINT64 Get_Size() = 0;
|
||||
virtual size_t Write(const tUINT8 *i_pBuffer,
|
||||
size_t i_szBuffer,
|
||||
tBOOL i_bFlush
|
||||
) = 0;
|
||||
virtual size_t Read(tUINT8 *o_pBuffer, size_t i_szBuffer) = 0;
|
||||
|
||||
virtual tINT32 Add_Ref() = 0;
|
||||
virtual tINT32 Release() = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif //IFILE_H
|
||||
100
p7lib/Shared/IJournal.h
Normal file
100
p7lib/Shared/IJournal.h
Normal file
@ -0,0 +1,100 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Simple logger to file/stdout /
|
||||
// Each start it create new file and delete old files if count of files is more/
|
||||
// than allowed /
|
||||
// It works in different thread /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef IJOURNAL_H
|
||||
#define IJOURNAL_H
|
||||
|
||||
#if !defined(JOURNAL_MODULE)
|
||||
#define JOURNAL_MODULE NULL
|
||||
#endif
|
||||
|
||||
#define JADD(i_pLogger, i_eVerb, ...) if (i_pLogger) (i_pLogger)->Log(i_eVerb,\
|
||||
JOURNAL_MODULE,\
|
||||
__FILE__,\
|
||||
__FUNCTION__,\
|
||||
__LINE__,\
|
||||
__VA_ARGS__);
|
||||
|
||||
#define JOURNAL_TRACE(i_pLogger, ...) JADD(i_pLogger, IJournal::eLEVEL_TRACE, __VA_ARGS__);
|
||||
#define JOURNAL_DEBUG(i_pLogger, ...) JADD(i_pLogger, IJournal::eLEVEL_DEBUG, __VA_ARGS__);
|
||||
#define JOURNAL_INFO(i_pLogger, ...) JADD(i_pLogger, IJournal::eLEVEL_INFO, __VA_ARGS__);
|
||||
#define JOURNAL_WARNING(i_pLogger, ...) JADD(i_pLogger, IJournal::eLEVEL_WARNING, __VA_ARGS__);
|
||||
#define JOURNAL_ERROR(i_pLogger, ...) JADD(i_pLogger, IJournal::eLEVEL_ERROR, __VA_ARGS__);
|
||||
#define JOURNAL_CRITICAL(i_pLogger, ...) JADD(i_pLogger, IJournal::eLEVEL_CRITICAL, __VA_ARGS__);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class IJournal
|
||||
{
|
||||
public:
|
||||
typedef void* hModule;
|
||||
|
||||
enum eTime
|
||||
{
|
||||
eTIME_YYYYMMDDHHMMSSMS = 0,
|
||||
eTIME_YYYYMMDDHHMMSS ,
|
||||
eTIME_HHMMSSMS ,
|
||||
eTIME_HHMMSS
|
||||
};
|
||||
|
||||
enum eLevel
|
||||
{
|
||||
eLEVEL_TRACE = 0,
|
||||
eLEVEL_DEBUG ,
|
||||
eLEVEL_INFO ,
|
||||
eLEVEL_WARNING ,
|
||||
eLEVEL_ERROR ,
|
||||
eLEVEL_CRITICAL ,
|
||||
|
||||
eLEVEL_COUNT
|
||||
};
|
||||
|
||||
virtual tBOOL Initialize(const tXCHAR *i_pName) = 0;
|
||||
virtual void Set_Verbosity(IJournal::eLevel i_eVerbosity) = 0;
|
||||
virtual IJournal::eLevel Get_Verbosity() = 0;
|
||||
|
||||
virtual tBOOL Register_Thread(const tXCHAR *i_pName,
|
||||
tUINT32 i_dwThreadId
|
||||
) = 0;
|
||||
virtual tBOOL Unregister_Thread(tUINT32 i_dwThreadId) = 0;
|
||||
|
||||
virtual tBOOL Register_Module(const tXCHAR *i_pName,
|
||||
IJournal::hModule *o_hModule
|
||||
) = 0;
|
||||
|
||||
virtual tBOOL Log(IJournal::eLevel i_eType,
|
||||
IJournal::hModule i_hModule,
|
||||
const char *i_pFile,
|
||||
const char *i_pFunction,
|
||||
tUINT32 i_dwLine,
|
||||
const tXCHAR *i_pFormat,
|
||||
...
|
||||
) = 0;
|
||||
|
||||
virtual tUINT64 Get_Count(IJournal::eLevel i_eType) = 0;
|
||||
virtual tINT32 Add_Ref() = 0;
|
||||
virtual tINT32 Release() = 0;
|
||||
};
|
||||
|
||||
#endif //IJOURNAL_H
|
||||
49
p7lib/Shared/IMEvent.h
Normal file
49
p7lib/Shared/IMEvent.h
Normal file
@ -0,0 +1,49 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef IMEVENT_H
|
||||
#define IMEVENT_H
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
enum eMEvent_Type
|
||||
{
|
||||
EMEVENT_SINGLE_AUTO = 0,
|
||||
EMEVENT_SINGLE_MANUAL ,
|
||||
EMEVENT_MULTI
|
||||
};
|
||||
|
||||
|
||||
#define MEVENT_TIME_OUT (0xFFFFFFF)
|
||||
#define MEVENT_SIGNAL_0 (0)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class IMEvent
|
||||
{
|
||||
public:
|
||||
//For example
|
||||
//Init(3, EMEVENT_SINGLE_AUTO, EMEVENT_SINGLE_MANUAL, EMEVENT_MULTI);
|
||||
virtual tBOOL Init(tUINT8 i_bCount, ...) = 0;
|
||||
virtual tBOOL Set(tUINT32 i_dwID) = 0;
|
||||
virtual tBOOL Clr(tUINT32 i_dwID) = 0;
|
||||
virtual tUINT32 Wait() = 0;
|
||||
virtual tUINT32 Wait(tUINT32 i_dwMSec) = 0;
|
||||
};
|
||||
|
||||
#endif //IMEVENT_H
|
||||
46
p7lib/Shared/IPerformanceInfo.h
Normal file
46
p7lib/Shared/IPerformanceInfo.h
Normal file
@ -0,0 +1,46 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef IPERFORMANCE_INFO_H
|
||||
#define IPERFORMANCE_INFO_H
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class IPerformanceInfo
|
||||
{
|
||||
public:
|
||||
enum eCounter
|
||||
{
|
||||
eCounterSystemCpu = 0,
|
||||
eCounterProcessCpu,
|
||||
eCounterProcessHandles,
|
||||
eCounterProcessThreads,
|
||||
eCounterProcessMemory,
|
||||
|
||||
eCounterTotal
|
||||
};
|
||||
|
||||
public:
|
||||
virtual tBOOL Refresh() = 0;
|
||||
virtual tINT64 Get(IPerformanceInfo::eCounter i_eCounter) = 0;
|
||||
virtual tINT32 Add_Ref() = 0;
|
||||
virtual tINT32 Release() = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif //IPERFORMANCE_INFO_H
|
||||
41
p7lib/Shared/ISignal.h
Normal file
41
p7lib/Shared/ISignal.h
Normal file
@ -0,0 +1,41 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef ISIGNAL_H
|
||||
#define ISIGNAL_H
|
||||
|
||||
enum eCrashCode
|
||||
{
|
||||
eCrashException,
|
||||
eCrashPureCall,
|
||||
eCrashMemAlloc,
|
||||
eCrashInvalidParameter,
|
||||
eCrashSignal
|
||||
};
|
||||
|
||||
typedef void (__cdecl *fnCrashHandler)(eCrashCode i_eCode, const void *i_pCrashContext, void *i_pUserContext);
|
||||
|
||||
struct stChContext
|
||||
{
|
||||
volatile int iInstalled;
|
||||
volatile int iProcessed;
|
||||
void *pUserContext;
|
||||
fnCrashHandler pUserHandler;
|
||||
};
|
||||
|
||||
#endif //ISIGNAL_H
|
||||
28
p7lib/Shared/Length.h
Normal file
28
p7lib/Shared/Length.h
Normal file
@ -0,0 +1,28 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef LENGTH_H
|
||||
#define LENGTH_H
|
||||
|
||||
template <typename Type, size_t i_szLength>
|
||||
char (&GetCharArray(Type (&i_pArray)[i_szLength]))[i_szLength];
|
||||
#define LENGTH(i_pArray) (sizeof(GetCharArray(i_pArray)))
|
||||
|
||||
#define MEMBER_SIZE(Structure, Memeber) sizeof(((Structure*)0)->Memeber)
|
||||
|
||||
#endif //LENGTH_H
|
||||
71
p7lib/Shared/Lock.h
Normal file
71
p7lib/Shared/Lock.h
Normal file
@ -0,0 +1,71 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef LOCK_H
|
||||
#define LOCK_H
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include "PLock.h"
|
||||
|
||||
class CLock
|
||||
{
|
||||
tLOCK m_hCS;
|
||||
CLock *m_pLock;
|
||||
public:
|
||||
CLock()
|
||||
: m_pLock(NULL)
|
||||
{
|
||||
LOCK_CREATE(m_hCS);
|
||||
}
|
||||
|
||||
CLock(CLock *i_pLock)
|
||||
: m_pLock(i_pLock)
|
||||
{
|
||||
m_pLock->Lock();
|
||||
}
|
||||
|
||||
virtual ~CLock()
|
||||
{
|
||||
if (NULL == m_pLock)
|
||||
{
|
||||
LOCK_DESTROY(m_hCS);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLock->Unlock();
|
||||
m_pLock = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
inline void Lock()
|
||||
{
|
||||
LOCK_ENTER(m_hCS);
|
||||
}
|
||||
|
||||
inline tBOOL Try()
|
||||
{
|
||||
return LOCK_TRY(m_hCS);
|
||||
}
|
||||
|
||||
inline void Unlock()
|
||||
{
|
||||
LOCK_EXIT(m_hCS);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //LOCK_H
|
||||
144
p7lib/Shared/Platforms/Linux_x86/PAtomic.h
Normal file
144
p7lib/Shared/Platforms/Linux_x86/PAtomic.h
Normal file
@ -0,0 +1,144 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PATOMIC_H
|
||||
#define PATOMIC_H
|
||||
|
||||
#ifdef __ARM_ARCH_5TEJ__
|
||||
|
||||
//Source:
|
||||
//http://svn.dd-wrt.com/browser/src/linux/xscale/linux-2.6.23/arch/arm/kernel/entry-armv.S?rev=8329
|
||||
// Reference prototype:
|
||||
//
|
||||
// int __kernel_cmpxchg(int oldval, int newval, int *ptr)
|
||||
//
|
||||
// Input:
|
||||
//
|
||||
// r0 = oldval
|
||||
// r1 = newval
|
||||
// r2 = ptr
|
||||
// lr = return address
|
||||
//
|
||||
// Output:
|
||||
//
|
||||
// r0 = returned value (zero or non-zero)
|
||||
// C flag = set if r0 == 0, clear if r0 != 0
|
||||
//
|
||||
// Clobbered:
|
||||
//
|
||||
// r3, ip, flags
|
||||
//
|
||||
// Definition and user space usage example:
|
||||
//
|
||||
// typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
|
||||
// #define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
|
||||
//
|
||||
// Atomically store newval in *ptr if *ptr is equal to oldval for user space.
|
||||
// Return zero if *ptr was changed or non-zero if no exchange happened.
|
||||
// The C flag is also set if *ptr was changed to allow for assembly
|
||||
// optimization in the calling code.
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// - This routine already includes memory barriers as needed.
|
||||
//
|
||||
// - A failure might be transient, i.e. it is possible, although unlikely,
|
||||
// that "failure" be returned even if *ptr == oldval.
|
||||
//
|
||||
//Another implementations:
|
||||
//http://upc.lbl.gov/web-translator/2.8.0/runtime/inst/opt/include/gasnet_atomic_bits.h
|
||||
//http://upc.lbl.gov/web-translator/ - in last versions very interesting
|
||||
// For arm 6 & 7:
|
||||
//http://lxr.free-electrons.com/source/arch/arm/include/asm/atomic.h
|
||||
|
||||
#define ATOMIC_ADD(ptr, val) \
|
||||
__extension__ ({ volatile register tINT32 *__ptr asm("r2") = (ptr); \
|
||||
register tINT32 __result asm("r1"); \
|
||||
asm volatile ( \
|
||||
"1: @ atomic_add\n\t" \
|
||||
"ldr r0, [r2]\n\t" \
|
||||
"mov r3, #0xffff0fff\n\t" \
|
||||
"add lr, pc, #4\n\t" \
|
||||
"add r1, r0, %2\n\t" \
|
||||
"add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \
|
||||
"bcc 1b" \
|
||||
: "=&r" (__result) \
|
||||
: "r" (__ptr), "rIL" (val) \
|
||||
: "r0","r3","ip","lr","cc","memory" ); \
|
||||
__result; })
|
||||
|
||||
|
||||
#define ATOMIC_SUB(ptr, val) \
|
||||
__extension__ ({ volatile register tINT32 *__ptr asm("r2") = (ptr); \
|
||||
register tINT32 __result asm("r1"); \
|
||||
asm volatile ( \
|
||||
"1: @ atomic_add\n\t" \
|
||||
"ldr r0, [r2]\n\t" \
|
||||
"mov r3, #0xffff0fff\n\t" \
|
||||
"add lr, pc, #4\n\t" \
|
||||
"sub r1, r0, %2\n\t" \
|
||||
"add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \
|
||||
"bcc 1b" \
|
||||
: "=&r" (__result) \
|
||||
: "r" (__ptr), "rIL" (val) \
|
||||
: "r0","r3","ip","lr","cc","memory" ); \
|
||||
__result; })
|
||||
|
||||
//#ifdef __ARM_ARCH_5TEJ__
|
||||
#elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_6__)
|
||||
#define ATOMIC_ADD(ptr, val) \
|
||||
__extension__ ({ int32_t tmp; \
|
||||
int result; \
|
||||
__asm__ __volatile__("@ atomic_add\n" \
|
||||
"1: ldrex %0, [%3]\n" \
|
||||
" add %0, %0, %4\n" \
|
||||
" strex %1, %0, [%3]\n" \
|
||||
" teq %1, #0\n" \
|
||||
" bne 1b" \
|
||||
: "=&r" (result), "=&r" (tmp), "+Qo" (*ptr) \
|
||||
: "r" (ptr), "Ir" (val) \
|
||||
: "cc"); \
|
||||
result;})
|
||||
|
||||
#define ATOMIC_SUB(ptr, val) \
|
||||
__extension__ ({ unsigned long tmp; \
|
||||
int result; \
|
||||
__asm__ __volatile__("@ atomic_sub\n" \
|
||||
"1: ldrex %0, [%3]\n" \
|
||||
" sub %0, %0, %4\n" \
|
||||
" strex %1, %0, [%3]\n" \
|
||||
" teq %1, #0\n" \
|
||||
" bne 1b" \
|
||||
: "=&r" (result), "=&r" (tmp), "+Qo" (*ptr) \
|
||||
: "r" (ptr), "Ir" (val) \
|
||||
: "cc"); \
|
||||
result;})
|
||||
#else //#elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_6__)
|
||||
|
||||
#define ATOMIC_ADD(io_Val, i_Add) __sync_add_and_fetch(io_Val, i_Add)
|
||||
#define ATOMIC_SUB(io_Val, i_Add) __sync_sub_and_fetch(io_Val, i_Add)
|
||||
#define ATOMIC_SET(io_Var, i_Val) __sync_lock_test_and_set(io_Var, i_Val)
|
||||
|
||||
#endif //#ifdef __ARM_ARCH_5TEJ__
|
||||
|
||||
|
||||
#define ATOMIC_INC(io_Val) ATOMIC_ADD(io_Val, 1)
|
||||
#define ATOMIC_DEC(io_Val) ATOMIC_SUB(io_Val, 1)
|
||||
|
||||
#endif //PATOMIC_H
|
||||
|
||||
85
p7lib/Shared/Platforms/Linux_x86/PCRC32.h
Normal file
85
p7lib/Shared/Platforms/Linux_x86/PCRC32.h
Normal file
@ -0,0 +1,85 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PCRC32_H
|
||||
#define PCRC32_H
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_CRC32
|
||||
//This function implement 2 calculation kinds:
|
||||
// * AT&T assembler for X86 architecture for GNU C compiler
|
||||
// * standard C function for all other cases like X64 or ARM
|
||||
//Assembler code if faster than generated by GCC (o2) up to 1% it is not a lot
|
||||
//but for big amount of data and often calculation is enough to use it.
|
||||
static UNUSED_FUNC tUINT32 Get_CRC32(tUINT8 *i_pData, size_t i_szCount)
|
||||
{
|
||||
tUINT32 l_dwResult = 0xFFFFFFFF;
|
||||
|
||||
if ( (NULL == i_pData)
|
||||
|| (0 >= i_szCount)
|
||||
)
|
||||
{
|
||||
return l_dwResult;
|
||||
}
|
||||
|
||||
#if defined(__i386__) && defined(__GNUC__) && !defined(__PIC__)
|
||||
// Register use:
|
||||
// eax - CRC32 value
|
||||
// ebx - a lot of things
|
||||
// ecx - CRC32 value
|
||||
// edx - address of end of buffer
|
||||
// esi - address of start of buffer
|
||||
// edi - CRC32 table
|
||||
|
||||
__asm__("push %%esi;" // Save the esi and edi registers
|
||||
"push %%edi;"
|
||||
//"movl l_dwResult, %%ecx;" do it already by constraints
|
||||
//"movl g_ppCRC32_Table, %%edi;"
|
||||
"leal (%%esi,%%ebx),%%edx;" // Calculate the end of the buffer
|
||||
"crc32loop:;"
|
||||
"xorl %%eax, %%eax;" // Clear the eax register"
|
||||
"movb (%%esi), %%bl;"
|
||||
"movb %%cl, %%al;" // Copy crc value into eax
|
||||
"incl %%esi;" // Advance the source pointer
|
||||
"xorb %%bl, %%al;" // Create the index into the CRC32 table
|
||||
"shr $8, %%ecx;"
|
||||
"movl (%%edi, %%eax, 4), %%ebx;" // Get the value out of the table
|
||||
"xorl %%ebx, %%ecx;" // xor with the current byte
|
||||
"cmpl %%edx, %%esi;" // Have we reached the end of the buffer?
|
||||
"jne crc32loop;"
|
||||
"pop %%edi;"
|
||||
"pop %%esi;"
|
||||
|
||||
//output
|
||||
:"=c"(l_dwResult)
|
||||
//input
|
||||
:"D"(g_ppCRC32_Table), "c"(l_dwResult), "S"(i_pData), "b"(i_szCount)
|
||||
);
|
||||
#else
|
||||
for (size_t l_szI = 0; l_szI < i_szCount; l_szI ++)
|
||||
{
|
||||
l_dwResult = g_ppCRC32_Table[(l_dwResult ^ i_pData[l_szI]) & 0xFF ] ^ (l_dwResult >> 8);
|
||||
}
|
||||
/* Suppress warning that this is not used */
|
||||
(void)g_ppCRC32_Table;
|
||||
#endif
|
||||
return l_dwResult;
|
||||
}
|
||||
|
||||
#endif //PCRC32_H
|
||||
712
p7lib/Shared/Platforms/Linux_x86/PConsole.h
Normal file
712
p7lib/Shared/Platforms/Linux_x86/PConsole.h
Normal file
@ -0,0 +1,712 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PCONSOLE_H
|
||||
#define PCONSOLE_H
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "IConsole.h"
|
||||
#include "RBTree.h"
|
||||
#include "AList.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Is_Key_Hit
|
||||
static __attribute__ ((unused)) tBOOL Is_Key_Hit(void)
|
||||
{
|
||||
struct termios oldt, newt;
|
||||
int ch;
|
||||
int oldf;
|
||||
|
||||
tcgetattr(STDIN_FILENO, &oldt);
|
||||
newt = oldt;
|
||||
newt.c_lflag &= ~(ICANON | ECHO);
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
||||
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
|
||||
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
|
||||
|
||||
ch = getchar();
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||||
fcntl(STDIN_FILENO, F_SETFL, oldf);
|
||||
|
||||
if(ch != EOF)
|
||||
{
|
||||
ungetc(ch, stdin);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}//Is_Key_Hit
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Char
|
||||
static __attribute__ ((unused)) tXCHAR Get_Char()
|
||||
{
|
||||
return getchar();
|
||||
}//Get_Char
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//SetEchoOff
|
||||
static __attribute__ ((unused)) void Set_EchoOff(tBOOL i_bOff)
|
||||
{
|
||||
struct termios termInfo;
|
||||
|
||||
if (-1 == tcgetattr(0,&termInfo))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (i_bOff)
|
||||
{
|
||||
termInfo.c_lflag &= ~ECHO; //turn off ECHO
|
||||
}
|
||||
else
|
||||
{
|
||||
termInfo.c_lflag |= ECHO; //turn on ECHO
|
||||
}
|
||||
tcsetattr(0, 0, &termInfo);
|
||||
}//Get_Char
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
struct stKeyMap
|
||||
{
|
||||
tUINT16 wKey;
|
||||
tUINT64 qwHash;
|
||||
stKeyMap(tUINT16 i_wKey,
|
||||
tUINT8 i_pv7,
|
||||
tUINT8 i_pv6,
|
||||
tUINT8 i_pv5,
|
||||
tUINT8 i_pv4,
|
||||
tUINT8 i_pv3,
|
||||
tUINT8 i_pv2,
|
||||
tUINT8 i_pv1,
|
||||
tUINT8 i_pv0
|
||||
)
|
||||
: wKey(i_wKey), qwHash(0)
|
||||
{
|
||||
qwHash = ((tUINT64)i_pv7 << 56)
|
||||
| ((tUINT64)i_pv6 << 48)
|
||||
| ((tUINT64)i_pv5 << 40)
|
||||
| ((tUINT64)i_pv4 << 32)
|
||||
| ((tUINT64)i_pv3 << 24)
|
||||
| ((tUINT64)i_pv2 << 16)
|
||||
| ((tUINT64)i_pv1 << 8)
|
||||
| (tUINT64)i_pv0;
|
||||
}
|
||||
|
||||
stKeyMap(tUINT16 i_wKey,
|
||||
tUINT8 i_pv4,
|
||||
tUINT8 i_pv3,
|
||||
tUINT8 i_pv2,
|
||||
tUINT8 i_pv1,
|
||||
tUINT8 i_pv0
|
||||
)
|
||||
: wKey(i_wKey), qwHash(0)
|
||||
{
|
||||
qwHash = ((tUINT64)i_pv4 << 32)
|
||||
| ((tUINT64)i_pv3 << 24)
|
||||
| ((tUINT64)i_pv2 << 16)
|
||||
| ((tUINT64)i_pv1 << 8)
|
||||
| (tUINT64)i_pv0;
|
||||
}
|
||||
|
||||
stKeyMap(tUINT16 i_wKey,
|
||||
tUINT8 i_pv3,
|
||||
tUINT8 i_pv2,
|
||||
tUINT8 i_pv1,
|
||||
tUINT8 i_pv0
|
||||
)
|
||||
: wKey(i_wKey), qwHash(0)
|
||||
{
|
||||
qwHash = ((tUINT64)i_pv3 << 24)
|
||||
| ((tUINT64)i_pv2 << 16)
|
||||
| ((tUINT64)i_pv1 << 8)
|
||||
| (tUINT64)i_pv0;
|
||||
}
|
||||
|
||||
stKeyMap(tUINT16 i_wKey,
|
||||
tUINT8 i_pv2,
|
||||
tUINT8 i_pv1,
|
||||
tUINT8 i_pv0
|
||||
)
|
||||
: wKey(i_wKey), qwHash(0)
|
||||
{
|
||||
qwHash = ((tUINT64)i_pv2 << 16)
|
||||
| ((tUINT64)i_pv1 << 8)
|
||||
| (tUINT64)i_pv0;
|
||||
}
|
||||
|
||||
stKeyMap(tUINT16 i_wKey,
|
||||
tUINT8 i_pv1,
|
||||
tUINT8 i_pv0
|
||||
)
|
||||
: wKey(i_wKey), qwHash(0)
|
||||
{
|
||||
qwHash = ((tUINT64)i_pv1 << 8)
|
||||
| (tUINT64)i_pv0;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CKeysTree
|
||||
class CKeysList
|
||||
: public CListPool<char>
|
||||
{
|
||||
protected:
|
||||
virtual tBOOL Data_Release(char i_pData)
|
||||
{
|
||||
UNUSED_ARG(i_pData);
|
||||
return TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CKeysTree
|
||||
class CKeysTree:
|
||||
public CRBTree<stKeyMap*, tUINT64>
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//~CKeysTree
|
||||
virtual ~CKeysTree()
|
||||
{
|
||||
Clear();
|
||||
}//~CRBTree
|
||||
|
||||
protected:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
virtual tBOOL Data_Release(stKeyMap* i_pData)
|
||||
{
|
||||
delete i_pData;
|
||||
return TRUE; //memory used from pool, not necessary to return
|
||||
}// Data_Release
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Return
|
||||
//TRUE - if (i_pKey < i_pData::key)
|
||||
//FALSE - otherwise
|
||||
tBOOL Is_Key_Less(tUINT64 i_pKey, stKeyMap *i_pData)
|
||||
{
|
||||
return (i_pKey < i_pData->qwHash);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Return
|
||||
//TRUE - if (i_pKey == i_pData::key)
|
||||
//FALSE - otherwise
|
||||
tBOOL Is_Qual(tUINT64 i_pKey, stKeyMap *i_pData)
|
||||
{
|
||||
return (i_pKey == i_pData->qwHash);
|
||||
}
|
||||
};//CDesc_Tree
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
class CConsole
|
||||
: public IConsole
|
||||
{
|
||||
tUINT32 m_pCl[IConsole::eColorsMax];
|
||||
size_t m_szText;
|
||||
tXCHAR *m_pText;
|
||||
tXCHAR *m_pEmpty;
|
||||
size_t m_szEmpty;
|
||||
CKeysTree m_pKeys;
|
||||
CKeysList m_cKeysList;
|
||||
public:
|
||||
CConsole()
|
||||
{
|
||||
m_szText = 32768;
|
||||
m_pText = (tXCHAR*)malloc(m_szText * sizeof(tXCHAR));
|
||||
|
||||
m_szEmpty = 0;
|
||||
m_pEmpty = NULL;
|
||||
AllocEmptyString(1024);
|
||||
|
||||
Set_EchoOff(TRUE);
|
||||
|
||||
//https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
m_pCl[IConsole::eBlack] = 0;
|
||||
m_pCl[IConsole::eBlue] = 12;
|
||||
m_pCl[IConsole::eGreen] = 40;
|
||||
m_pCl[IConsole::eCyan] = 51;
|
||||
m_pCl[IConsole::eRed] = 124;
|
||||
m_pCl[IConsole::eMagenta] = 129;
|
||||
m_pCl[IConsole::eBrown] = 94;
|
||||
m_pCl[IConsole::eLightGray] = 252;
|
||||
m_pCl[IConsole::eDarkGray] = 244;
|
||||
m_pCl[IConsole::eLightBlue] = 33;
|
||||
m_pCl[IConsole::eLightGreen] = 48;
|
||||
m_pCl[IConsole::eLightCyan] = 195;
|
||||
m_pCl[IConsole::eLightRed] = 196;
|
||||
m_pCl[IConsole::eLightMagenta] = 201;
|
||||
m_pCl[IConsole::eYellow] = 11;
|
||||
m_pCl[IConsole::eWhite] = 15;
|
||||
|
||||
stKeyMap *l_pKey = new stKeyMap(eKeyArrowLeft, 27,91,68);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyArrowRight, 27,91,67);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyArrowDown, 27,91,66);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyArrowUp, 27,91,65);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyPageUp, 27,91,53,126);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyPageDown, 27,91,54,126);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyHome, 27,79,72);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyEnd, 27,79,70);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyDel, 27,91,51,126);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyInsert, 27,91,50,126);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyF1, 27,79,80);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyF2, 27,79,81);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyF3, 27,79,82);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyF4, 27,79,83);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyF5, 27,91,49,53,126);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyF6, 27,91,49,55,126);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyF7, 27,91,49,56,126);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyF8, 27,91,49,57,126);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyF9, 27,91,50,48,126);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyF10, 27,91,50,49,126);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyF11, 27,91,50,51,126);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
|
||||
l_pKey = new stKeyMap(eKeyF12, 27,91,50,52,126);
|
||||
m_pKeys.Push(l_pKey, l_pKey->qwHash);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual ~CConsole()
|
||||
{
|
||||
if (m_pText)
|
||||
{
|
||||
free(m_pText);
|
||||
m_pText = NULL;
|
||||
}
|
||||
|
||||
if (m_pEmpty)
|
||||
{
|
||||
free(m_pEmpty);
|
||||
m_pEmpty = NULL;
|
||||
}
|
||||
|
||||
m_pKeys.Clear();
|
||||
m_cKeysList.Clear(TRUE);
|
||||
Set_EchoOff(FALSE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL SetCursor(tUINT32 i_uX, tUINT32 i_uY)
|
||||
{
|
||||
printf("\033[%d;%dH", i_uY+1, i_uX+1);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tUINT32 GetCursorX()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL GetInput(IConsole::sInput &o_rInput)
|
||||
{
|
||||
while (Is_Key_Hit())
|
||||
{
|
||||
m_cKeysList.Add_After(m_cKeysList.Get_Last(), Get_Char());
|
||||
}
|
||||
|
||||
if (!m_cKeysList.Count())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char l_cVal = m_cKeysList.Get_Data(m_cKeysList.Get_First());
|
||||
tBOOL l_bReturn = FALSE;
|
||||
|
||||
o_rInput.eEvent = IConsole::eKey;
|
||||
o_rInput.stKey.bDown = TRUE;
|
||||
o_rInput.stKey.uControls = 0;
|
||||
o_rInput.stKey.wCount = 1;
|
||||
o_rInput.stKey.wKey = l_cVal;
|
||||
|
||||
if ( (27 == l_cVal) //escape sequence
|
||||
&& (m_cKeysList.Count())
|
||||
)
|
||||
{
|
||||
tUINT64 l_qwHash = 0;
|
||||
pAList_Cell l_pEl = m_cKeysList.Get_First();
|
||||
stKeyMap *l_pKey = NULL;
|
||||
tUINT32 l_uiCount = 0;
|
||||
|
||||
while ( (l_pEl)
|
||||
&& (8 > l_uiCount)
|
||||
)
|
||||
{
|
||||
l_uiCount++;
|
||||
|
||||
l_qwHash = (l_qwHash << 8) | m_cKeysList.Get_Data(l_pEl);
|
||||
l_pKey = m_pKeys.Find(l_qwHash);
|
||||
if (l_pKey)
|
||||
{
|
||||
o_rInput.stKey.wKey = l_pKey->wKey;
|
||||
l_bReturn = TRUE;
|
||||
|
||||
while (l_pEl) //clear esc sequence used to identefy key
|
||||
{
|
||||
pAList_Cell l_pPrevEl = m_cKeysList.Get_Prev(l_pEl);
|
||||
m_cKeysList.Del(l_pEl, TRUE);
|
||||
l_pEl = l_pPrevEl;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_pEl = m_cKeysList.Get_Next(l_pEl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!l_bReturn) //if it is not esc sequence - get first char and return it
|
||||
{
|
||||
if (10 == l_cVal)
|
||||
{
|
||||
o_rInput.stKey.wKey = (tUINT16)IConsole::eKeyEnter;
|
||||
}
|
||||
else if (9 == l_cVal)
|
||||
{
|
||||
o_rInput.stKey.wKey = (tUINT16)IConsole::eKeyTab;
|
||||
}
|
||||
else if (8 == l_cVal)
|
||||
{
|
||||
o_rInput.stKey.wKey = (tUINT16)IConsole::eKeyBackSpace;
|
||||
}
|
||||
|
||||
l_bReturn = TRUE;
|
||||
m_cKeysList.Del(m_cKeysList.Get_First(), TRUE);
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tUINT32 GetCursorY()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tUINT32 GetWidth()
|
||||
{
|
||||
struct winsize w;
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||
return w.ws_col;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tUINT32 GetHeight()
|
||||
{
|
||||
struct winsize w;
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||
return w.ws_row;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL SetTextAttr(IConsole::eColor i_eFg, IConsole::eColor i_eBg)
|
||||
{
|
||||
if ( (i_eFg < 0)
|
||||
|| (i_eFg >= IConsole::eColorsMax)
|
||||
|| (i_eBg < 0)
|
||||
|| (i_eBg >= IConsole::eColorsMax)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
printf("\x1b[38;5;%dm\x1b[48;5;%dm", m_pCl[i_eFg], m_pCl[i_eBg]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Clear()
|
||||
{
|
||||
printf("\033[H\033[J");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Clear(tUINT32 i_uX, tUINT32 i_uY, tUINT32 i_uW, tUINT32 i_uH, IConsole::eColor i_eBg)
|
||||
{
|
||||
tUINT32 l_uiW = GetWidth();
|
||||
tUINT32 l_uiH = GetHeight();
|
||||
|
||||
if ( (i_uX > l_uiW)
|
||||
|| (i_uY > l_uiH)
|
||||
|| (!i_uW)
|
||||
|| (!i_uH)
|
||||
|| (i_uW >= m_szEmpty)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((i_uX + i_uW) > l_uiW)
|
||||
{
|
||||
i_uW = l_uiW - i_uX;
|
||||
}
|
||||
|
||||
if ((i_uY + i_uH) > l_uiH)
|
||||
{
|
||||
i_uH = l_uiH - i_uY;
|
||||
}
|
||||
|
||||
if (i_uW > m_szEmpty)
|
||||
{
|
||||
if (!AllocEmptyString((size_t)i_uW))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SetTextAttr(IConsole::eBlack, i_eBg))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SetCursor(i_uX, i_uY);
|
||||
|
||||
tUINT32 l_uiXOld = i_uX;
|
||||
tUINT32 l_uiYOld = i_uY;
|
||||
while (i_uH--)
|
||||
{
|
||||
SetCursor(i_uX, i_uY++);
|
||||
m_pEmpty[i_uW] = 0;
|
||||
WriteTextB(m_pEmpty, i_uW);
|
||||
m_pEmpty[i_uW] = ' ';
|
||||
}
|
||||
|
||||
SetCursor(l_uiXOld, l_uiYOld);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
size_t WriteTextB(const tXCHAR *i_pText, size_t i_szText)
|
||||
{
|
||||
UNUSED_ARG(i_szText);
|
||||
return (size_t)printf("%s", i_pText);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
size_t WriteTextB(IConsole::eColor i_eFg,
|
||||
IConsole::eColor i_eBg,
|
||||
size_t i_szLenMin,
|
||||
size_t i_szLenMax,
|
||||
size_t i_szOffset,
|
||||
tXCHAR *i_pText,
|
||||
size_t i_szText,
|
||||
size_t i_szTextMax
|
||||
)
|
||||
{
|
||||
if ( (i_szLenMin > i_szLenMax)
|
||||
|| (!i_pText)
|
||||
|| (8 >= i_szTextMax)
|
||||
|| (i_szText >= i_szTextMax)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!SetTextAttr(i_eFg, i_eBg))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
tXCHAR *l_pText = i_pText;
|
||||
|
||||
if (!i_szText)
|
||||
{
|
||||
i_szText = PStrLen(i_pText);
|
||||
}
|
||||
|
||||
//if there is offset, recalculate all inputs
|
||||
if (i_szOffset)
|
||||
{
|
||||
if (i_szOffset < i_szText) //set sext offset and recalculate all
|
||||
{
|
||||
l_pText = l_pText + i_szOffset;
|
||||
i_szText -= i_szOffset;
|
||||
i_szTextMax -= i_szOffset;
|
||||
i_szOffset = 0;
|
||||
*l_pText = TM('<');
|
||||
}
|
||||
else //if (i_szOffset >= i_szText)
|
||||
{
|
||||
l_pText = m_pText;
|
||||
*l_pText = TM('<');
|
||||
i_szText = 1;
|
||||
i_szTextMax= m_szText;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (i_szText > i_szLenMax)
|
||||
{
|
||||
i_szText = i_szLenMax;
|
||||
l_pText[i_szText-1] = TM('>');
|
||||
}
|
||||
else if (i_szText < i_szLenMin)
|
||||
{
|
||||
if (i_szTextMax < (i_szLenMin + 1))
|
||||
{
|
||||
PStrNCpy(m_pText, m_szText, l_pText, i_szText);
|
||||
l_pText = m_pText;
|
||||
i_szTextMax = m_szText;
|
||||
}
|
||||
|
||||
tXCHAR *l_pIter = l_pText + i_szText;
|
||||
|
||||
while (i_szText < i_szLenMin)
|
||||
{
|
||||
*l_pIter = TM(' ');
|
||||
l_pIter ++;
|
||||
i_szText++;
|
||||
}
|
||||
}
|
||||
|
||||
if (i_szText < i_szTextMax)
|
||||
{
|
||||
l_pText[i_szText] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_pText[i_szText-1] = 0;
|
||||
}
|
||||
|
||||
return (size_t)printf("%s", l_pText);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
size_t WriteTextF(IConsole::eColor i_eFg,
|
||||
IConsole::eColor i_eBg,
|
||||
size_t i_szLenMin,
|
||||
size_t i_szLenMax,
|
||||
size_t i_szOffset,
|
||||
const tXCHAR *i_pFormat,
|
||||
va_list i_pVA
|
||||
)
|
||||
{
|
||||
int l_iReturn = PVsnprintf(m_pText, m_szText, i_pFormat, i_pVA);
|
||||
|
||||
if (0 > l_iReturn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return WriteTextB(i_eFg, i_eBg, i_szLenMin, i_szLenMax, i_szOffset, m_pText, (size_t)l_iReturn, m_szText);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Present()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
protected:
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL AllocEmptyString(size_t i_szEmpty)
|
||||
{
|
||||
if (m_pEmpty)
|
||||
{
|
||||
free(m_pEmpty);
|
||||
}
|
||||
|
||||
if (i_szEmpty > 4096)
|
||||
{
|
||||
i_szEmpty = 4096;
|
||||
}
|
||||
|
||||
m_szEmpty = i_szEmpty;
|
||||
m_pEmpty = (tXCHAR*)malloc(m_szEmpty * sizeof(tXCHAR));
|
||||
|
||||
if (!m_pEmpty)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tXCHAR *l_pEmpty = m_pEmpty;
|
||||
size_t l_szIterator = m_szEmpty;
|
||||
|
||||
while (l_szIterator--)
|
||||
{
|
||||
*l_pEmpty = TM(' ');
|
||||
l_pEmpty++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //PCONSOLE_H
|
||||
229
p7lib/Shared/Platforms/Linux_x86/PCrashDump.h
Normal file
229
p7lib/Shared/Platforms/Linux_x86/PCrashDump.h
Normal file
@ -0,0 +1,229 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//http://www.codeproject.com/Articles/207464/Exception-Handling-in-Visual-Cplusplus
|
||||
|
||||
#ifndef PCRASH_DUMP_H
|
||||
#define PCRASH_DUMP_H
|
||||
|
||||
#include "GTypes.h"
|
||||
#include "Length.h"
|
||||
#include "PString.h"
|
||||
#include "WString.h"
|
||||
#include "AList.h"
|
||||
#include "PAtomic.h"
|
||||
#include "ISignal.h"
|
||||
|
||||
#define CH_DESC_FILE_EXT TM("dsc")
|
||||
|
||||
struct sCdContext
|
||||
{
|
||||
char *pBuffer;
|
||||
size_t szBuffer;
|
||||
size_t szPathMax;
|
||||
char *pDescFileName;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CdCreateDumpTxt
|
||||
static __attribute__ ((unused)) void CdCreateDumpTxt(sCdContext *i_pCdContext, const char *i_pText, tUINT64 i_qwCode)
|
||||
{
|
||||
UNUSED_ARG(i_pCdContext);
|
||||
UNUSED_ARG(i_pText);
|
||||
UNUSED_ARG(i_qwCode);
|
||||
}//CdCreateDumpTxt
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CdWrite
|
||||
static __attribute__ ((unused)) void CdWrite(void *i_pCdInfo, eCrashCode i_eCode, const void *i_pContext)
|
||||
{
|
||||
UNUSED_ARG(i_pCdInfo);
|
||||
UNUSED_ARG(i_eCode);
|
||||
UNUSED_ARG(i_pContext);
|
||||
|
||||
//sCdContext *l_pCrush = (sCdContext*)i_pCdInfo;
|
||||
//
|
||||
//if ( IBreakdownNotify::eException == i_eCode )
|
||||
//{
|
||||
// if (i_pContext)
|
||||
// {
|
||||
// _EXCEPTION_POINTERS l_sException = *(_EXCEPTION_POINTERS*)(i_pContext);
|
||||
//
|
||||
// char l_pText[128];
|
||||
// sprintf_s(l_pText,
|
||||
// _countof(l_pText),
|
||||
// "Exception 0x%08X",
|
||||
// l_sException.ExceptionRecord->ExceptionCode
|
||||
// );
|
||||
//
|
||||
// tUINT64 l_qwCode = CdCreateDumpBin(&l_sException);
|
||||
// CdCreateDumpTxt(l_pCrush, l_pText, l_qwCode);
|
||||
//
|
||||
// }
|
||||
//}
|
||||
//else if (IBreakdownNotify::ePureCall == i_eCode)
|
||||
//{
|
||||
// CdCreateDumpTxt(l_pCrush, (const char*)i_pContext, i_eCode);
|
||||
//}
|
||||
//else if (IBreakdownNotify::eMemAlloc == i_eCode)
|
||||
//{
|
||||
// CdCreateDumpTxt(l_pCrush, (const char*)i_pContext, i_eCode);
|
||||
//}
|
||||
//else if (IBreakdownNotify::eInvalidParameter == i_eCode)
|
||||
//{
|
||||
// CdCreateDumpTxt(l_pCrush, (const char*)i_pContext, i_eCode);
|
||||
//}
|
||||
//else if ( IBreakdownNotify::eSignal >= i_eCode)
|
||||
//{
|
||||
// CdCreateDumpTxt(l_pCrush, (const char*)i_pContext, i_eCode);
|
||||
//}
|
||||
}//CdWrite
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CdCleanUp
|
||||
static __attribute__ ((unused)) void CdCleanUp(const tXCHAR *i_pDir, unsigned int i_dwMax_Count)
|
||||
{
|
||||
CBList<CWString*> l_cFiles;
|
||||
CWString l_cDir;
|
||||
|
||||
l_cDir.Set(i_pDir);
|
||||
CFSYS::Enumerate_Files(&l_cFiles, &l_cDir, TM("*.") CH_DESC_FILE_EXT, 0);
|
||||
|
||||
//sort files - first is oldest, last is newest !
|
||||
pAList_Cell l_pStart = NULL;
|
||||
tUINT32 l_dwDirLen = l_cDir.Length();
|
||||
|
||||
while ((l_pStart = l_cFiles.Get_Next(l_pStart)))
|
||||
{
|
||||
pAList_Cell l_pMin = l_pStart;
|
||||
pAList_Cell l_pIter = l_pStart;
|
||||
|
||||
while ((l_pIter = l_cFiles.Get_Next(l_pIter)))
|
||||
{
|
||||
CWString *l_pPathM = l_cFiles.Get_Data(l_pMin);
|
||||
CWString *l_pPathI = l_cFiles.Get_Data(l_pIter);
|
||||
tXCHAR *l_pNameM = l_pPathM->Get() + l_dwDirLen;
|
||||
tXCHAR *l_pNameI = l_pPathI->Get() + l_dwDirLen;
|
||||
|
||||
if (0 < PStrICmp(l_pNameM, l_pNameI))
|
||||
{
|
||||
l_pMin = l_pIter;
|
||||
}
|
||||
}
|
||||
|
||||
if (l_pMin != l_pStart)
|
||||
{
|
||||
l_cFiles.Extract(l_pMin);
|
||||
l_cFiles.Put_After(l_cFiles.Get_Prev(l_pStart), l_pMin);
|
||||
l_pStart = l_pMin;
|
||||
}
|
||||
} //while (l_pStart = m_cFiles.Get_Next(l_pStart))
|
||||
|
||||
//delete oldest files
|
||||
while (l_cFiles.Count() > i_dwMax_Count)
|
||||
{
|
||||
l_pStart = l_cFiles.Get_First();
|
||||
if (l_pStart)
|
||||
{
|
||||
CWString *l_pPath = l_cFiles.Get_Data(l_pStart);
|
||||
|
||||
//delete description file
|
||||
CFSYS::Delete_File(l_pPath->Get());
|
||||
|
||||
l_cFiles.Del(l_pStart, TRUE);
|
||||
}
|
||||
}//while (l_cFiles.Count() > i_dwMax_Count)
|
||||
}//CdCleanUp
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CdAlloc
|
||||
static __attribute__ ((unused)) void *CdAlloc(const tXCHAR *i_pFolder)
|
||||
{
|
||||
sCdContext *l_pCrush = (sCdContext*)malloc(sizeof(sCdContext));
|
||||
tBOOL l_bError = FALSE;
|
||||
|
||||
if ( !l_pCrush )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//initialize parameters
|
||||
memset(l_pCrush, 0, sizeof(sCdContext));
|
||||
|
||||
l_pCrush->szBuffer = 32768;
|
||||
l_pCrush->pBuffer = (char*)malloc(l_pCrush->szBuffer * sizeof(char));
|
||||
l_pCrush->szPathMax = 16384;
|
||||
l_pCrush->pDescFileName = (tXCHAR*)malloc(l_pCrush->szPathMax * sizeof(tXCHAR));
|
||||
|
||||
if ( (NULL == l_pCrush->pBuffer)
|
||||
|| (NULL == l_pCrush->pDescFileName)
|
||||
)
|
||||
{
|
||||
l_bError = TRUE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
CdCleanUp(i_pFolder, 5);
|
||||
|
||||
|
||||
l_lblExit:
|
||||
if ( (l_bError)
|
||||
&& (l_pCrush)
|
||||
)
|
||||
{
|
||||
free(l_pCrush);
|
||||
l_pCrush = NULL;
|
||||
}
|
||||
|
||||
|
||||
return l_pCrush;
|
||||
}//CH_Install
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CdFree
|
||||
static __attribute__ ((unused)) void CdFree(void *i_pCdInfo)
|
||||
{
|
||||
sCdContext *l_pCrush = (sCdContext*)i_pCdInfo;
|
||||
|
||||
if ( !l_pCrush )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (l_pCrush->pBuffer)
|
||||
{
|
||||
free(l_pCrush->pBuffer);
|
||||
l_pCrush->pBuffer = NULL;
|
||||
}
|
||||
|
||||
if (l_pCrush->pDescFileName)
|
||||
{
|
||||
free(l_pCrush->pDescFileName);
|
||||
l_pCrush->pDescFileName = NULL;
|
||||
}
|
||||
}//CdFree
|
||||
|
||||
#endif //PCRASH_DUMP_H
|
||||
89
p7lib/Shared/Platforms/Linux_x86/PDnsTxtResolver.h
Normal file
89
p7lib/Shared/Platforms/Linux_x86/PDnsTxtResolver.h
Normal file
@ -0,0 +1,89 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <netinet/in.h>
|
||||
//#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "GTypes.h"
|
||||
#include "AList.h"
|
||||
|
||||
class CDnsTxt: public CAList<tACHAR*>
|
||||
{
|
||||
protected:
|
||||
virtual tBOOL Data_Release(tACHAR *i_pStr)
|
||||
{
|
||||
if (NULL == i_pStr)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
free(i_pStr);
|
||||
return TRUE;
|
||||
}//CListBase::Data_Release
|
||||
};
|
||||
|
||||
|
||||
tBOOL static inline GetDnsTxtRecords(const tACHAR *i_pDomain, CDnsTxt &io_rList)
|
||||
{
|
||||
const size_t l_szTxtBuf = 2048;
|
||||
u_char l_pTxtBuf[l_szTxtBuf];
|
||||
int l_iResult = -1;
|
||||
int l_iLen = 0;
|
||||
ns_msg l_stMsg = {0};
|
||||
ns_rr l_stRr = {0};
|
||||
tUINT16 l_sMsgCount= 0;
|
||||
|
||||
l_iLen = res_query(i_pDomain, ns_c_in, ns_t_txt, l_pTxtBuf, (int)l_szTxtBuf);
|
||||
if (l_iLen < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
l_iResult = ns_initparse(l_pTxtBuf, l_iLen, &l_stMsg);
|
||||
if (l_iResult < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
l_sMsgCount = ns_msg_count(l_stMsg, ns_s_an);
|
||||
for (tUINT16 i = 0; i < l_sMsgCount; i++)
|
||||
{
|
||||
if ( (0 == ns_parserr(&l_stMsg, ns_s_an, i, &l_stRr))
|
||||
&& (l_stRr.rdlength)
|
||||
)
|
||||
{
|
||||
tACHAR *l_pText = (tACHAR*)malloc(l_stRr.rdlength-1);
|
||||
if (l_pText)
|
||||
{
|
||||
//TXT record RDATA format is:
|
||||
// length, 1 byte
|
||||
// string, <length bytes>
|
||||
// length2, 1 byte
|
||||
// string2, <length2 bytes>
|
||||
// etc.
|
||||
memcpy(l_pText, (tACHAR *)l_stRr.rdata + 1, l_stRr.rdlength - 1);
|
||||
l_pText[l_stRr.rdlength - 1] = 0;
|
||||
io_rList.Push_Last(l_pText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (io_rList.Count() != 0);
|
||||
}
|
||||
291
p7lib/Shared/Platforms/Linux_x86/PFile.h
Normal file
291
p7lib/Shared/Platforms/Linux_x86/PFile.h
Normal file
@ -0,0 +1,291 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PFILE_H
|
||||
#define PFILE_H
|
||||
|
||||
#define PFILE_INVALID_HANDLE (-1)
|
||||
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
//Headers have to be included in application source files
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define GetLastError() errno
|
||||
|
||||
//UTF-8 text file header - {0xEF, 0xBB, 0xBF}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class CPFile
|
||||
: public IFile //virtual
|
||||
{
|
||||
volatile tINT32 m_iRCnt;
|
||||
//tLOCK m_hCS;
|
||||
int m_iFile;
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
CPFile()
|
||||
: m_iRCnt(1)
|
||||
, m_iFile(-1)
|
||||
{
|
||||
//LOCK_CREATE(m_hCS);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
virtual ~CPFile()
|
||||
{
|
||||
//LOCK_DESTROY(m_hCS);
|
||||
Close(FALSE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL IsOpened()
|
||||
{
|
||||
return (PFILE_INVALID_HANDLE != m_iFile);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Open(const tXCHAR *i_pName, tUINT32 i_dwFlags)
|
||||
{
|
||||
//create file if it is not exists, else - open, heh ... engineers
|
||||
//friendly POSIX API :-(
|
||||
int l_iFlags = O_CREAT;
|
||||
mode_t l_tMode = 0;
|
||||
|
||||
if (PFILE_INVALID_HANDLE != m_iFile)
|
||||
{
|
||||
Close(TRUE);
|
||||
}
|
||||
|
||||
l_iFlags |= O_RDWR;
|
||||
|
||||
if (ECREATE & i_dwFlags)
|
||||
{
|
||||
l_iFlags |= O_TRUNC;
|
||||
|
||||
if (EACCESS_WRITE & i_dwFlags)
|
||||
{
|
||||
l_tMode = S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH;
|
||||
}
|
||||
else if (EACCESS_READ & i_dwFlags)
|
||||
{
|
||||
l_tMode = S_IRUSR | S_IRGRP | S_IROTH;
|
||||
}
|
||||
}
|
||||
|
||||
m_iFile = open(i_pName, l_iFlags, l_tMode);
|
||||
|
||||
return (PFILE_INVALID_HANDLE != m_iFile) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Close(tBOOL i_bFlush)
|
||||
{
|
||||
tBOOL l_bReturn = TRUE;
|
||||
int l_iTemp = PFILE_INVALID_HANDLE;
|
||||
|
||||
if (PFILE_INVALID_HANDLE == m_iFile)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (i_bFlush)
|
||||
{
|
||||
if (-1 == fsync(m_iFile))
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lExit;
|
||||
}
|
||||
}
|
||||
|
||||
l_iTemp = m_iFile;
|
||||
m_iFile = PFILE_INVALID_HANDLE;
|
||||
|
||||
if (-1 == close(l_iTemp))
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lExit;
|
||||
}
|
||||
|
||||
l_lExit:
|
||||
return l_bReturn;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Set_Position(tUINT64 i_qwOffset)
|
||||
{
|
||||
if (PFILE_INVALID_HANDLE == m_iFile)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
if ((off64_t)i_qwOffset != lseek64(m_iFile, (off64_t)i_qwOffset, SEEK_SET))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tUINT64 Get_Position()
|
||||
{
|
||||
if (PFILE_INVALID_HANDLE == m_iFile)
|
||||
{
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
return (off64_t)lseek64(m_iFile, 0LL, SEEK_CUR);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tUINT64 Get_Size()
|
||||
{
|
||||
if (PFILE_INVALID_HANDLE == m_iFile)
|
||||
{
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
off64_t l_llPos = lseek64(m_iFile, 0LL, SEEK_CUR);
|
||||
off64_t l_llSize = lseek64(m_iFile, 0LL, SEEK_END);
|
||||
lseek64(m_iFile, l_llPos, SEEK_SET);
|
||||
return l_llSize;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
size_t Write(const tUINT8 *i_pBuffer, size_t i_szBuffer, tBOOL i_bFlush)
|
||||
{
|
||||
if ( (PFILE_INVALID_HANDLE == m_iFile)
|
||||
|| (NULL == i_pBuffer)
|
||||
|| (0 == i_szBuffer)
|
||||
)
|
||||
{
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
ssize_t l_szRes = 0;
|
||||
size_t l_szWritten = 0;
|
||||
int l_iError = 0;
|
||||
|
||||
while (l_szWritten < i_szBuffer)
|
||||
{
|
||||
l_szRes = write(m_iFile, i_pBuffer + l_szWritten, i_szBuffer - l_szWritten);
|
||||
if (0 < l_szRes)
|
||||
{
|
||||
l_szWritten += (size_t)l_szRes;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_iError = errno;
|
||||
printf("%d", l_iError);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( (i_bFlush)
|
||||
&& (l_szWritten)
|
||||
)
|
||||
{
|
||||
fsync(m_iFile);
|
||||
}
|
||||
|
||||
return l_szWritten;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
size_t Read(tUINT8 *o_pBuffer, size_t i_szBuffer)
|
||||
{
|
||||
if ( (PFILE_INVALID_HANDLE == m_iFile)
|
||||
|| (NULL == o_pBuffer)
|
||||
|| (0 == i_szBuffer)
|
||||
)
|
||||
{
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
size_t l_szRead = 0;
|
||||
ssize_t l_szRes = 0;
|
||||
|
||||
while (l_szRead < i_szBuffer)
|
||||
{
|
||||
l_szRes = read(m_iFile, o_pBuffer + l_szRead, i_szBuffer - l_szRead);
|
||||
if (0 < l_szRes)
|
||||
{
|
||||
l_szRead += (size_t)l_szRes;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return l_szRead;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tINT32 Add_Ref()
|
||||
{
|
||||
return ATOMIC_INC(&m_iRCnt);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tINT32 Release()
|
||||
{
|
||||
volatile tINT32 l_iReturn = ATOMIC_DEC(&m_iRCnt);
|
||||
|
||||
if (0 >= l_iReturn)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
return l_iReturn;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //PFILE_H
|
||||
|
||||
|
||||
|
||||
/*
|
||||
CPFile l_cFile;
|
||||
const tUINT8 l_pHeader[] = {0xEF, 0xBB, 0xBF};
|
||||
const char l_pText[] = "Some Text For me !\xD\xA Another Text\xD\xA Third Text";
|
||||
tUINT64 l_qwCount = 0;
|
||||
tUINT8 l_pBuffer[256] = {0};
|
||||
|
||||
l_cFile.Open("./ABC.txt", IFile::ECREATE | IFile::ESHARE_WRITE);
|
||||
|
||||
l_qwCount = l_cFile.Write(l_pHeader, LENGTH(l_pHeader), FALSE);
|
||||
l_qwCount = l_cFile.Write((tUINT8*)l_pText, LENGTH(l_pText) - 1, TRUE);
|
||||
|
||||
l_qwCount = l_cFile.Get_Size();
|
||||
|
||||
l_cFile.Set_Position(0);
|
||||
|
||||
l_qwCount = l_cFile.Read(l_pBuffer, LENGTH(l_pBuffer));
|
||||
|
||||
l_cFile.Close(TRUE);
|
||||
*/
|
||||
362
p7lib/Shared/Platforms/Linux_x86/PFileSystem.h
Normal file
362
p7lib/Shared/Platforms/Linux_x86/PFileSystem.h
Normal file
@ -0,0 +1,362 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PFILESYSTEM_H
|
||||
#define PFILESYSTEM_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <fnmatch.h>
|
||||
#include <pwd.h>
|
||||
|
||||
class CFSYS
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Directory_Exists
|
||||
static tBOOL Directory_Exists(const tACHAR *i_pPath)
|
||||
{
|
||||
struct stat l_sStat;
|
||||
l_sStat.st_mode = 0;
|
||||
if (0 == stat(i_pPath, &l_sStat))
|
||||
{
|
||||
if (0 != (l_sStat.st_mode & S_IFDIR))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}//Directory_Exists
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Directory_Create
|
||||
static tBOOL Directory_Create(const tACHAR *i_pDir)
|
||||
{
|
||||
if (NULL == i_pDir)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char *l_pDir = (char *)malloc(strlen(i_pDir) + 1);
|
||||
char *l_pIter = l_pDir;
|
||||
|
||||
if (NULL == l_pDir)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
strcpy(l_pDir, i_pDir);
|
||||
while (*l_pIter)
|
||||
{
|
||||
if ('/' == (*l_pIter))
|
||||
{
|
||||
*l_pIter = 0;
|
||||
|
||||
if ( (FALSE == CFSYS::Directory_Exists(l_pDir))
|
||||
&& (l_pIter != l_pDir)
|
||||
)
|
||||
{
|
||||
mkdir(l_pDir, S_IRWXU | S_IRWXG | S_IROTH);
|
||||
}
|
||||
|
||||
*l_pIter = '/';
|
||||
}
|
||||
|
||||
l_pIter++;
|
||||
}
|
||||
|
||||
free(l_pDir);
|
||||
l_pDir = NULL;
|
||||
|
||||
mkdir(i_pDir, S_IRWXU | S_IRWXG | S_IROTH);
|
||||
|
||||
return Directory_Exists((tACHAR*)i_pDir);
|
||||
}//Directory_Create
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Directory_Delete
|
||||
static tBOOL Directory_Delete(const tACHAR *i_pDir)
|
||||
{
|
||||
if (NULL == i_pDir)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return (0 == rmdir(i_pDir));
|
||||
}//Directory_Delete
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//File_Exists
|
||||
static tBOOL File_Exists(const tACHAR * i_pFileName)
|
||||
{
|
||||
struct stat l_sStat;
|
||||
l_sStat.st_mode = 0;
|
||||
if (0 == stat(i_pFileName, &l_sStat))
|
||||
{
|
||||
if (0 != (l_sStat.st_mode & S_IFREG))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}//File_Exists
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Enumerate_Files
|
||||
static void Enumerate_Files(CBList<CWString*> *i_pDll_List,
|
||||
CWString *i_pDirectory,
|
||||
const char *i_pMask, //for example L"*.so"
|
||||
tUINT32 i_dwDepth = 0xFFFFFFul
|
||||
)
|
||||
{
|
||||
tUINT32 l_dwLength = i_pDirectory->Length();
|
||||
|
||||
if ( (NULL == i_pDll_List)
|
||||
|| (NULL == i_pDirectory)
|
||||
|| (NULL == i_pMask)
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DIR *l_pDir = opendir(i_pDirectory->Get());
|
||||
dirent *l_pDir_Entry = 0;
|
||||
|
||||
if (!l_pDir)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while ((l_pDir_Entry = readdir(l_pDir)) != 0)
|
||||
{
|
||||
if (DT_REG == l_pDir_Entry->d_type)
|
||||
{
|
||||
if (0 == fnmatch(i_pMask, l_pDir_Entry->d_name, FNM_NOESCAPE | FNM_CASEFOLD))
|
||||
{
|
||||
CWString *i_pFile = new CWString();
|
||||
if (i_pFile)
|
||||
{
|
||||
i_pFile->Set(i_pDirectory->Get());
|
||||
i_pFile->Append(2, L"/", l_pDir_Entry->d_name);
|
||||
i_pDll_List->Add_After(i_pDll_List->Get_Last(), i_pFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( (DT_DIR == l_pDir_Entry->d_type)
|
||||
&& (0 != PStrCmp(l_pDir_Entry->d_name, "."))
|
||||
&& (0 != PStrCmp(l_pDir_Entry->d_name, ".."))
|
||||
&& (i_dwDepth)
|
||||
)
|
||||
{
|
||||
i_pDirectory->Append(2, L"/", l_pDir_Entry->d_name);
|
||||
Enumerate_Files(i_pDll_List, i_pDirectory, i_pMask, i_dwDepth - 1);
|
||||
i_pDirectory->Trim(l_dwLength);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(l_pDir);
|
||||
l_pDir = 0;
|
||||
|
||||
}// Enumerate_Files
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Enumerate_Dirs
|
||||
static void Enumerate_Dirs(CBList<CWString*> *io_pList, const tXCHAR *i_pRoot)
|
||||
{
|
||||
if (NULL == io_pList)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!i_pRoot)
|
||||
{
|
||||
i_pRoot = "/";
|
||||
}
|
||||
|
||||
DIR *l_pDir = opendir(i_pRoot);
|
||||
dirent *l_pDir_Entry = 0;
|
||||
|
||||
if (!l_pDir)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while ((l_pDir_Entry = readdir(l_pDir)) != 0)
|
||||
{
|
||||
if ( (DT_DIR == l_pDir_Entry->d_type)
|
||||
&& (0 != PStrCmp(l_pDir_Entry->d_name, "."))
|
||||
&& (0 != PStrCmp(l_pDir_Entry->d_name, ".."))
|
||||
)
|
||||
{
|
||||
CWString *i_pFile = new CWString();
|
||||
if (i_pFile)
|
||||
{
|
||||
i_pFile->Set(i_pRoot);
|
||||
i_pFile->Append(2, "/", l_pDir_Entry->d_name);
|
||||
io_pList->Add_After(io_pList->Get_Last(), i_pFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir(l_pDir);
|
||||
l_pDir = 0;
|
||||
}// Enumerate_Dirs
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_File_Size
|
||||
static tUINT64 Get_File_Size(const tACHAR *i_pFile)
|
||||
{
|
||||
struct stat l_sStat;
|
||||
l_sStat.st_size = 0;
|
||||
if (0 == stat(i_pFile, &l_sStat))
|
||||
{
|
||||
return (tUINT64)l_sStat.st_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}//Get_File_Size
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Version
|
||||
static tUINT64 Get_Version(const char *i_pFile)
|
||||
{
|
||||
UNUSED_ARG(i_pFile);
|
||||
return 0ull;
|
||||
}//Get_Version
|
||||
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
// //Get_Process_Directory
|
||||
// static BOOL Get_Process_Directory(CWString *o_pDirectory)
|
||||
// {
|
||||
// BOOL l_bReturn = FALSE;
|
||||
// DWORD l_dwLength = 4096;
|
||||
|
||||
// if ( (NULL == o_pDirectory)
|
||||
// || (FALSE == o_pDirectory->Realloc(l_dwLength))
|
||||
// )
|
||||
// {
|
||||
// return l_bReturn;
|
||||
// }
|
||||
|
||||
// if (0 != GetModuleFileNameW(GetModuleHandleW(NULL),
|
||||
// o_pDirectory->Get(),
|
||||
// o_pDirectory->Max_Length())
|
||||
// )
|
||||
// {
|
||||
// wchar_t *l_pExe_Name = NULL;
|
||||
|
||||
// if ( (l_pExe_Name = wcsrchr(o_pDirectory->Get(), L'\\'))
|
||||
// || (l_pExe_Name = wcsrchr(o_pDirectory->Get(), L'/'))
|
||||
// )
|
||||
// {
|
||||
// o_pDirectory->Trim((DWORD)(l_pExe_Name - o_pDirectory->Get()));
|
||||
// l_bReturn = TRUE;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return l_bReturn;
|
||||
// }//Get_Process_Directory
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Delete_File
|
||||
static tBOOL Delete_File(const char *i_pFile_Name)
|
||||
{
|
||||
if (NULL == i_pFile_Name)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return (0 == remove(i_pFile_Name));
|
||||
}//Delete_File
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//GetUserDirectory
|
||||
static tBOOL GetUserDirectory(CWString *o_pPath)
|
||||
{
|
||||
if ( (NULL == o_pPath)
|
||||
|| (FALSE == o_pPath->Realloc(4096))
|
||||
)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct passwd *pw = getpwuid(getuid());
|
||||
|
||||
if (!pw)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
o_pPath->Set(pw->pw_dir);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//GetUserDirectory
|
||||
static tBOOL GetDirectoryParent(CWString &i_rChild, CWString &o_rParent)
|
||||
{
|
||||
o_rParent.Set(i_rChild.Get());
|
||||
size_t l_szDir = o_rParent.Length();
|
||||
tXCHAR *l_pDir = o_rParent.Get();
|
||||
|
||||
//cut trailing '/' or '\'
|
||||
while ( (l_szDir > 1)
|
||||
&& (TM('/') == l_pDir[l_szDir - 1])
|
||||
)
|
||||
{
|
||||
l_pDir[--l_szDir] = 0;
|
||||
}
|
||||
|
||||
tXCHAR *l_pTemp = strrchr(l_pDir, TM('/'));
|
||||
|
||||
if (!l_pTemp)
|
||||
{
|
||||
o_rParent.Set(TM(""));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
l_pTemp++;
|
||||
*l_pTemp = 0;
|
||||
l_pTemp--;
|
||||
|
||||
//removing duplicates of '/'
|
||||
while ( (TM('/') == *l_pTemp)
|
||||
&& (l_pTemp > l_pDir)
|
||||
)
|
||||
{
|
||||
*l_pTemp = 0;
|
||||
l_pTemp--;
|
||||
}
|
||||
|
||||
return (*l_pDir) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //PFILESYSTEM_H
|
||||
266
p7lib/Shared/Platforms/Linux_x86/PJournal.h
Normal file
266
p7lib/Shared/Platforms/Linux_x86/PJournal.h
Normal file
@ -0,0 +1,266 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PJOURNAL_H
|
||||
#define PJOURNAL_H
|
||||
|
||||
//#include <stdio.h>
|
||||
//#include <string.h>
|
||||
//#include <stdarg.h>
|
||||
//#include <iostream>
|
||||
//#include <pthread.h> //-pthread
|
||||
//#include <time.h>
|
||||
//#include "Atomic.hpp"
|
||||
//#include "Lock.hpp"
|
||||
//#include "PTypes.hpp"
|
||||
//#include "GTypes.hpp"
|
||||
//#include "IJournal.hpp"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class CJournal
|
||||
: public IJournal //virtual
|
||||
{
|
||||
volatile tINT32 m_iRCnt;
|
||||
tLOCK m_hCS;
|
||||
tUINT64 m_pCount[IJournal::eLEVEL_COUNT];
|
||||
IJournal::eLevel m_eVerbosity;
|
||||
tUINT32 m_pLength;
|
||||
tXCHAR *m_pBuffer;
|
||||
tXCHAR m_pName[IJournal::eLEVEL_COUNT][16];
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
CJournal()
|
||||
: m_iRCnt(1)
|
||||
, m_eVerbosity(IJournal::eLEVEL_WARNING)
|
||||
, m_pLength(8192)
|
||||
{
|
||||
LOCK_CREATE(m_hCS);
|
||||
|
||||
for (tUINT32 l_dwI = 0; l_dwI < IJournal::eLEVEL_COUNT; l_dwI++)
|
||||
{
|
||||
m_pName[l_dwI][0] = 0;
|
||||
m_pCount[l_dwI] = 0ULL;
|
||||
}
|
||||
|
||||
strcpy(m_pName[IJournal::eLEVEL_TRACE], "TRACE: ");
|
||||
strcpy(m_pName[IJournal::eLEVEL_DEBUG], "DEBUG: ");
|
||||
strcpy(m_pName[IJournal::eLEVEL_INFO], "INFO : ");
|
||||
strcpy(m_pName[IJournal::eLEVEL_WARNING], "WARN.: ");
|
||||
strcpy(m_pName[IJournal::eLEVEL_ERROR], "ERROR: ");
|
||||
strcpy(m_pName[IJournal::eLEVEL_CRITICAL], "CRIT.: ");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
virtual ~CJournal()
|
||||
{
|
||||
if (m_pBuffer)
|
||||
{
|
||||
delete [] m_pBuffer;
|
||||
m_pBuffer = NULL;
|
||||
}
|
||||
|
||||
//if (m_iRCnt)
|
||||
//{
|
||||
// printf("Error: CJournal reference counter is not 0");
|
||||
//}
|
||||
LOCK_DESTROY(m_hCS);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Initialize(const tXCHAR *i_pName)
|
||||
{
|
||||
UNUSED_ARG(i_pName);
|
||||
|
||||
if (m_pBuffer)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
m_pBuffer = new tXCHAR[m_pLength];
|
||||
|
||||
return m_pBuffer ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
void Set_Verbosity(IJournal::eLevel i_eVerbosity)
|
||||
{
|
||||
LOCK_ENTER(m_hCS);
|
||||
m_eVerbosity = i_eVerbosity;
|
||||
LOCK_EXIT(m_hCS);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
IJournal::eLevel Get_Verbosity()
|
||||
{
|
||||
IJournal::eLevel l_eReturn;
|
||||
|
||||
LOCK_ENTER(m_hCS);
|
||||
l_eReturn = m_eVerbosity;
|
||||
LOCK_EXIT(m_hCS);
|
||||
|
||||
return l_eReturn;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Log(IJournal::eLevel i_eType,
|
||||
IJournal::hModule i_hModule,
|
||||
const char *i_pFile,
|
||||
const char *i_pFunction,
|
||||
tUINT32 i_dwLine,
|
||||
const tXCHAR *i_pFormat,
|
||||
...
|
||||
)
|
||||
{
|
||||
UNUSED_ARG(i_hModule);
|
||||
UNUSED_ARG(i_pFile);
|
||||
tBOOL l_bReturn = TRUE;
|
||||
time_t l_tNow = time(NULL);
|
||||
struct tm *l_pTime = localtime(&l_tNow);
|
||||
struct timespec l_sTime = {0, 0};
|
||||
int l_iRes = 0;
|
||||
int l_iOffs = 0;
|
||||
tUINT64 l_qwMSec = 0;
|
||||
|
||||
LOCK_ENTER(m_hCS);
|
||||
|
||||
if ( (i_eType < m_eVerbosity)
|
||||
|| (NULL == m_pBuffer)
|
||||
|| (i_eType >= IJournal::eLEVEL_COUNT)
|
||||
)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lExit;
|
||||
}
|
||||
|
||||
m_pCount[i_eType] ++;
|
||||
|
||||
l_iRes = snprintf(m_pBuffer + l_iOffs,
|
||||
m_pLength - l_iOffs,
|
||||
"[%s] : [%d]\n",
|
||||
i_pFunction,
|
||||
(int)i_dwLine
|
||||
);
|
||||
if (0 <= l_iRes)
|
||||
{
|
||||
l_iOffs += l_iRes;
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &l_sTime);
|
||||
|
||||
l_qwMSec = l_sTime.tv_sec;
|
||||
l_qwMSec *= 1000;
|
||||
l_qwMSec += l_sTime.tv_nsec/1000000;
|
||||
|
||||
l_iRes = snprintf(m_pBuffer + l_iOffs,
|
||||
m_pLength - l_iOffs,
|
||||
"%04d.%02d.%02d %02d:%02d:%02d.%03d: %s: ",
|
||||
l_pTime->tm_year + 1900,
|
||||
l_pTime->tm_mon + 1,
|
||||
l_pTime->tm_mday,
|
||||
l_pTime->tm_hour,
|
||||
l_pTime->tm_min,
|
||||
l_pTime->tm_sec,
|
||||
(int)(l_qwMSec % 1000),
|
||||
m_pName[i_eType]
|
||||
);
|
||||
if (0 <= l_iRes)
|
||||
{
|
||||
l_iOffs += l_iRes;
|
||||
}
|
||||
|
||||
va_list l_pVA;
|
||||
va_start(l_pVA, i_pFormat);
|
||||
vsnprintf(m_pBuffer + l_iOffs, m_pLength - l_iOffs, i_pFormat, l_pVA);
|
||||
va_end(l_pVA);
|
||||
|
||||
//std::cout << m_pBuffer << "\n";
|
||||
printf(m_pBuffer, 0); //0 to close warning from G++
|
||||
printf("\n");
|
||||
|
||||
|
||||
l_lExit:
|
||||
LOCK_EXIT(m_hCS);
|
||||
return l_bReturn;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tUINT64 Get_Count(IJournal::eLevel i_eType)
|
||||
{
|
||||
tUINT64 l_qwReturn = 0ULL;
|
||||
|
||||
if (i_eType >= IJournal::eLEVEL_COUNT)
|
||||
{
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
LOCK_ENTER(m_hCS);
|
||||
l_qwReturn = m_pCount[i_eType];
|
||||
LOCK_EXIT(m_hCS);
|
||||
|
||||
return l_qwReturn;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Register_Thread(const tXCHAR *i_pName, tUINT32 i_dwThreadId)
|
||||
{
|
||||
UNUSED_ARG(i_pName);
|
||||
UNUSED_ARG(i_dwThreadId);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Unregister_Thread(tUINT32 i_dwThreadId)
|
||||
{
|
||||
UNUSED_ARG(i_dwThreadId);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Register_Module(const tXCHAR *i_pName, IJournal::hModule *o_hModule)
|
||||
{
|
||||
UNUSED_ARG(i_pName);
|
||||
if (o_hModule)
|
||||
{
|
||||
*o_hModule = NULL;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tINT32 Add_Ref()
|
||||
{
|
||||
return ATOMIC_INC(&m_iRCnt);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tINT32 Release()
|
||||
{
|
||||
volatile tINT32 l_iReturn = ATOMIC_DEC(&m_iRCnt);
|
||||
|
||||
if (0 >= l_iReturn)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
return l_iReturn;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //PJOURNAL_H
|
||||
45
p7lib/Shared/Platforms/Linux_x86/PLock.h
Normal file
45
p7lib/Shared/Platforms/Linux_x86/PLock.h
Normal file
@ -0,0 +1,45 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PLOCK_H
|
||||
#define PLOCK_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typedef pthread_mutex_t tLOCK;
|
||||
|
||||
|
||||
#define LOCK_CREATE(i_Lock) {\
|
||||
pthread_mutexattr_t l_sAttr;\
|
||||
memset(&l_sAttr, 0, sizeof(pthread_mutexattr_t));\
|
||||
pthread_mutexattr_init(&l_sAttr);\
|
||||
pthread_mutexattr_settype(&l_sAttr,\
|
||||
PTHREAD_MUTEX_RECURSIVE);\
|
||||
pthread_mutex_init(&i_Lock, &l_sAttr);\
|
||||
pthread_mutexattr_destroy(&l_sAttr);\
|
||||
}\
|
||||
|
||||
|
||||
#define LOCK_DESTROY(i_Lock) pthread_mutex_destroy(&i_Lock)
|
||||
|
||||
#define LOCK_ENTER(i_Lock) pthread_mutex_lock(&i_Lock)
|
||||
#define LOCK_EXIT(i_Lock) pthread_mutex_unlock(&i_Lock)
|
||||
#define LOCK_TRY(i_Lock) ((0 == pthread_mutex_trylock(&i_Lock)) ? TRUE : FALSE)
|
||||
|
||||
#endif //PLOCK_H
|
||||
469
p7lib/Shared/Platforms/Linux_x86/PMEvent.h
Normal file
469
p7lib/Shared/Platforms/Linux_x86/PMEvent.h
Normal file
@ -0,0 +1,469 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PMEVENT_H
|
||||
#define PMEVENT_H
|
||||
|
||||
#include <semaphore.h>
|
||||
|
||||
// Infinite timeout
|
||||
#define INFINITE 0xFFFFFFFF
|
||||
|
||||
//#define PMEVENT_COND_VARIABLE
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CMEvent - class designed to avoid problem of "wait" POSIX functions. They are
|
||||
// based on abs. time and they are affected by system time changes.
|
||||
class CMEvent
|
||||
: public IMEvent //virtual
|
||||
{
|
||||
struct sEvent
|
||||
{
|
||||
volatile tINT32 iCounter;
|
||||
eMEvent_Type eType;
|
||||
tUINT32 dwIdx;
|
||||
sEvent *pNext;
|
||||
};
|
||||
|
||||
pthread_mutex_t m_sMutex;
|
||||
|
||||
#ifdef PMEVENT_COND_VARIABLE
|
||||
pthread_cond_t m_sCV;
|
||||
#else
|
||||
sem_t m_sSem;
|
||||
#endif
|
||||
|
||||
tUINT8 m_bCount;
|
||||
tBOOL m_bInit;
|
||||
tBOOL m_bError;
|
||||
sEvent *m_pEvents;
|
||||
sEvent *m_pEvent_Cur;
|
||||
tINT32 m_iSignals;
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CMEvent
|
||||
CMEvent()
|
||||
: m_bCount(0)
|
||||
, m_bInit(FALSE)
|
||||
, m_bError(FALSE)
|
||||
, m_pEvents(NULL)
|
||||
, m_pEvent_Cur(NULL)
|
||||
, m_iSignals(0)
|
||||
{
|
||||
}//CMEvent
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//~CMEvent
|
||||
virtual ~CMEvent()
|
||||
{
|
||||
if (m_bInit)
|
||||
{
|
||||
pthread_mutex_destroy(&m_sMutex);
|
||||
|
||||
#ifdef PMEVENT_COND_VARIABLE
|
||||
pthread_cond_destroy(&m_sCV);
|
||||
#else
|
||||
sem_destroy(&m_sSem);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
Cleanup();
|
||||
|
||||
m_bCount = 0;
|
||||
}//~CMEvent
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Init
|
||||
tBOOL Init(tUINT8 i_bCount, ...)
|
||||
{
|
||||
va_list l_pVA;
|
||||
tUINT8 l_bIDX = 0;
|
||||
tBOOL l_bCA = FALSE;
|
||||
tBOOL l_bSig = FALSE;
|
||||
tBOOL l_bMutex = FALSE;
|
||||
pthread_condattr_t l_sCA;
|
||||
|
||||
|
||||
if ( (TRUE == m_bInit)
|
||||
|| (TRUE == m_bError)
|
||||
|| (0 >= i_bCount)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef PMEVENT_COND_VARIABLE
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//initialize Cond.Variable
|
||||
clockid_t l_iClock = CLOCK_REALTIME;
|
||||
|
||||
if (0 != pthread_condattr_init(&l_sCA))
|
||||
{
|
||||
goto l_lExit; //error
|
||||
}
|
||||
else
|
||||
{
|
||||
l_bCA = TRUE;
|
||||
}
|
||||
|
||||
//#ifdef __USE_XOPEN2K
|
||||
if (0 != pthread_condattr_setclock(&l_sCA, CLOCK_MONOTONIC))
|
||||
{
|
||||
goto l_lExit; //error
|
||||
}
|
||||
|
||||
if ( (0 != pthread_condattr_getclock(&l_sCA, &l_iClock))
|
||||
|| (CLOCK_MONOTONIC != l_iClock)
|
||||
)
|
||||
{
|
||||
goto l_lExit; //error
|
||||
}
|
||||
//#else
|
||||
//#endif
|
||||
|
||||
if (0 != pthread_cond_init(&m_sCV, &l_sCA))
|
||||
{
|
||||
goto l_lExit; //error
|
||||
}
|
||||
else
|
||||
{
|
||||
l_bSig = TRUE;
|
||||
}
|
||||
#else
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//initialize semaphore
|
||||
if (0 != sem_init(&m_sSem, 0, 0))
|
||||
{
|
||||
goto l_lExit; //error
|
||||
}
|
||||
else
|
||||
{
|
||||
l_bSig = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//initialize mutex
|
||||
if (0 != pthread_mutex_init(&m_sMutex, NULL))
|
||||
{
|
||||
m_bError = TRUE;
|
||||
goto l_lExit;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_bMutex = TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//initialize events structure
|
||||
m_pEvents = new sEvent[i_bCount];
|
||||
if (NULL == m_pEvents)
|
||||
{
|
||||
goto l_lExit;
|
||||
}
|
||||
|
||||
memset(m_pEvents, 0, sizeof(sEvent) * i_bCount);
|
||||
|
||||
m_pEvent_Cur = &m_pEvents[0];
|
||||
|
||||
va_start(l_pVA, i_bCount);
|
||||
while (l_bIDX < i_bCount)
|
||||
{
|
||||
m_pEvents[l_bIDX].eType = (eMEvent_Type)va_arg(l_pVA, /*eMEvent_Type*/int);
|
||||
m_pEvents[l_bIDX].iCounter = 0;
|
||||
m_pEvents[l_bIDX].dwIdx = l_bIDX;
|
||||
|
||||
//make round trip links
|
||||
if ((l_bIDX + 1) < i_bCount)
|
||||
{
|
||||
m_pEvents[l_bIDX].pNext = &m_pEvents[l_bIDX + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pEvents[l_bIDX].pNext = &m_pEvents[0];
|
||||
}
|
||||
|
||||
l_bIDX++;
|
||||
}
|
||||
|
||||
va_end(l_pVA);
|
||||
|
||||
m_bInit = TRUE;
|
||||
m_bCount = i_bCount;
|
||||
|
||||
l_lExit:
|
||||
if (l_bCA)
|
||||
{
|
||||
pthread_condattr_destroy(&l_sCA);
|
||||
}
|
||||
|
||||
if (FALSE == m_bInit)
|
||||
{
|
||||
m_bError = TRUE;
|
||||
|
||||
if (l_bMutex)
|
||||
{
|
||||
pthread_mutex_destroy(&m_sMutex);
|
||||
}
|
||||
|
||||
if (l_bSig)
|
||||
{
|
||||
#ifdef PMEVENT_COND_VARIABLE
|
||||
pthread_cond_destroy(&m_sCV);
|
||||
#else
|
||||
sem_destroy(&m_sSem);
|
||||
#endif
|
||||
}
|
||||
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
return m_bInit;
|
||||
}//Init
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Set
|
||||
tBOOL Set(tUINT32 i_dwID)
|
||||
{
|
||||
if ( (i_dwID >= m_bCount)
|
||||
|| (FALSE == m_bInit)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&m_sMutex);
|
||||
|
||||
m_iSignals++;
|
||||
m_pEvents[i_dwID].iCounter ++;
|
||||
|
||||
#ifdef PMEVENT_COND_VARIABLE
|
||||
pthread_cond_signal(&m_sCV);
|
||||
#else
|
||||
sem_post(&m_sSem);
|
||||
#endif
|
||||
|
||||
pthread_mutex_unlock(&m_sMutex);
|
||||
|
||||
return TRUE;
|
||||
}//Set
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Clr
|
||||
tBOOL Clr(tUINT32 i_dwID)
|
||||
{
|
||||
tBOOL l_bReturn = FALSE;
|
||||
if ( (i_dwID >= m_bCount)
|
||||
|| (EMEVENT_SINGLE_MANUAL != m_pEvents[i_dwID].eType)
|
||||
)
|
||||
{
|
||||
return l_bReturn;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&m_sMutex);
|
||||
|
||||
if (m_pEvents[i_dwID].iCounter)
|
||||
{
|
||||
m_iSignals --;
|
||||
m_pEvents[i_dwID].iCounter --;
|
||||
|
||||
sem_trywait(&m_sSem); //decrease semaphore
|
||||
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&m_sMutex);
|
||||
|
||||
return l_bReturn;
|
||||
}//Clr
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Wait
|
||||
tUINT32 Wait()
|
||||
{
|
||||
tUINT32 l_dwReturn = MEVENT_TIME_OUT;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//LOCK
|
||||
|
||||
#ifdef PMEVENT_COND_VARIABLE
|
||||
int l_iCV_Res = 0;
|
||||
|
||||
pthread_mutex_lock(&m_sMutex);
|
||||
|
||||
while (0 == m_iSignals)
|
||||
{
|
||||
l_iCV_Res = pthread_cond_wait(&m_sCV, &m_sMutex);
|
||||
if (0 != l_iCV_Res)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
l_dwReturn = Get_Signal();
|
||||
|
||||
pthread_mutex_unlock(&m_sMutex);
|
||||
#else
|
||||
sem_wait(&m_sSem);
|
||||
|
||||
pthread_mutex_lock(&m_sMutex);
|
||||
l_dwReturn = Get_Signal();
|
||||
pthread_mutex_unlock(&m_sMutex);
|
||||
#endif
|
||||
|
||||
|
||||
//UNLOCK
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
return l_dwReturn;
|
||||
}//Wait
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Wait
|
||||
tUINT32 Wait(tUINT32 i_dwMSec)
|
||||
{
|
||||
tUINT64 l_qwNano = (tUINT64)i_dwMSec * 1000000ULL;
|
||||
tUINT32 l_dwReturn = MEVENT_TIME_OUT;
|
||||
struct timespec l_sTime = {0, 0};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//LOCK
|
||||
|
||||
#ifdef PMEVENT_COND_VARIABLE
|
||||
int l_iRes = 0;
|
||||
pthread_mutex_lock(&m_sMutex);
|
||||
clock_gettime(CLOCK_MONOTONIC, &l_sTime);
|
||||
|
||||
l_qwNano += l_sTime.tv_nsec;
|
||||
l_sTime.tv_sec += static_cast<__time_t>(l_qwNano / 1000000000ULL);
|
||||
l_sTime.tv_nsec = static_cast<long int>(l_qwNano % 1000000000ULL);
|
||||
|
||||
while (0 == m_iSignals)
|
||||
{
|
||||
//ETIMEDOUT
|
||||
l_iRes = pthread_cond_timedwait(&m_sCV, &m_sMutex, &l_sTime);
|
||||
if (0 != l_iRes)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
l_dwReturn = Get_Signal();
|
||||
pthread_mutex_unlock(&m_sMutex);
|
||||
#else
|
||||
if (0 == i_dwMSec)
|
||||
{
|
||||
if (0 == sem_trywait(&m_sSem))
|
||||
{
|
||||
pthread_mutex_lock(&m_sMutex);
|
||||
l_dwReturn = Get_Signal();
|
||||
pthread_mutex_unlock(&m_sMutex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clock_gettime(CLOCK_REALTIME, &l_sTime);
|
||||
|
||||
l_qwNano += l_sTime.tv_nsec;
|
||||
l_sTime.tv_sec += static_cast<time_t>(l_qwNano/1000000000ULL);
|
||||
l_sTime.tv_nsec = static_cast<long>(l_qwNano%1000000000ULL);
|
||||
|
||||
if (0 == sem_timedwait(&m_sSem, &l_sTime))
|
||||
{
|
||||
pthread_mutex_lock(&m_sMutex);
|
||||
l_dwReturn = Get_Signal();
|
||||
pthread_mutex_unlock(&m_sMutex);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//UNLOCK
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
return l_dwReturn;
|
||||
}//Wait
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Signal
|
||||
tUINT32 Get_Signal()
|
||||
{
|
||||
tUINT32 l_dwReturn = MEVENT_TIME_OUT;
|
||||
|
||||
if (0 == m_iSignals) //if we register some signal
|
||||
{
|
||||
return l_dwReturn;
|
||||
}
|
||||
|
||||
sEvent *l_pStart = m_pEvent_Cur;
|
||||
//we will walk through all events in attempt to find signal
|
||||
do
|
||||
{
|
||||
m_pEvent_Cur = m_pEvent_Cur->pNext;
|
||||
|
||||
if (m_pEvent_Cur->iCounter)
|
||||
{
|
||||
l_dwReturn = m_pEvent_Cur->dwIdx;
|
||||
if (EMEVENT_SINGLE_MANUAL == m_pEvent_Cur->eType)
|
||||
{
|
||||
sem_post(&m_sSem); //return sem value to signal again
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pEvent_Cur->iCounter --;
|
||||
m_iSignals --;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//if we do round trip
|
||||
} while (l_pStart != m_pEvent_Cur);
|
||||
|
||||
if (MEVENT_TIME_OUT == l_dwReturn)
|
||||
{
|
||||
//error: signal event wasn't found !
|
||||
m_iSignals --;
|
||||
}
|
||||
|
||||
return l_dwReturn;
|
||||
}//Get_Signal
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Cleanup
|
||||
void Cleanup()
|
||||
{
|
||||
if (m_pEvents)
|
||||
{
|
||||
delete [] m_pEvents;
|
||||
m_pEvents = NULL;
|
||||
}
|
||||
}//Cleanup
|
||||
};
|
||||
|
||||
#endif //PMEVENT_H
|
||||
72
p7lib/Shared/Platforms/Linux_x86/PPerformanceInfo.h
Normal file
72
p7lib/Shared/Platforms/Linux_x86/PPerformanceInfo.h
Normal file
@ -0,0 +1,72 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PPERFORMANCE_INFO_H
|
||||
#define PPERFORMANCE_INFO_H
|
||||
|
||||
#include "IPerformanceInfo.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class CPerformanceInfo
|
||||
: public IPerformanceInfo
|
||||
{
|
||||
volatile tINT32 m_iRCnt;
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
CPerformanceInfo(const tXCHAR *i_pProcessName)
|
||||
: m_iRCnt(1)
|
||||
{
|
||||
UNUSED_ARG(i_pProcessName);
|
||||
}
|
||||
|
||||
virtual ~CPerformanceInfo()
|
||||
{
|
||||
}
|
||||
|
||||
tBOOL Refresh()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
tINT64 Get(IPerformanceInfo::eCounter i_eCounter)
|
||||
{
|
||||
UNUSED_ARG(i_eCounter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tINT32 Add_Ref()
|
||||
{
|
||||
return ATOMIC_INC(&m_iRCnt);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tINT32 Release()
|
||||
{
|
||||
volatile tINT32 l_iReturn = ATOMIC_DEC(&m_iRCnt);
|
||||
|
||||
if (0 >= l_iReturn)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
return l_iReturn;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //PPERFORMANCE_INFO_H
|
||||
575
p7lib/Shared/Platforms/Linux_x86/PProcess.h
Normal file
575
p7lib/Shared/Platforms/Linux_x86/PProcess.h
Normal file
@ -0,0 +1,575 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PPROCESS_H
|
||||
#define PPROCESS_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <asm/param.h> //HZ macro !
|
||||
#include <sched.h>
|
||||
|
||||
class CProc
|
||||
{
|
||||
public:
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//Get_ArgV
|
||||
static tXCHAR **Get_ArgV(tINT32 *o_pCount)
|
||||
{
|
||||
const tUINT16 l_wLen = 4096;
|
||||
tXCHAR *l_pBuffer = new tXCHAR[l_wLen];
|
||||
tXCHAR **l_pReturn = NULL;
|
||||
int l_pFile = -1;
|
||||
tINT32 l_iRead = -1;
|
||||
tBOOL l_bNew = TRUE;
|
||||
tINT32 l_iIDX = 0;
|
||||
|
||||
if ( (NULL == l_pBuffer)
|
||||
|| (NULL == o_pCount)
|
||||
)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_pFile = open("/proc/self/cmdline", O_RDONLY);
|
||||
|
||||
if (-1 == l_pFile)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_iRead = read(l_pFile, l_pBuffer, l_wLen * sizeof(tXCHAR));
|
||||
|
||||
if (0 >= l_iRead)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
//calculate count of items//////////////////////////////////////////////////
|
||||
*o_pCount = 0;
|
||||
for (tINT32 l_iI = 0; l_iI < l_iRead; l_iI++)
|
||||
{
|
||||
if ( (0 == l_pBuffer[l_iI])
|
||||
|| ((l_iI + 1) == l_iRead)
|
||||
)
|
||||
{
|
||||
(*o_pCount) ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 >= *o_pCount)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
//allocate result///////////////////////////////////////////////////////////
|
||||
l_pReturn = new tXCHAR*[*o_pCount];
|
||||
|
||||
if (NULL == l_pReturn)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
//fill result///////////////////////////////////////////////////////////////
|
||||
l_bNew = TRUE;
|
||||
for (tINT32 l_iI = 0; l_iI < l_iRead; l_iI++)
|
||||
{
|
||||
if (l_bNew)
|
||||
{
|
||||
l_pReturn[l_iIDX++] = &l_pBuffer[l_iI];
|
||||
l_bNew = FALSE;
|
||||
}
|
||||
|
||||
if (0 == l_pBuffer[l_iI])
|
||||
{
|
||||
l_bNew = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
l_lblExit:
|
||||
|
||||
if (-1 != l_pFile)
|
||||
{
|
||||
close(l_pFile);
|
||||
}
|
||||
|
||||
if (NULL == l_pReturn)
|
||||
{
|
||||
if (l_pBuffer)
|
||||
{
|
||||
delete [] l_pBuffer;
|
||||
l_pBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return l_pReturn;
|
||||
// return = CommandLineToArgvW(GetCommandLineW(), o_pCount);
|
||||
}//Get_ArgV
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//Get_ArgV
|
||||
static tXCHAR **Get_ArgV(const tXCHAR *i_pCmdLine, tINT32 *o_pCount)
|
||||
{
|
||||
tINT32 l_iLen = 0;//strlen(i_pCmdLine);
|
||||
tXCHAR *l_pBuffer = NULL;//new tXCHAR[l_iLen];
|
||||
tXCHAR **l_pReturn = NULL;
|
||||
tBOOL l_bNew = TRUE;
|
||||
tBOOL l_bStr = FALSE;
|
||||
tINT32 l_iIDX = 0;
|
||||
|
||||
if ( (NULL == i_pCmdLine)
|
||||
|| (NULL == o_pCount)
|
||||
)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_iLen = (tINT32)strlen(i_pCmdLine) + 1;
|
||||
l_pBuffer = new tXCHAR[l_iLen];
|
||||
|
||||
if (NULL == l_pBuffer)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
for (tINT32 l_iI = 0; l_iI < l_iLen; l_iI++)
|
||||
{
|
||||
if (TM('\"') == i_pCmdLine[l_iI])
|
||||
{
|
||||
l_bStr = ! l_bStr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (TM(' ') == i_pCmdLine[l_iI])
|
||||
&& (!l_bStr)
|
||||
)
|
||||
{
|
||||
l_pBuffer[l_iIDX++] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_pBuffer[l_iIDX++] = i_pCmdLine[l_iI];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
l_iLen = l_iIDX;
|
||||
|
||||
//calculate count of items//////////////////////////////////////////////////
|
||||
*o_pCount = 0;
|
||||
for (tINT32 l_iI = 0; l_iI < l_iLen; l_iI++)
|
||||
{
|
||||
if ( (0 == l_pBuffer[l_iI])
|
||||
|| ((l_iI + 1) == l_iLen)
|
||||
)
|
||||
{
|
||||
(*o_pCount) ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 >= *o_pCount)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
//allocate result///////////////////////////////////////////////////////////
|
||||
l_pReturn = new tXCHAR*[*o_pCount];
|
||||
|
||||
if (NULL == l_pReturn)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
//fill result///////////////////////////////////////////////////////////////
|
||||
l_bNew = TRUE;
|
||||
l_iIDX = 0;
|
||||
for (tINT32 l_iI = 0; l_iI < l_iLen; l_iI++)
|
||||
{
|
||||
if (l_bNew)
|
||||
{
|
||||
l_pReturn[l_iIDX++] = &l_pBuffer[l_iI];
|
||||
l_bNew = FALSE;
|
||||
}
|
||||
|
||||
if (0 == l_pBuffer[l_iI])
|
||||
{
|
||||
l_bNew = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
l_lblExit:
|
||||
|
||||
return l_pReturn;
|
||||
}//Get_ArgV
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//Free_ArgV
|
||||
static void Free_ArgV(tXCHAR **i_pArgV)
|
||||
{
|
||||
if (NULL == i_pArgV)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (i_pArgV[0])
|
||||
{
|
||||
delete [] i_pArgV[0];
|
||||
}
|
||||
|
||||
delete [] i_pArgV;
|
||||
//LocalFree(i_pArgV);
|
||||
}//Free_ArgV
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Process_Time()
|
||||
//return a 64-bit value divided into 2 parts representing the number of
|
||||
//100-nanosecond intervals since January 1, 1601 (UTC).
|
||||
static tBOOL Get_Process_Time(tUINT32 *o_pHTime, tUINT32 *o_pLTime)
|
||||
{
|
||||
const int l_iLen = 8192;
|
||||
char *l_pBuffer = new char[l_iLen];
|
||||
int l_iRead = 0;
|
||||
int l_pFile = -1;
|
||||
char *l_pIter = NULL;
|
||||
long long l_llBtime = 0;
|
||||
long long l_llStime = 0;
|
||||
int l_iSscanf = 0;
|
||||
tBOOL l_bResult = FALSE;
|
||||
|
||||
if ( (NULL == l_pBuffer)
|
||||
|| (NULL == o_pHTime)
|
||||
|| (NULL == o_pLTime)
|
||||
)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
*o_pHTime = 0;
|
||||
*o_pLTime = 0;
|
||||
|
||||
//read global stat//////////////////////////////////////////////////////////
|
||||
l_pFile = open("/proc/stat", O_RDONLY);
|
||||
if (-1 == l_pFile)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_iRead = read(l_pFile, l_pBuffer, l_iLen);
|
||||
close(l_pFile);
|
||||
|
||||
if (0 >= l_iRead)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
if (l_iRead < l_iLen)
|
||||
{
|
||||
l_pBuffer[l_iRead -1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_pBuffer[l_iLen -1] = 0;
|
||||
}
|
||||
|
||||
//printf((char*)l_pBuffer, 0);
|
||||
//printf("\nLen = %d\n", l_iRead);
|
||||
|
||||
//get "btime" value/////////////////////////////////////////////////////////
|
||||
{
|
||||
const char l_pBtime[] = "btime ";
|
||||
int l_iBLen = strlen(l_pBtime);
|
||||
|
||||
l_pIter = l_pBuffer;
|
||||
for (int l_iI = 0; l_iI < l_iRead; l_iI++)
|
||||
{
|
||||
if (0 == strncmp(l_pBtime, l_pIter, l_iBLen))
|
||||
{
|
||||
l_iSscanf = sscanf(l_pIter + l_iBLen, "%lld", &l_llBtime);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_pIter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 >= l_iSscanf)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
//read process statistics///////////////////////////////////////////////////
|
||||
l_pFile = open("/proc/self/stat", O_RDONLY);
|
||||
|
||||
if (-1 == l_pFile)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_iRead = read(l_pFile, l_pBuffer, l_iLen);
|
||||
close(l_pFile);
|
||||
|
||||
if (0 >= l_iRead)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
if (l_iRead < l_iLen)
|
||||
{
|
||||
l_pBuffer[l_iRead -1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_pBuffer[l_iLen -1] = 0;
|
||||
}
|
||||
|
||||
//get process start time////////////////////////////////////////////////////
|
||||
{
|
||||
int l_iItem = 1;
|
||||
l_pIter = l_pBuffer;
|
||||
for (int l_iI = 0; l_iI < l_iRead; l_iI++)
|
||||
{
|
||||
if (' ' == *l_pIter)
|
||||
{
|
||||
if (21 == l_iItem)
|
||||
{
|
||||
l_iSscanf = sscanf(l_pIter, " %lld", &l_llStime);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_iItem ++;
|
||||
}
|
||||
}
|
||||
|
||||
l_pIter++;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 >= l_iSscanf)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
//HZ defined in #include <asm/param.h>
|
||||
l_llStime = l_llBtime * 10000000ull + (l_llStime * 10000000ull / HZ);
|
||||
l_llStime += TIME_OFFSET_1601_1970; //defined in "PTime.h"
|
||||
|
||||
*o_pHTime = (l_llStime >> 32);
|
||||
*o_pLTime = (l_llStime & 0xFFFFFFFF);
|
||||
|
||||
l_bResult = TRUE;
|
||||
|
||||
l_lblExit:
|
||||
if (l_pBuffer)
|
||||
{
|
||||
delete [] l_pBuffer;
|
||||
l_pBuffer = NULL;
|
||||
}
|
||||
|
||||
return l_bResult;
|
||||
}//Get_Process_Time()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Process_Name
|
||||
static tBOOL Get_Process_Name(tACHAR *o_pName, tINT32 i_iMax_Len)
|
||||
{
|
||||
int l_iRead = 0;
|
||||
char *l_pName = NULL;
|
||||
char *l_pDst = o_pName;
|
||||
tBOOL l_bReturn = FALSE;
|
||||
|
||||
if ( (NULL == o_pName)
|
||||
|| (32 >= i_iMax_Len)
|
||||
|| (NULL == o_pName)
|
||||
)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_iRead = readlink("/proc/self/exe", o_pName, i_iMax_Len - 1);
|
||||
if (0 >= l_iRead)
|
||||
{
|
||||
// I guess we're not running on the right version of unix
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
if (l_iRead >= i_iMax_Len)
|
||||
{
|
||||
l_iRead = i_iMax_Len - 1;
|
||||
}
|
||||
|
||||
o_pName[l_iRead] = '\0';
|
||||
|
||||
l_pName = o_pName + l_iRead;
|
||||
|
||||
while (l_pName != o_pName)
|
||||
{
|
||||
if ( ('/' == *l_pName)
|
||||
|| ('\\' == *l_pName)
|
||||
)
|
||||
{
|
||||
l_pName ++;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_pName --;
|
||||
}
|
||||
}
|
||||
|
||||
while (*l_pName)
|
||||
{
|
||||
*l_pDst++=*l_pName++;
|
||||
}
|
||||
*l_pDst = 0;
|
||||
|
||||
l_bReturn = TRUE;
|
||||
|
||||
l_lblExit:
|
||||
return l_bReturn;
|
||||
}//Get_Process_Name
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Process_Name
|
||||
static tBOOL Get_Process_Name(tWCHAR *o_pName, tINT32 i_iMax_Len)
|
||||
{
|
||||
int l_iLen = 4096;
|
||||
char *l_pBuffer = new char[l_iLen];
|
||||
tBOOL l_bReturn = FALSE;
|
||||
|
||||
|
||||
if ( (l_pBuffer)
|
||||
&& (Get_Process_Name(l_pBuffer, l_iLen))
|
||||
)
|
||||
{
|
||||
l_bReturn = TRUE;
|
||||
Convert_UTF8_To_UTF16(l_pBuffer, o_pName, i_iMax_Len);
|
||||
}
|
||||
else
|
||||
{
|
||||
Convert_UTF8_To_UTF16("Unknown", o_pName, i_iMax_Len);
|
||||
}
|
||||
|
||||
if (l_pBuffer)
|
||||
{
|
||||
delete [] l_pBuffer;
|
||||
l_pBuffer = NULL;
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}//Get_Process_Name
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Process_Path
|
||||
static tBOOL Get_Process_Path(tXCHAR *o_pPath, tINT32 i_iMax_Len)
|
||||
{
|
||||
int l_iRead = 0;
|
||||
tBOOL l_bReturn = FALSE;
|
||||
|
||||
if ( (NULL == o_pPath)
|
||||
|| (32 >= i_iMax_Len)
|
||||
)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_iRead = readlink("/proc/self/exe", o_pPath, i_iMax_Len - 4);
|
||||
if (0 >= l_iRead)
|
||||
{
|
||||
// I guess we're not running on the right version of unix
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
if (l_iRead >= i_iMax_Len)
|
||||
{
|
||||
// buffer is too small
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
o_pPath[l_iRead] = '\0';
|
||||
|
||||
while (l_iRead)
|
||||
{
|
||||
if ( ('/' == o_pPath[l_iRead])
|
||||
|| ('\\' == o_pPath[l_iRead])
|
||||
)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
o_pPath[l_iRead--] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
l_bReturn = TRUE;
|
||||
|
||||
l_lblExit:
|
||||
|
||||
if (TRUE != l_bReturn)
|
||||
{
|
||||
strcpy(o_pPath, "./");
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}//Get_Process_Path
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Process_ID
|
||||
static tUINT32 Get_Process_ID()
|
||||
{
|
||||
return getpid();
|
||||
//return GetCurrentProcessId();
|
||||
}//Get_Process_ID
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Thread_Id
|
||||
static tUINT32 Get_Thread_Id()
|
||||
{
|
||||
return (int32_t)syscall(SYS_gettid);
|
||||
//return pthread_self();
|
||||
//return gettid();
|
||||
}//Get_Thread_Id
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Processor
|
||||
static __forceinline tUINT32 Get_Processor()
|
||||
{
|
||||
#ifdef __ARM_ARCH_5TEJ__
|
||||
return 0;
|
||||
#else
|
||||
return sched_getcpu();
|
||||
#endif
|
||||
}//Get_Processor
|
||||
};
|
||||
|
||||
#endif //PPROCESS_H
|
||||
99
p7lib/Shared/Platforms/Linux_x86/PProfiler.h
Normal file
99
p7lib/Shared/Platforms/Linux_x86/PProfiler.h
Normal file
@ -0,0 +1,99 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "PTime.h"
|
||||
#include "Ticks.h"
|
||||
|
||||
class CTickHi
|
||||
{
|
||||
tUINT64 m_qwCounter;
|
||||
tUINT64 m_qwMarkIn;
|
||||
tUINT64 m_qwMarkOut;
|
||||
tUINT64 m_qwResolution;
|
||||
public:
|
||||
CTickHi()
|
||||
{
|
||||
m_qwMarkIn = 0ull;
|
||||
m_qwMarkOut = 0ull;
|
||||
m_qwCounter = 0ull;
|
||||
m_qwResolution = GetPerformanceFrequency();
|
||||
|
||||
Reset();
|
||||
Start();
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
m_qwMarkIn = GetPerformanceCounter();
|
||||
}
|
||||
|
||||
void Stop()
|
||||
{
|
||||
m_qwMarkOut = GetPerformanceCounter();
|
||||
m_qwCounter += m_qwMarkOut - m_qwMarkIn;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_qwCounter = 0;
|
||||
}
|
||||
|
||||
//Second == 100 000;
|
||||
tUINT32 Get()
|
||||
{
|
||||
return (tUINT32)(m_qwCounter * 100000ULL / m_qwResolution);
|
||||
}
|
||||
};
|
||||
|
||||
class CTickLow
|
||||
{
|
||||
tUINT32 m_dwStart;
|
||||
tUINT32 m_dwStop;
|
||||
public:
|
||||
CTickLow()
|
||||
{
|
||||
m_dwStart = 0;
|
||||
m_dwStop = 0;
|
||||
|
||||
Reset();
|
||||
Start();
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
m_dwStart = GetTickCount();
|
||||
}
|
||||
|
||||
void Stop()
|
||||
{
|
||||
m_dwStop = GetTickCount();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_dwStop = 0;
|
||||
}
|
||||
|
||||
//frequency 1 000 per second
|
||||
tUINT32 Get()
|
||||
{
|
||||
return CTicks::Difference(m_dwStop, m_dwStart);
|
||||
}
|
||||
};
|
||||
639
p7lib/Shared/Platforms/Linux_x86/PShared.h
Normal file
639
p7lib/Shared/Platforms/Linux_x86/PShared.h
Normal file
@ -0,0 +1,639 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PSHARED_H
|
||||
#define PSHARED_H
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Headers dependencies:
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h> // For O_* constants
|
||||
#include <semaphore.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h> // For mode constants
|
||||
|
||||
#define SHARED_NAME_FORMAT_STRING "/P7_Type%d_PID%d_Text%s"
|
||||
#define SHARED_NAME_LEN (strlen(SHARED_NAME_FORMAT_STRING) + 64)
|
||||
#define SHARED_SEM_NULL SEM_FAILED
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CShared
|
||||
class CShared
|
||||
{
|
||||
struct sShared
|
||||
{
|
||||
int iMFD;
|
||||
sem_t *hSemaphore;
|
||||
size_t szName;
|
||||
char *pName;
|
||||
char *pSemName;
|
||||
char *pMemName;
|
||||
};
|
||||
|
||||
enum eType
|
||||
{
|
||||
ETYPE_MUTEX = 0,
|
||||
ETYPE_FILE ,
|
||||
ETYPE_MAX
|
||||
};
|
||||
|
||||
public:
|
||||
typedef sShared *hShared;
|
||||
typedef sem_t *hSem;
|
||||
|
||||
enum eLock
|
||||
{
|
||||
E_OK ,
|
||||
E_TIMEOUT ,
|
||||
E_ERROR ,
|
||||
E_NOT_EXISTS
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CShared::Create
|
||||
static tBOOL Create(CShared::hShared *o_pHandle,
|
||||
const tXCHAR *i_pName,
|
||||
const tUINT8 *i_pData,
|
||||
tUINT16 i_wSize
|
||||
)
|
||||
{
|
||||
hShared l_pShared = NULL;
|
||||
tBOOL l_bResult = TRUE;
|
||||
tBOOL l_bRelease = FALSE;
|
||||
void *l_pBuffer = NULL;
|
||||
|
||||
if ( (NULL == i_pName)
|
||||
|| (NULL == i_pData)
|
||||
|| (0 >= i_wSize)
|
||||
|| (NULL == o_pHandle)
|
||||
)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_pShared = (hShared)malloc(sizeof(sShared));
|
||||
if (NULL == l_pShared)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
memset(l_pShared, 0, sizeof(sShared));
|
||||
l_pShared->hSemaphore = SHARED_SEM_NULL;
|
||||
l_pShared->iMFD = -1;
|
||||
|
||||
l_pShared->szName = strlen(i_pName) + SHARED_NAME_LEN;
|
||||
l_pShared->pName = strdup(i_pName);
|
||||
l_pShared->pSemName = (char*)malloc(l_pShared->szName);
|
||||
l_pShared->pMemName = (char*)malloc(l_pShared->szName);
|
||||
|
||||
if ( (NULL == l_pShared->pSemName)
|
||||
|| (NULL == l_pShared->pMemName)
|
||||
|| (NULL == l_pShared->pName)
|
||||
)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//create ssemaphore and own it
|
||||
Create_Name(l_pShared->pSemName, l_pShared->szName, ETYPE_MUTEX, i_pName);
|
||||
|
||||
l_pShared->hSemaphore = sem_open(l_pShared->pSemName, O_CREAT | O_EXCL, 0666, 0);
|
||||
if (SHARED_SEM_NULL == l_pShared->hSemaphore)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_bRelease = TRUE;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//share memory
|
||||
Create_Name(l_pShared->pMemName, l_pShared->szName, ETYPE_FILE, i_pName);
|
||||
|
||||
l_pShared->iMFD = shm_open(l_pShared->pMemName,
|
||||
O_RDWR | O_CREAT | O_EXCL,
|
||||
0666
|
||||
);
|
||||
if (0 > l_pShared->iMFD)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
if (0 != ftruncate(l_pShared->iMFD, (off_t)i_wSize))
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_pBuffer = mmap(0,
|
||||
(size_t)i_wSize,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
l_pShared->iMFD,
|
||||
0
|
||||
);
|
||||
|
||||
if ( (NULL == l_pBuffer)
|
||||
|| (MAP_FAILED == l_pBuffer)
|
||||
)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
*o_pHandle = (CShared::hShared)l_pShared;
|
||||
|
||||
memcpy(l_pBuffer, i_pData, (size_t)i_wSize);
|
||||
|
||||
if (0 != munmap(l_pBuffer, (size_t)i_wSize))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
l_lblExit:
|
||||
if (l_bRelease)
|
||||
{
|
||||
sem_post(l_pShared->hSemaphore);
|
||||
}
|
||||
|
||||
if (FALSE == l_bResult)
|
||||
{
|
||||
Close(l_pShared);
|
||||
l_pShared = NULL;
|
||||
|
||||
if (o_pHandle)
|
||||
{
|
||||
*o_pHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return l_bResult;
|
||||
}//CShared::Create
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Read
|
||||
static tBOOL Read(const tXCHAR *i_pName,
|
||||
void *o_pData,
|
||||
tUINT16 i_wSize
|
||||
)
|
||||
{
|
||||
tBOOL l_bResult = TRUE;
|
||||
size_t l_szName = 0;
|
||||
char *l_pName = NULL;
|
||||
void *l_pBuffer = NULL;
|
||||
int l_iMFD = -1;
|
||||
struct stat l_sStat;
|
||||
|
||||
|
||||
if ( (NULL == i_pName)
|
||||
|| (NULL == o_pData)
|
||||
|| (0 >= i_wSize)
|
||||
)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_szName = strlen(i_pName) + SHARED_NAME_LEN;
|
||||
l_pName = (char*)malloc(l_szName);
|
||||
|
||||
if (NULL == l_pName)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//open shared memory object
|
||||
Create_Name(l_pName, l_szName, ETYPE_FILE, i_pName);
|
||||
|
||||
l_iMFD = shm_open(l_pName, O_RDONLY, 0444);
|
||||
|
||||
if (0 > l_iMFD)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
memset(&l_sStat, 0, sizeof(l_sStat));
|
||||
if (-1 == fstat(l_iMFD, &l_sStat))
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
if ((size_t)l_sStat.st_size > (size_t)i_wSize)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_pBuffer = mmap(0,
|
||||
(size_t)l_sStat.st_size,
|
||||
PROT_READ,
|
||||
MAP_SHARED,
|
||||
l_iMFD,
|
||||
0
|
||||
);
|
||||
|
||||
if ( (NULL == l_pBuffer)
|
||||
|| (MAP_FAILED == l_pBuffer)
|
||||
)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
memcpy(o_pData, l_pBuffer, (size_t)l_sStat.st_size);
|
||||
|
||||
if (0 == munmap(l_pBuffer, (size_t)l_sStat.st_size))
|
||||
{
|
||||
l_pBuffer = NULL;
|
||||
}
|
||||
|
||||
|
||||
l_lblExit:
|
||||
if (l_pName)
|
||||
{
|
||||
free(l_pName);
|
||||
l_pName = NULL;
|
||||
}
|
||||
|
||||
if (0 <= l_iMFD)
|
||||
{
|
||||
close(l_iMFD);
|
||||
l_iMFD = -1;
|
||||
}
|
||||
|
||||
return l_bResult;
|
||||
}//Read
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Write
|
||||
static tBOOL Write(const tXCHAR *i_pName,
|
||||
const tUINT8 *i_pData,
|
||||
tUINT16 i_wSize
|
||||
)
|
||||
{
|
||||
tBOOL l_bResult = TRUE;
|
||||
size_t l_szName = 0;
|
||||
char *l_pName = NULL;
|
||||
void *l_pBuffer = NULL;
|
||||
int l_iMFD = -1;
|
||||
struct stat l_sStat;
|
||||
|
||||
|
||||
if ( (NULL == i_pName)
|
||||
|| (NULL == i_pData)
|
||||
|| (0 >= i_wSize)
|
||||
)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_szName = strlen(i_pName) + SHARED_NAME_LEN;
|
||||
l_pName = (char*)malloc(l_szName);
|
||||
|
||||
if (NULL == l_pName)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//open shared memory object
|
||||
Create_Name(l_pName, l_szName, ETYPE_FILE, i_pName);
|
||||
|
||||
l_iMFD = shm_open(l_pName, O_RDWR, 0666);
|
||||
|
||||
if (0 > l_iMFD)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
memset(&l_sStat, 0, sizeof(l_sStat));
|
||||
if (-1 == fstat(l_iMFD, &l_sStat))
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
if ((size_t)l_sStat.st_size < (size_t)i_wSize)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_pBuffer = mmap(0,
|
||||
(size_t)l_sStat.st_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
l_iMFD,
|
||||
0
|
||||
);
|
||||
|
||||
if ( (NULL == l_pBuffer)
|
||||
|| (MAP_FAILED == l_pBuffer)
|
||||
)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
memcpy(l_pBuffer, i_pData, (size_t)i_wSize);
|
||||
|
||||
if (0 == munmap(l_pBuffer, (size_t)l_sStat.st_size))
|
||||
{
|
||||
l_pBuffer = NULL;
|
||||
}
|
||||
|
||||
|
||||
l_lblExit:
|
||||
if (l_pName)
|
||||
{
|
||||
free(l_pName);
|
||||
l_pName = NULL;
|
||||
}
|
||||
|
||||
if (0 <= l_iMFD)
|
||||
{
|
||||
close(l_iMFD);
|
||||
l_iMFD = -1;
|
||||
}
|
||||
|
||||
return l_bResult;
|
||||
}//Write
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Lock
|
||||
static eLock Lock(const tXCHAR *i_pName, CShared::hSem &o_rSem, tUINT32 i_dwTimeout_ms)
|
||||
{
|
||||
eLock l_eReturn = CShared::E_TIMEOUT;
|
||||
size_t l_szName = 0;
|
||||
char *l_pName = NULL;
|
||||
const int l_i1ms = 1000;
|
||||
tINT64 l_llWait = (tINT64)i_dwTimeout_ms * 1000LL;
|
||||
sem_t *l_hSem = SHARED_SEM_NULL;
|
||||
|
||||
o_rSem = SHARED_SEM_NULL;
|
||||
|
||||
if (NULL == i_pName)
|
||||
{
|
||||
l_eReturn = CShared::E_ERROR;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_szName = strlen(i_pName) + SHARED_NAME_LEN;
|
||||
l_pName = (char*)malloc(l_szName);
|
||||
|
||||
if (NULL == l_pName)
|
||||
{
|
||||
l_eReturn = CShared::E_ERROR;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//open semaphore
|
||||
Create_Name(l_pName, l_szName, ETYPE_MUTEX, i_pName);
|
||||
|
||||
l_hSem = sem_open(l_pName, 0);
|
||||
if (SHARED_SEM_NULL == l_hSem)
|
||||
{
|
||||
l_eReturn = CShared::E_NOT_EXISTS;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_eReturn = CShared::E_TIMEOUT;
|
||||
|
||||
while (0 < l_llWait)
|
||||
{
|
||||
if (0 == sem_trywait(l_hSem))
|
||||
{
|
||||
l_eReturn = CShared::E_OK;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
usleep(l_i1ms); //10 ms
|
||||
l_llWait -= l_i1ms;
|
||||
}
|
||||
}
|
||||
|
||||
l_lblExit:
|
||||
if (l_pName)
|
||||
{
|
||||
free(l_pName);
|
||||
l_pName = NULL;
|
||||
}
|
||||
|
||||
if (SHARED_SEM_NULL != l_hSem)
|
||||
{
|
||||
if (CShared::E_OK == l_eReturn)
|
||||
{
|
||||
o_rSem = l_hSem;
|
||||
}
|
||||
else
|
||||
{
|
||||
sem_close(l_hSem);
|
||||
l_hSem = SHARED_SEM_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return l_eReturn;
|
||||
}//Lock
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//UnLock
|
||||
static eLock UnLock(CShared::hSem &io_rSem)
|
||||
{
|
||||
eLock l_eReturn = CShared::E_ERROR;
|
||||
|
||||
if (SHARED_SEM_NULL == io_rSem)
|
||||
{
|
||||
l_eReturn = CShared::E_NOT_EXISTS;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
if (0 == sem_post(io_rSem))
|
||||
{
|
||||
l_eReturn = CShared::E_OK;
|
||||
}
|
||||
|
||||
sem_close(io_rSem);
|
||||
io_rSem = SHARED_SEM_NULL;
|
||||
|
||||
l_lblExit:
|
||||
return l_eReturn;
|
||||
}//UnLock
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//GetSemName
|
||||
static const tXCHAR* GetName(hShared i_pShared)
|
||||
{
|
||||
if (NULL == i_pShared)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return i_pShared->pName;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Close
|
||||
static tBOOL Close(hShared i_pShared)
|
||||
{
|
||||
if (NULL == i_pShared)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//if (SHARED_SEM_NULL != i_pShared->hSemaphore)
|
||||
//{
|
||||
// sem_wait(i_pShared->hSemaphore);
|
||||
//}
|
||||
|
||||
if (0 <= i_pShared->iMFD)
|
||||
{
|
||||
close(i_pShared->iMFD);
|
||||
i_pShared->iMFD = -1;
|
||||
}
|
||||
|
||||
if (i_pShared->pMemName)
|
||||
{
|
||||
shm_unlink(i_pShared->pMemName);
|
||||
}
|
||||
|
||||
if (SHARED_SEM_NULL != i_pShared->hSemaphore)
|
||||
{
|
||||
int l_iRes = -1;
|
||||
l_iRes = sem_close(i_pShared->hSemaphore);
|
||||
i_pShared->hSemaphore = SHARED_SEM_NULL;
|
||||
UNUSED_ARG(l_iRes);
|
||||
}
|
||||
|
||||
if (i_pShared->pSemName)
|
||||
{
|
||||
sem_unlink(i_pShared->pSemName);
|
||||
free(i_pShared->pSemName);
|
||||
i_pShared->pSemName = NULL;
|
||||
}
|
||||
|
||||
if (i_pShared->pMemName)
|
||||
{
|
||||
free(i_pShared->pMemName);
|
||||
i_pShared->pMemName = NULL;
|
||||
}
|
||||
|
||||
if (i_pShared->pName)
|
||||
{
|
||||
free(i_pShared->pName);
|
||||
i_pShared->pName = NULL;
|
||||
}
|
||||
|
||||
i_pShared->szName = 0;
|
||||
|
||||
free(i_pShared);
|
||||
i_pShared = NULL;
|
||||
|
||||
return TRUE;
|
||||
}//Close
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//UnLink
|
||||
static tBOOL UnLink(const tXCHAR *i_pName)
|
||||
{
|
||||
tBOOL l_bReturn = TRUE;
|
||||
size_t l_szName = 0;
|
||||
char *l_pName = NULL;
|
||||
|
||||
if (NULL == i_pName)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_szName = strlen(i_pName) + SHARED_NAME_LEN;
|
||||
l_pName = (char*)malloc(l_szName);
|
||||
|
||||
if (NULL == l_pName)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
Create_Name(l_pName, l_szName, ETYPE_MUTEX, i_pName);
|
||||
if (0 != sem_unlink(l_pName))
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
}
|
||||
|
||||
Create_Name(l_pName, l_szName, ETYPE_FILE, i_pName);
|
||||
if (0 != shm_unlink(l_pName))
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
}
|
||||
|
||||
l_lblExit:
|
||||
if (l_pName)
|
||||
{
|
||||
free(l_pName);
|
||||
l_pName = NULL;
|
||||
}
|
||||
return l_bReturn;
|
||||
}//UnLink
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Create_Name
|
||||
static tBOOL Create_Name(tXCHAR *o_pName,
|
||||
size_t i_szName,
|
||||
eType i_eType,
|
||||
const tXCHAR *i_pPostfix
|
||||
)
|
||||
{
|
||||
if ( (NULL == o_pName)
|
||||
|| (16 >= i_szName)
|
||||
|| (ETYPE_MAX <= i_eType)
|
||||
|| (NULL == i_pPostfix)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
snprintf(o_pName, i_szName, SHARED_NAME_FORMAT_STRING, i_eType, getpid(), i_pPostfix);
|
||||
|
||||
return TRUE;
|
||||
}//Create_Name
|
||||
};
|
||||
|
||||
|
||||
#endif //PSHARED_H
|
||||
75
p7lib/Shared/Platforms/Linux_x86/PSharedLib.h
Normal file
75
p7lib/Shared/Platforms/Linux_x86/PSharedLib.h
Normal file
@ -0,0 +1,75 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef IPSHARED_LIB_H
|
||||
#define IPSHARED_LIB_H
|
||||
|
||||
#include "GTypes.h"
|
||||
|
||||
#include "Length.h"
|
||||
#include "PString.h"
|
||||
#include "WString.h"
|
||||
#include "SharedLib.h"
|
||||
#include "PAtomic.h"
|
||||
#include <dlfcn.h>
|
||||
|
||||
class CPSharedLib
|
||||
: public CSharedLib
|
||||
{
|
||||
protected:
|
||||
void *m_pSo;
|
||||
|
||||
public:
|
||||
CPSharedLib(const tXCHAR *i_pPath)
|
||||
: CSharedLib(i_pPath)
|
||||
, m_pSo(NULL)
|
||||
{
|
||||
m_pSo = dlopen(i_pPath, RTLD_LAZY);
|
||||
|
||||
if (m_pSo)
|
||||
{
|
||||
m_bState = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void *GetFunction(const tACHAR *i_pName)
|
||||
{
|
||||
dlerror(); /* Clear any existing error */
|
||||
|
||||
void* l_pReturn = (void*) (dlsym(m_pSo, i_pName));
|
||||
|
||||
if (NULL != dlerror())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return l_pReturn;
|
||||
}
|
||||
|
||||
virtual ~CPSharedLib()
|
||||
{
|
||||
if (m_pSo)
|
||||
{
|
||||
dlclose(m_pSo);
|
||||
m_pSo = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif //IPSHARED_LIB_H
|
||||
217
p7lib/Shared/Platforms/Linux_x86/PSignal.h
Normal file
217
p7lib/Shared/Platforms/Linux_x86/PSignal.h
Normal file
@ -0,0 +1,217 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PSIGNAL_H
|
||||
#define PSIGNAL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "signal.h"
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <features.h>
|
||||
#include "ISignal.h"
|
||||
|
||||
//Linux signal handling article:
|
||||
//http://www.linuxprogrammingblog.com/all-about-linux-signals?page=show
|
||||
|
||||
static stChContext g_stContext = {0};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Signal_Text
|
||||
static __attribute__ ((unused)) const char *ChGetSignalText(int i_iSignal, siginfo_t* i_pSigInfo)
|
||||
{
|
||||
if (i_iSignal == SIGBUS)
|
||||
{
|
||||
if (i_pSigInfo->si_code == BUS_ADRALN) { return "SIGBUS::BUS_ADRALN"; }
|
||||
else if (i_pSigInfo->si_code == BUS_ADRERR) { return "SIGBUS::BUS_ADRERR"; }
|
||||
else if (i_pSigInfo->si_code == BUS_OBJERR) { return "SIGBUS::BUS_OBJERR"; }
|
||||
else { return "SIGBUS::<unknown>"; }
|
||||
}
|
||||
else if (i_iSignal == SIGFPE)
|
||||
{
|
||||
if (i_pSigInfo->si_code == FPE_FLTDIV) { return "SIGFPE::FPE_FLTDIV"; }
|
||||
else if (i_pSigInfo->si_code == FPE_FLTINV) { return "SIGFPE::FPE_FLTINV"; }
|
||||
else if (i_pSigInfo->si_code == FPE_FLTOVF) { return "SIGFPE::FPE_FLTOVF"; }
|
||||
else if (i_pSigInfo->si_code == FPE_FLTRES) { return "SIGFPE::FPE_FLTRES"; }
|
||||
else if (i_pSigInfo->si_code == FPE_FLTSUB) { return "SIGFPE::FPE_FLTSUB"; }
|
||||
else if (i_pSigInfo->si_code == FPE_FLTUND) { return "SIGFPE::FPE_FLTUND"; }
|
||||
else if (i_pSigInfo->si_code == FPE_INTDIV) { return "SIGFPE::FPE_INTDIV"; }
|
||||
else if (i_pSigInfo->si_code == FPE_INTOVF) { return "SIGFPE::FPE_INTOVF"; }
|
||||
else { return "SIGFPE::<unknown>"; }
|
||||
}
|
||||
else if (i_iSignal == SIGILL)
|
||||
{
|
||||
if (i_pSigInfo->si_code == ILL_BADSTK) { return "SIGILL::ILL_BADSTK"; }
|
||||
else if (i_pSigInfo->si_code == ILL_COPROC) { return "SIGILL::ILL_COPROC"; }
|
||||
else if (i_pSigInfo->si_code == ILL_ILLOPN) { return "SIGILL::ILL_ILLOPN"; }
|
||||
else if (i_pSigInfo->si_code == ILL_ILLADR) { return "SIGILL::ILL_ILLADR"; }
|
||||
else if (i_pSigInfo->si_code == ILL_ILLTRP) { return "SIGILL::ILL_ILLTRP"; }
|
||||
else if (i_pSigInfo->si_code == ILL_PRVOPC) { return "SIGILL::ILL_PRVOPC"; }
|
||||
else if (i_pSigInfo->si_code == ILL_PRVREG) { return "SIGILL::ILL_PRVREG"; }
|
||||
else { return "SIGILL::<unknown>"; }
|
||||
}
|
||||
else if (i_iSignal == SIGSEGV)
|
||||
{
|
||||
if (i_pSigInfo->si_code == SEGV_MAPERR) { return "SIGSEGV::SEGV_MAPERR"; }
|
||||
else if (i_pSigInfo->si_code == SEGV_ACCERR){ return "SIGSEGV::SEGV_ACCERR"; }
|
||||
else { return "SIGSEGV::<unknown>"; }
|
||||
}
|
||||
|
||||
return "<unknown>::<unknown>";
|
||||
}//Get_Signal_Text
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChHandler
|
||||
static __attribute__ ((unused)) void ChHandler(int i_iSignal,
|
||||
siginfo_t *i_pSigInfo,
|
||||
void *i_pContext
|
||||
)
|
||||
{
|
||||
UNUSED_ARG(i_pContext);
|
||||
if (g_stContext.iProcessed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_stContext.iProcessed = 1;
|
||||
|
||||
const char *l_pText = ChGetSignalText(i_iSignal, i_pSigInfo);
|
||||
|
||||
if (g_stContext.pUserHandler)
|
||||
{
|
||||
g_stContext.pUserHandler((eCrashCode)(eCrashSignal + i_iSignal), l_pText, g_stContext.pUserContext);
|
||||
}
|
||||
|
||||
printf("Process has been terminated by signal {%s}\n", l_pText);
|
||||
}//ChHandler
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChInstall
|
||||
static __attribute__ ((unused)) tBOOL ChInstallPrivate()
|
||||
{
|
||||
struct sigaction l_sSignal;
|
||||
struct sigaction l_sSignalPipe;
|
||||
tBOOL l_bReturn = TRUE;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// installing signal handling ...
|
||||
memset(&l_sSignalPipe, 0, sizeof(l_sSignalPipe));
|
||||
memset(&l_sSignal, 0, sizeof(l_sSignal));
|
||||
|
||||
//remove SIGPIPE signal, should be ignored
|
||||
l_sSignalPipe.sa_handler = SIG_IGN;
|
||||
sigemptyset(&l_sSignalPipe.sa_mask);
|
||||
l_bReturn = (sigaction(SIGPIPE, &l_sSignalPipe, NULL) == 0);
|
||||
|
||||
l_sSignal.sa_flags = SA_RESETHAND | SA_SIGINFO;
|
||||
l_sSignal.sa_sigaction = &ChHandler;
|
||||
sigemptyset(&l_sSignal.sa_mask);
|
||||
|
||||
l_bReturn &= (sigaction(SIGILL, &l_sSignal, NULL) == 0);
|
||||
l_bReturn &= (sigaction(SIGABRT, &l_sSignal, NULL) == 0);
|
||||
l_bReturn &= (sigaction(SIGFPE, &l_sSignal, NULL) == 0);
|
||||
l_bReturn &= (sigaction(SIGBUS, &l_sSignal, NULL) == 0);
|
||||
l_bReturn &= (sigaction(SIGSEGV, &l_sSignal, NULL) == 0);
|
||||
|
||||
if (!l_bReturn)
|
||||
{
|
||||
printf("ERROR: can't initialize signal handler");
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}//ChInstall
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChInstall
|
||||
static __attribute__ ((unused)) tBOOL ChInstall()
|
||||
{
|
||||
tBOOL l_bReturn = TRUE;
|
||||
|
||||
if (g_stContext.iInstalled)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(&g_stContext, 0, sizeof(g_stContext));
|
||||
g_stContext.iProcessed = 0;
|
||||
|
||||
l_bReturn = ChInstallPrivate();
|
||||
|
||||
if (l_bReturn)
|
||||
{
|
||||
g_stContext.iInstalled = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ERROR: can't initialize signal handler");
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}//ChInstall
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChSetHandler
|
||||
static __attribute__ ((unused)) tBOOL ChSetHandler(fnCrashHandler i_fnHandler)
|
||||
{
|
||||
if (!g_stContext.iInstalled)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_stContext.pUserHandler = i_fnHandler;
|
||||
|
||||
return TRUE;
|
||||
}//ChSetHandler
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChSetContext
|
||||
static __attribute__ ((unused)) tBOOL ChSetContext(void *i_pContext)
|
||||
{
|
||||
if (!g_stContext.iInstalled)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_stContext.pUserContext = i_pContext;
|
||||
|
||||
return TRUE;
|
||||
}//ChSetContext
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChUnInstall
|
||||
static __attribute__ ((unused)) tBOOL ChUnInstall()
|
||||
{
|
||||
return TRUE;
|
||||
}//ChUnInstall
|
||||
|
||||
#endif //PSIGNAL_H
|
||||
237
p7lib/Shared/Platforms/Linux_x86/PSocket.h
Normal file
237
p7lib/Shared/Platforms/Linux_x86/PSocket.h
Normal file
@ -0,0 +1,237 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PSOCKET_H
|
||||
#define PSOCKET_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <ifaddrs.h>
|
||||
#include "AList.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#ifdef __ARM_ARCH_5TEJ__
|
||||
#define SERVER_RECV_BUFFER_SIZE (0x200000) //2mb
|
||||
#define SERVER_SEND_BUFFER_SIZE (0x40000) //256kb
|
||||
|
||||
#define CLIENT_RECV_BUFFER_SIZE (0x4000) //16 kb
|
||||
#define CLIENT_SEND_BUFFER_SIZE (0x10000) //64 kb
|
||||
#else
|
||||
#define SERVER_RECV_BUFFER_SIZE (0x200000) //2mb
|
||||
#define SERVER_SEND_BUFFER_SIZE (0x40000) //256kb
|
||||
|
||||
#define CLIENT_RECV_BUFFER_SIZE (0x40000) //256 kb
|
||||
#define CLIENT_SEND_BUFFER_SIZE (0x40000) //256 kb
|
||||
#endif
|
||||
|
||||
typedef int tSOCKET;
|
||||
//typedef SOCKET tSOCKET;
|
||||
|
||||
typedef socklen_t tADDR_LEN;
|
||||
//typedef int tADDR_LEN;
|
||||
|
||||
typedef addrinfo tADDR_INFO;
|
||||
//typedef addrinfoW tADDR_INFO;
|
||||
|
||||
|
||||
#define INVALID_SOCKET_VAL (-1)
|
||||
//(INVALID_SOCKET)
|
||||
|
||||
#define CONNECTION_IN_PROGRESS (EINPROGRESS)
|
||||
//(WSAEWOULDBLOCK)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define CLOSE_SOCKET(i_Socket) close(i_Socket)
|
||||
//closesocket(m_hSocket);
|
||||
|
||||
|
||||
#define GET_SOCKET_ERROR() errno
|
||||
//WSAGetLastError();
|
||||
|
||||
#define SOCKET_ERROR (-1)
|
||||
|
||||
#define GET_ADDR_INFO(i_Node, i_Service, i_Hints, o_Res) getaddrinfo(i_Node,\
|
||||
i_Service,\
|
||||
i_Hints,\
|
||||
o_Res)
|
||||
//GetAddrInfoW
|
||||
|
||||
#define FREE_ADDR_INFO(i_Info) freeaddrinfo(i_Info)
|
||||
//FreeAddrInfoW
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//WSA_Init
|
||||
static __attribute__ ((unused)) tBOOL WSA_Init()
|
||||
{
|
||||
return TRUE;
|
||||
|
||||
//WSADATA l_tWSA;
|
||||
//
|
||||
//if (0 != WSAStartup(MAKEWORD(1,1), &l_tWSA))
|
||||
//{
|
||||
// return FALSE;
|
||||
//}
|
||||
//return TRUE;
|
||||
}//WSA_Init
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//WSA_UnInit
|
||||
static __attribute__ ((unused)) void WSA_UnInit()
|
||||
{
|
||||
//WSACleanup();
|
||||
}//WSA_UnInit
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PEnumIps
|
||||
static __attribute__ ((unused)) tBOOL PEnumIps(CBList<sockaddr_storage*> *io_pList)
|
||||
{
|
||||
if (!io_pList)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
io_pList->Clear(TRUE);
|
||||
|
||||
struct ifaddrs *l_pIfAddr = NULL;
|
||||
|
||||
if (-1 == getifaddrs(&l_pIfAddr))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (struct ifaddrs *l_pAddr = l_pIfAddr; l_pAddr != NULL; l_pAddr = l_pAddr->ifa_next)
|
||||
{
|
||||
if ( (l_pAddr->ifa_addr == NULL)
|
||||
|| ( (AF_INET != l_pAddr->ifa_addr->sa_family)
|
||||
&& (AF_INET6 != l_pAddr->ifa_addr->sa_family)
|
||||
)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sockaddr_storage *l_pNew = new sockaddr_storage;
|
||||
if (AF_INET == l_pAddr->ifa_addr->sa_family)
|
||||
{
|
||||
memcpy(l_pNew, l_pAddr->ifa_addr, sizeof(sockaddr_in));
|
||||
}
|
||||
else if (AF_INET6 == l_pAddr->ifa_addr->sa_family)
|
||||
{
|
||||
memcpy(l_pNew, l_pAddr->ifa_addr, sizeof(sockaddr_in6));
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(l_pNew, 0, sizeof(sockaddr_storage));
|
||||
}
|
||||
|
||||
io_pList->Add_After(NULL, l_pNew);
|
||||
}
|
||||
|
||||
freeifaddrs(l_pIfAddr);
|
||||
|
||||
return TRUE;
|
||||
}//PEnumIps
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Print_SAddr
|
||||
static __attribute__ ((unused)) tBOOL Print_SAddr(sockaddr *i_pAddress, XCHAR *o_pIP, tUINT32 i_dwLen)
|
||||
{
|
||||
tBOOL l_bReturn = FALSE;
|
||||
|
||||
if ( (NULL == i_pAddress)
|
||||
|| (NULL == o_pIP)
|
||||
|| (15 >= i_dwLen)
|
||||
)
|
||||
{
|
||||
return l_bReturn;
|
||||
}
|
||||
|
||||
if (AF_INET6 == i_pAddress->sa_family)
|
||||
{
|
||||
if (NULL != inet_ntop(i_pAddress->sa_family,
|
||||
&((sockaddr_in6*)i_pAddress)->sin6_addr,
|
||||
o_pIP,
|
||||
i_dwLen
|
||||
)
|
||||
)
|
||||
{
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
}
|
||||
else if (AF_INET == i_pAddress->sa_family)
|
||||
{
|
||||
if (NULL != inet_ntop(i_pAddress->sa_family,
|
||||
&((sockaddr_in*)i_pAddress)->sin_addr,
|
||||
o_pIP,
|
||||
i_dwLen
|
||||
)
|
||||
)
|
||||
{
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
//WSAAddressToString(i_pAddress,
|
||||
// m_dwAddress_Size,
|
||||
// NULL,
|
||||
// l_pIP,
|
||||
// &l_dwSize);
|
||||
|
||||
return l_bReturn;
|
||||
}//Print_SAddr
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Disable_PortUnreachable_ICMP
|
||||
static __attribute__ ((unused)) tBOOL Disable_PortUnreachable_ICMP(tSOCKET i_hSocket)
|
||||
{
|
||||
UNUSED_ARG(i_hSocket);
|
||||
|
||||
//tUINT32 l_dwBytesReturned = 0;
|
||||
//tBOOL l_bNewBehavior = FALSE;
|
||||
//tUINT32 l_dwStatus = 0;
|
||||
//
|
||||
//
|
||||
//l_dwStatus = WSAIoctl(m_hSocket,
|
||||
// SIO_UDP_CONNRESET,
|
||||
// &l_bNewBehavior,
|
||||
// sizeof(l_bNewBehavior),
|
||||
// NULL,
|
||||
// 0,
|
||||
// &l_dwBytesReturned,
|
||||
// NULL,
|
||||
// NULL
|
||||
// );
|
||||
//return (SOCKET_ERROR == l_dwStatus) ? FALSE : TRUE;
|
||||
|
||||
//don't know how to do it under Linux yet.
|
||||
return TRUE;
|
||||
}//Disable_PortUnreachable_ICMP
|
||||
|
||||
#endif //PSOCKET_H
|
||||
245
p7lib/Shared/Platforms/Linux_x86/PString.h
Normal file
245
p7lib/Shared/Platforms/Linux_x86/PString.h
Normal file
@ -0,0 +1,245 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PSTRING_H
|
||||
#define PSTRING_H
|
||||
|
||||
#if !defined(PRINTF)
|
||||
#if defined(UTF8_ENCODING)
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) wprintf(__VA_ARGS__)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "UTF.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PStrLen
|
||||
static __attribute__ ((unused)) tUINT32 PStrLen(const tXCHAR *i_pText)
|
||||
{
|
||||
return strlen(i_pText);
|
||||
}//PStrLen
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PStrCpy
|
||||
static __attribute__ ((unused)) tXCHAR* PStrCpy(tXCHAR *i_pDst,
|
||||
size_t i_szDst,
|
||||
const tXCHAR *i_pSrc)
|
||||
{
|
||||
UNUSED_ARG(i_szDst);
|
||||
return strcpy(i_pDst, i_pSrc);
|
||||
}//PStrLen
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PWStrCpy
|
||||
static inline tWCHAR *PWStrCpy(tWCHAR *i_pDst,
|
||||
size_t i_szDst,
|
||||
const tWCHAR *i_pSrc
|
||||
)
|
||||
{
|
||||
while ( (*i_pSrc)
|
||||
&& (1 < i_szDst)
|
||||
)
|
||||
{
|
||||
*i_pDst = *i_pSrc;
|
||||
i_pDst++; i_pSrc++;
|
||||
i_szDst--;
|
||||
}
|
||||
|
||||
*i_pDst = 0;
|
||||
|
||||
return i_pDst;
|
||||
}//PStrLen
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PStrCpy
|
||||
static __attribute__ ((unused)) tXCHAR* PStrNCpy(tXCHAR *i_pDst,
|
||||
size_t i_szDst,
|
||||
const tXCHAR *i_pSrc,
|
||||
size_t i_pSrcMaxCount
|
||||
)
|
||||
{
|
||||
UNUSED_ARG(i_szDst);
|
||||
strncpy((char*)i_pDst, (char*)i_pSrc, i_pSrcMaxCount);
|
||||
return i_pDst;
|
||||
}//PStrLen
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PStrNCmp
|
||||
static __attribute__ ((unused)) tINT32 PStrNCmp(const tXCHAR *i_pS1,
|
||||
const tXCHAR *i_pS2,
|
||||
size_t i_szLen
|
||||
)
|
||||
{
|
||||
return strncmp(i_pS1, i_pS2, i_szLen);
|
||||
}//PStrNCmp
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PStrNCmp
|
||||
static __attribute__ ((unused)) tINT32 PStrNiCmp(const tXCHAR *i_pS1,
|
||||
const tXCHAR *i_pS2,
|
||||
size_t i_szLen
|
||||
)
|
||||
{
|
||||
return strncasecmp(i_pS1, i_pS2, i_szLen);
|
||||
}//PStrNCmp
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PStrNCmp
|
||||
static __attribute__ ((unused)) tINT32 PStrICmp(const tXCHAR *i_pS1,
|
||||
const tXCHAR *i_pS2
|
||||
)
|
||||
{
|
||||
return strcasecmp(i_pS1, i_pS2);
|
||||
}//PStrNCmp
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PStrCmp
|
||||
static __attribute__ ((unused)) tINT32 PStrCmp(const tXCHAR *i_pS1,
|
||||
const tXCHAR *i_pS2
|
||||
)
|
||||
{
|
||||
return strcmp(i_pS1, i_pS2);
|
||||
}//PStrCmp
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PStrToInt
|
||||
static __attribute__ ((unused)) tINT32 PStrToInt(const tXCHAR *i_pS1)
|
||||
{
|
||||
return atoi(i_pS1);
|
||||
}//PStrToInt
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PUStrLen
|
||||
static __attribute__ ((unused)) tUINT32 PUStrLen(const tXCHAR *i_pText)
|
||||
{
|
||||
return Get_UTF8_Length(i_pText);
|
||||
}//PUStrLen
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PUStrCpy
|
||||
static __attribute__ ((unused)) void PUStrCpy(tWCHAR *i_pDst,
|
||||
tUINT32 i_dwMax_Len,
|
||||
const tXCHAR *i_pSrc)
|
||||
{
|
||||
Convert_UTF8_To_UTF16(i_pSrc, i_pDst, i_dwMax_Len);
|
||||
//wcscpy_s(i_pDst, i_dwMax_Len, i_pSrc);
|
||||
}//PUStrCpy
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PSPrint
|
||||
static __attribute__ ((unused)) tINT32 PSPrint(tXCHAR *o_pBuffer,
|
||||
size_t i_szBuffer,
|
||||
const tXCHAR *i_pFormat,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list l_pVA;
|
||||
int l_iReturn = 0;
|
||||
|
||||
va_start(l_pVA, i_pFormat);
|
||||
|
||||
l_iReturn = vsnprintf((char*)o_pBuffer,
|
||||
i_szBuffer,
|
||||
(char*)i_pFormat,
|
||||
l_pVA);
|
||||
|
||||
va_end(l_pVA);
|
||||
|
||||
return (tINT32)l_iReturn;
|
||||
}//PSPrint
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrDub
|
||||
static __attribute__ ((unused)) tXCHAR *PStrDub(const tXCHAR *i_pStr)
|
||||
{
|
||||
return strdup(i_pStr);
|
||||
}//PStrDub
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrFreeDub
|
||||
static __attribute__ ((unused)) void PStrFreeDub(tXCHAR *i_pStr)
|
||||
{
|
||||
free(i_pStr);
|
||||
}//PStrFreeDub
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrChr
|
||||
static const __attribute__ ((unused)) tXCHAR *PStrChr(const tXCHAR * i_pStr, tXCHAR i_cCh)
|
||||
{
|
||||
return strchr(i_pStr, i_cCh);
|
||||
}//PStrChr
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrChr
|
||||
static __attribute__ ((unused)) tXCHAR *PStrChr(tXCHAR * i_pStr, tXCHAR i_cCh)
|
||||
{
|
||||
return strchr(i_pStr, i_cCh);
|
||||
}//PStrChr
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrrChr
|
||||
static const __attribute__ ((unused)) tXCHAR *PStrrChr(const tXCHAR * i_pStr, const tXCHAR i_cCh)
|
||||
{
|
||||
return strrchr(i_pStr, i_cCh);
|
||||
}//PStrrChr
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrrChr
|
||||
static __attribute__ ((unused)) tXCHAR *PStrrChr(tXCHAR * i_pStr, tXCHAR i_cCh)
|
||||
{
|
||||
return strrchr(i_pStr, i_cCh);
|
||||
}//PStrrChr
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PVsnprintf
|
||||
static __attribute__ ((unused)) int PVsnprintf(tXCHAR *o_pBuffer,
|
||||
size_t i_szBuffer,
|
||||
const tXCHAR *i_pFormat,
|
||||
va_list i_pArgs)
|
||||
{
|
||||
return vsnprintf(o_pBuffer, i_szBuffer, i_pFormat, i_pArgs);
|
||||
}//PVsnprintf
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrScan
|
||||
#define PStrScan(i_pBuffer, i_pFormat, ...) sscanf(i_pBuffer, i_pFormat, __VA_ARGS__)
|
||||
|
||||
|
||||
#endif //PSTRING_H
|
||||
100
p7lib/Shared/Platforms/Linux_x86/PSystem.h
Normal file
100
p7lib/Shared/Platforms/Linux_x86/PSystem.h
Normal file
@ -0,0 +1,100 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PSYSTEM_H
|
||||
#define PSYSTEM_H
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
class CSys
|
||||
{
|
||||
public:
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Host_Name
|
||||
static tBOOL Get_Host_Name(tWCHAR *o_pName, size_t i_szName)
|
||||
{
|
||||
const size_t l_szName = 256;
|
||||
char l_pName[l_szName];
|
||||
|
||||
if (0 == gethostname(l_pName, l_szName))
|
||||
{
|
||||
//If the null-terminated hostname is too large to fit, then the name
|
||||
//is truncated, and no error is returned (but see NOTES below).
|
||||
//POSIX.1-2001 says that if such truncation occurs, then it is
|
||||
//unspecified whether the returned buffer includes a terminating
|
||||
//null byte.
|
||||
l_pName[l_szName-1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(l_pName, "Unknown:Error");
|
||||
}
|
||||
|
||||
Convert_UTF8_To_UTF16(l_pName, o_pName, i_szName);
|
||||
return TRUE;
|
||||
}//Get_Host_Name
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Host_Name
|
||||
static tBOOL Get_Host_Name(tACHAR *o_pName, size_t i_szName)
|
||||
{
|
||||
if (0 == gethostname(o_pName, i_szName))
|
||||
{
|
||||
//If the null-terminated hostname is too large to fit, then the name
|
||||
//is truncated, and no error is returned (but see NOTES below).
|
||||
//POSIX.1-2001 says that if such truncation occurs, then it is
|
||||
//unspecified whether the returned buffer includes a terminating
|
||||
//null byte.
|
||||
o_pName[i_szName-1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(o_pName, "Unknown:Error");
|
||||
}
|
||||
return TRUE;
|
||||
}//Get_Host_Name
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//Get_DateTime
|
||||
static tBOOL Get_DateTime(tUINT32 &o_rYear,
|
||||
tUINT32 &o_rMonth,
|
||||
tUINT32 &o_rDay,
|
||||
tUINT32 &o_rHour,
|
||||
tUINT32 &o_rMinute,
|
||||
tUINT32 &o_rSecond,
|
||||
tUINT32 &o_rmSec
|
||||
)
|
||||
{
|
||||
time_t l_sTime = time(NULL);
|
||||
struct tm l_sTM = *localtime(&l_sTime);
|
||||
|
||||
o_rYear = (uint32_t)(l_sTM.tm_year + 1900);
|
||||
o_rMonth = (uint32_t)(l_sTM.tm_mon + 1);
|
||||
o_rDay = (uint32_t)l_sTM.tm_mday;
|
||||
o_rHour = (uint32_t)l_sTM.tm_hour;
|
||||
o_rMinute = (uint32_t)l_sTM.tm_min;
|
||||
o_rSecond = (uint32_t)l_sTM.tm_sec;
|
||||
o_rmSec = 0;
|
||||
|
||||
return TRUE;
|
||||
}//Get_Host_Name
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //PSYSTEM_H
|
||||
110
p7lib/Shared/Platforms/Linux_x86/PThreadShell.h
Normal file
110
p7lib/Shared/Platforms/Linux_x86/PThreadShell.h
Normal file
@ -0,0 +1,110 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PTHREADSHELL_H
|
||||
#define PTHREADSHELL_H
|
||||
|
||||
|
||||
#define THSHELL_CALL_TYPE
|
||||
#define THSHELL_RET_TYPE void*
|
||||
|
||||
#define THSHELL_RET_OK NULL
|
||||
#define THSHELL_RET_NOK 0xDEAD
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class CThShell
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Base types
|
||||
typedef pthread_t tTHREAD;
|
||||
typedef THSHELL_RET_TYPE (THSHELL_CALL_TYPE *tpThreadProc)(void *i_pParameter);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Create
|
||||
static tBOOL Create(tpThreadProc i_pThread_Proc,
|
||||
void *i_pPrm,
|
||||
tTHREAD *o_pThread,
|
||||
const tXCHAR *i_pName
|
||||
)
|
||||
{
|
||||
UNUSED_ARG(i_pName);
|
||||
if ( ( NULL == i_pThread_Proc )
|
||||
|| ( NULL == o_pThread )
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*o_pThread = 0;
|
||||
|
||||
pthread_attr_t l_sAttr;
|
||||
int l_iResult = -1;
|
||||
|
||||
pthread_attr_init(&l_sAttr);
|
||||
pthread_attr_setdetachstate(&l_sAttr, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
l_iResult = pthread_create(o_pThread, &l_sAttr, i_pThread_Proc, i_pPrm);
|
||||
|
||||
pthread_attr_destroy(&l_sAttr);
|
||||
|
||||
#ifdef __USE_GNU
|
||||
//if ( (0 == l_iResult)
|
||||
// && (i_pName)
|
||||
// )
|
||||
//{
|
||||
// pthread_setname_np(pthread_self(), i_pName);
|
||||
//}
|
||||
#endif
|
||||
|
||||
return (0 == l_iResult) ? TRUE : FALSE;
|
||||
}//Create
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Cleanup
|
||||
static void Cleanup()
|
||||
{
|
||||
}//Thread_Cleanup
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Close
|
||||
static tBOOL Close(tTHREAD i_hThread, tUINT32 i_dwTimeOut)
|
||||
{
|
||||
UNUSED_ARG(i_dwTimeOut);
|
||||
|
||||
void *l_pRet = THSHELL_RET_OK;
|
||||
|
||||
tUINT32 l_iResult = pthread_join(i_hThread, &l_pRet);
|
||||
|
||||
return (( 0 == l_iResult ) && (THSHELL_RET_OK == l_pRet)) ? TRUE : FALSE;
|
||||
}//Close
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Sleep
|
||||
static void Sleep(tUINT32 i_dwTimeOut)
|
||||
{
|
||||
usleep(1000 * i_dwTimeOut);
|
||||
}//Sleep
|
||||
|
||||
};
|
||||
|
||||
#endif //PTHREADSHELL_H
|
||||
241
p7lib/Shared/Platforms/Linux_x86/PTime.h
Normal file
241
p7lib/Shared/Platforms/Linux_x86/PTime.h
Normal file
@ -0,0 +1,241 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PTIME_H
|
||||
#define PTIME_H
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
//time offset from January 1, 1601 to January 1, 1970, resolution 100ns
|
||||
#define TIME_OFFSET_1601_1970 (116444736000000000ULL)
|
||||
|
||||
#define TIME_HRS_100NS 36000000000ull
|
||||
#define TIME_MIN_100NS 600000000ull
|
||||
#define TIME_SEC_100NS 10000000ull
|
||||
#define TIME_MLSC_100NS 10000ull
|
||||
#define TIME_MCSC_100NS 10ull
|
||||
|
||||
#define TIME_ZONE_AVALIABLE
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetTickCount
|
||||
static __attribute__ ((unused)) tUINT32 GetTickCount()
|
||||
{
|
||||
tUINT64 l_qwReturn; //Warn:without initialization !
|
||||
//timeval l_sTime;
|
||||
//gettimeofday(&l_sTime, NULL);
|
||||
|
||||
struct timespec l_sTime = {0, 0};
|
||||
clock_gettime(CLOCK_MONOTONIC, &l_sTime);
|
||||
|
||||
l_qwReturn = l_sTime.tv_sec;
|
||||
l_qwReturn *= 1000;
|
||||
l_qwReturn += l_sTime.tv_nsec/1000000;
|
||||
|
||||
return (tUINT32)l_qwReturn;
|
||||
}//GetTickCount
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetPerformanceCounter
|
||||
static __attribute__ ((unused)) tUINT64 GetPerformanceCounter()
|
||||
{
|
||||
tUINT64 l_qwReturn = 0;
|
||||
struct timespec l_sTime = {0, 0};
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &l_sTime);
|
||||
|
||||
l_qwReturn = (tUINT64)(l_sTime.tv_sec) * 10000000;
|
||||
l_qwReturn += (tUINT64)(l_sTime.tv_nsec) / 100;
|
||||
|
||||
return l_qwReturn;
|
||||
}//GetPerformanceCounter
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetPerformanceFrequency
|
||||
static __attribute__ ((unused)) tUINT64 GetPerformanceFrequency()
|
||||
{
|
||||
return 10000000; //100 nano second
|
||||
}//GetPerformanceFrequency
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//UnpackLocalTime
|
||||
//convert a 64-bit value of 100-nanosecond intervals since January 1, 1601 (UTC)
|
||||
//to readable form
|
||||
static __attribute__ ((unused)) void UnpackLocalTime(tUINT64 i_qwTime,
|
||||
tUINT32 &o_rYear,
|
||||
tUINT32 &o_rMonth,
|
||||
tUINT32 &o_rDay,
|
||||
tUINT32 &o_rHour,
|
||||
tUINT32 &o_rMinutes,
|
||||
tUINT32 &o_rSeconds,
|
||||
tUINT32 &o_rMilliseconds,
|
||||
tUINT32 &o_rMicroseconds,
|
||||
tUINT32 &o_rNanoseconds
|
||||
)
|
||||
{
|
||||
tUINT32 l_dwReminder = i_qwTime % TIME_MLSC_100NS; //micro & 100xNanoseconds
|
||||
tUINT32 l_dwNano = i_qwTime % 10;
|
||||
tUINT32 l_dwMicro = l_dwReminder / 10;
|
||||
|
||||
i_qwTime -= l_dwReminder;
|
||||
|
||||
tUINT32 l_dwMilli = (i_qwTime % TIME_SEC_100NS) / TIME_MLSC_100NS;
|
||||
|
||||
i_qwTime -= TIME_OFFSET_1601_1970;
|
||||
|
||||
time_t l_llTime = i_qwTime / TIME_SEC_100NS;
|
||||
tm *l_pTime = localtime(&l_llTime);
|
||||
if (l_pTime)
|
||||
{
|
||||
o_rYear = 1900 + l_pTime->tm_year;
|
||||
o_rMonth = 1 + l_pTime->tm_mon;
|
||||
o_rDay = l_pTime->tm_mday;
|
||||
o_rHour = l_pTime->tm_hour;
|
||||
o_rMinutes = l_pTime->tm_min;
|
||||
o_rSeconds = l_pTime->tm_sec;
|
||||
o_rMilliseconds = l_dwMilli;
|
||||
o_rMicroseconds = l_dwMicro;
|
||||
o_rNanoseconds = l_dwNano;
|
||||
}
|
||||
else
|
||||
{
|
||||
o_rYear = 0;
|
||||
o_rMonth = 0;
|
||||
o_rDay = 0;
|
||||
o_rHour = 0;
|
||||
o_rMinutes = 0;
|
||||
o_rSeconds = 0;
|
||||
o_rMilliseconds = l_dwMilli;
|
||||
o_rMicroseconds = l_dwMicro;
|
||||
o_rNanoseconds = l_dwNano;
|
||||
}
|
||||
}//UnpackLocalTime
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PackLocalTime
|
||||
//convert date & time to 64-bit value of 100-nanosecond intervals since January 1, 1601 (UTC)
|
||||
static __attribute__ ((unused)) tUINT64 PackLocalTime(tUINT32 i_uiYear,
|
||||
tUINT32 i_uiMonth,
|
||||
tUINT32 i_uiDay,
|
||||
tUINT32 i_uiHour,
|
||||
tUINT32 i_uiMinutes,
|
||||
tUINT32 i_uiSeconds,
|
||||
tUINT32 i_uiMilliseconds,
|
||||
tUINT32 i_uiMicroseconds,
|
||||
tUINT32 i_uiNanoseconds
|
||||
)
|
||||
{
|
||||
tm l_stTime = {0};
|
||||
l_stTime.tm_year = (int)i_uiYear - 1900;
|
||||
l_stTime.tm_mon = (int)i_uiMonth - 1;
|
||||
l_stTime.tm_mday = (int)i_uiDay;
|
||||
l_stTime.tm_hour = (int)i_uiHour;
|
||||
l_stTime.tm_min = (int)i_uiMinutes;
|
||||
l_stTime.tm_sec = (int)i_uiSeconds;
|
||||
l_stTime.tm_isdst = -1;
|
||||
|
||||
time_t l_qwTimeT = mktime(&l_stTime);
|
||||
|
||||
tUINT64 l_qwReturn = l_qwTimeT * TIME_SEC_100NS;
|
||||
l_qwReturn += TIME_OFFSET_1601_1970;
|
||||
|
||||
l_qwReturn += (i_uiMilliseconds * TIME_MLSC_100NS) + (i_uiMicroseconds * 10ull) + (i_uiNanoseconds / 100ull);
|
||||
|
||||
return l_qwReturn;
|
||||
}//PackLocalTime
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetSecondOfDay
|
||||
static inline tUINT32 GetSecondOfDay()
|
||||
{
|
||||
time_t l_llRawtime;
|
||||
time(&l_llRawtime);
|
||||
tm *l_pTime = localtime(&l_llRawtime);
|
||||
|
||||
if (l_pTime)
|
||||
{
|
||||
return 3600 * (tUINT32)l_pTime->tm_hour + (tUINT32)l_pTime->tm_min * 60 + l_pTime->tm_sec;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}//GetSecondOfDay
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetEpochTime
|
||||
//return a 64-bit value of 100-nanosecond intervals since January 1, 1601 (UTC).
|
||||
static __attribute__ ((unused)) void GetEpochTime(tUINT32 *o_pHi, tUINT32 *o_pLow)
|
||||
{
|
||||
tUINT64 l_qwResult = 0;
|
||||
struct timeval l_sTime = {0, 0};
|
||||
|
||||
gettimeofday(&l_sTime, NULL);
|
||||
|
||||
l_qwResult = (tUINT64)(l_sTime.tv_sec) * TIME_SEC_100NS;
|
||||
l_qwResult += (tUINT64)(l_sTime.tv_usec) * TIME_MCSC_100NS;
|
||||
l_qwResult += TIME_OFFSET_1601_1970;
|
||||
|
||||
if (o_pHi)
|
||||
{
|
||||
*o_pHi = (tUINT32)(l_qwResult >> 32);
|
||||
}
|
||||
|
||||
if (o_pLow)
|
||||
{
|
||||
*o_pLow = (tUINT32)(l_qwResult & 0xFFFFFFFF);
|
||||
}
|
||||
}//GetEpochTime
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetEpochTime
|
||||
//return a 64-bit value of 100-nanosecond intervals since January 1, 1601 (UTC).
|
||||
static inline tUINT64 GetEpochTime()
|
||||
{
|
||||
tUINT32 dwHighDateTime = 0, dwLowDateTime = 0;
|
||||
|
||||
GetEpochTime(&dwHighDateTime, &dwLowDateTime);
|
||||
|
||||
return (((tUINT64)dwHighDateTime) << 32ull) + (tUINT64)dwLowDateTime;
|
||||
}//GetEpochTime
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetUtcOffsetSeconds
|
||||
//return UTC0 offset in seconds
|
||||
static inline tINT32 GetUtcOffsetSeconds()
|
||||
{
|
||||
#if defined(TIME_ZONE_AVALIABLE)
|
||||
time_t l_sTime = time(NULL);
|
||||
struct tm l_stLocal = {0};
|
||||
|
||||
tzset();
|
||||
localtime_r(&l_sTime, &l_stLocal);
|
||||
|
||||
return l_stLocal.tm_gmtoff;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif //PTIME_H
|
||||
27
p7lib/Shared/Platforms/Windows_x86/PAtomic.h
Normal file
27
p7lib/Shared/Platforms/Windows_x86/PAtomic.h
Normal file
@ -0,0 +1,27 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define ATOMIC_ADD(io_Val, i_Add) InterlockedExchangeAdd((LONG volatile *)io_Val, i_Add)
|
||||
#define ATOMIC_SUB(io_Val, i_Sub) InterlockedExchangeAdd((LONG volatile *)io_Val, -((tINT32)i_Sub))
|
||||
#define ATOMIC_SET(io_Var, i_Val) InterlockedExchange((LONG volatile *)io_Var, (LONG)i_Val)
|
||||
|
||||
#define ATOMIC_INC(io_Val) InterlockedIncrement((LONG volatile *)io_Val)
|
||||
#define ATOMIC_DEC(io_Val) InterlockedDecrement((LONG volatile *)io_Val)
|
||||
118
p7lib/Shared/Platforms/Windows_x86/PCRC32.h
Normal file
118
p7lib/Shared/Platforms/Windows_x86/PCRC32.h
Normal file
@ -0,0 +1,118 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
static inline tUINT32 Get_CRC32(tUINT8 *i_pData, size_t i_szCount)
|
||||
{
|
||||
tUINT32 l_dwResult = 0xFFFFFFFF;
|
||||
|
||||
if ( (NULL == i_pData)
|
||||
|| (0 >= i_szCount)
|
||||
)
|
||||
{
|
||||
return l_dwResult;
|
||||
}
|
||||
|
||||
|
||||
#if defined(GTX64) || defined(__linux__) || !defined(_MSC_VER)
|
||||
|
||||
for (size_t l_szI = 0; l_szI < i_szCount; l_szI ++)
|
||||
{
|
||||
l_dwResult = g_pCRC32_Table[(l_dwResult ^ i_pData[l_szI]) & 0xFF ] ^ (l_dwResult >> 8);
|
||||
}
|
||||
|
||||
//Suppress warning that this is not used
|
||||
(void)g_ppCRC32_Table;
|
||||
|
||||
#else
|
||||
|
||||
// Register use:
|
||||
// eax - CRC32 value
|
||||
// ebx - a lot of things
|
||||
// ecx - CRC32 value
|
||||
// edx - address of end of buffer
|
||||
// esi - address of start of buffer
|
||||
// edi - CRC32 table
|
||||
__asm
|
||||
{
|
||||
// Save the esi and edi registers
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov ecx, l_dwResult // load dwCrc32
|
||||
|
||||
mov edi, g_ppCRC32_Table // Load the CRC32 table
|
||||
|
||||
mov esi, i_pData // Load buffer
|
||||
mov ebx, i_szCount // Load dwBytesRead
|
||||
lea edx, [esi + ebx] // Calculate the end of the buffer
|
||||
|
||||
crc32loop:
|
||||
xor eax, eax // Clear the eax register
|
||||
mov bl, byte ptr [esi] // Load the current source byte
|
||||
|
||||
mov al, cl // Copy crc value into eax
|
||||
inc esi // Advance the source pointer
|
||||
|
||||
xor al, bl // Create the index into the CRC32 table
|
||||
shr ecx, 8
|
||||
|
||||
mov ebx, [edi + eax * 4] // Get the value out of the table
|
||||
xor ecx, ebx // xor with the current byte
|
||||
|
||||
cmp edx, esi // Have we reached the end of the buffer?
|
||||
jne crc32loop
|
||||
|
||||
// Restore the edi and esi registers
|
||||
pop edi
|
||||
pop esi
|
||||
|
||||
lea eax, l_dwResult // Load the pointer to dwCrc32
|
||||
mov [eax], ecx // Write the result
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return l_dwResult;
|
||||
}
|
||||
|
||||
|
||||
// #if defined(_WIN32) || defined(_WIN64)
|
||||
// tUINT32 Get_CRC32_SSE4(tUINT8 *i_pData, tUINT32 i_szCount)
|
||||
// {
|
||||
// tUINT32 l_dwCount = i_szCount >> 2; //count of DWORDs
|
||||
// tUINT32 l_dwResult = 0x0;
|
||||
//
|
||||
// while (l_dwCount--)
|
||||
// {
|
||||
// l_dwResult = _mm_crc32_u32(l_dwResult, *(DWORD*)i_pData);
|
||||
// i_pData += 4;
|
||||
// }
|
||||
//
|
||||
// l_dwCount = i_szCount & 0x3; //bytes count at the tail
|
||||
//
|
||||
// while (l_dwCount--)
|
||||
// {
|
||||
// l_dwResult = _mm_crc32_u8(l_dwResult, *i_pData);
|
||||
// i_pData ++;
|
||||
// }
|
||||
//
|
||||
// return l_dwResult;
|
||||
// }
|
||||
// #endif
|
||||
598
p7lib/Shared/Platforms/Windows_x86/PConsole.h
Normal file
598
p7lib/Shared/Platforms/Windows_x86/PConsole.h
Normal file
@ -0,0 +1,598 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include <conio.h>
|
||||
#include "AList.h"
|
||||
#include "PString.h"
|
||||
#include "IConsole.h"
|
||||
#include "RBTree.h"
|
||||
|
||||
#pragma warning( disable : 4482 )
|
||||
|
||||
//http://invisible-island.net/ncurses/
|
||||
//https://github.com/fffaraz/awesome-cpp
|
||||
//http://www.leonerd.org.uk/code/libtickit/
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Is_Key_Hit
|
||||
static tBOOL Is_Key_Hit(void)
|
||||
{
|
||||
return (_kbhit()) ? TRUE : FALSE;
|
||||
}//Is_Key_Hit
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Char
|
||||
static tXCHAR Get_Char()
|
||||
{
|
||||
return _getwch();
|
||||
}//Get_Char
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
struct stKeyMap
|
||||
{
|
||||
tUINT16 wKey;
|
||||
tUINT16 wValue;
|
||||
stKeyMap(tUINT16 i_wKey, tUINT16 i_wValue) : wKey(i_wKey), wValue(i_wValue) {}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CDesc_Tree
|
||||
class CKeysTree:
|
||||
public CRBTree<stKeyMap*, tUINT16>
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//~CKeysTree
|
||||
virtual ~CKeysTree()
|
||||
{
|
||||
Clear();
|
||||
}//~CRBTree
|
||||
|
||||
protected:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
virtual tBOOL Data_Release(stKeyMap* i_pData)
|
||||
{
|
||||
delete i_pData;
|
||||
return TRUE; //memory used from pool, not necessary to return
|
||||
}// Data_Release
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Return
|
||||
//TRUE - if (i_pKey < i_pData::key)
|
||||
//FALSE - otherwise
|
||||
tBOOL Is_Key_Less(tUINT16 i_pKey, stKeyMap *i_pData)
|
||||
{
|
||||
return (i_pKey < i_pData->wKey);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Return
|
||||
//TRUE - if (i_pKey == i_pData::key)
|
||||
//FALSE - otherwise
|
||||
tBOOL Is_Qual(tUINT16 i_pKey, stKeyMap *i_pData)
|
||||
{
|
||||
return (i_pKey == i_pData->wKey);
|
||||
}
|
||||
};//CDesc_Tree
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
class CConsole
|
||||
: public IConsole
|
||||
{
|
||||
tUINT16 m_pFg[IConsole::eColorsMax];
|
||||
tUINT16 m_pBg[IConsole::eColorsMax];
|
||||
size_t m_szText;
|
||||
tXCHAR *m_pText;
|
||||
HANDLE m_hStdOut;
|
||||
HANDLE m_hStdIn;
|
||||
tXCHAR *m_pEmpty;
|
||||
size_t m_szEmpty;
|
||||
CKeysTree m_pKeys;
|
||||
public:
|
||||
CConsole()
|
||||
{
|
||||
m_szText = 32768;
|
||||
m_pText = (tXCHAR*)malloc(m_szText * sizeof(tXCHAR));
|
||||
|
||||
m_szEmpty = 0;
|
||||
m_pEmpty = NULL;
|
||||
AllocEmptyString(1024);
|
||||
|
||||
m_pFg[IConsole::eBlack] = 0;
|
||||
m_pFg[IConsole::eBlue] = FOREGROUND_BLUE;
|
||||
m_pFg[IConsole::eGreen] = FOREGROUND_GREEN;
|
||||
m_pFg[IConsole::eCyan] = FOREGROUND_BLUE|FOREGROUND_GREEN;
|
||||
m_pFg[IConsole::eRed] = FOREGROUND_RED;
|
||||
m_pFg[IConsole::eMagenta] = FOREGROUND_BLUE|FOREGROUND_RED;
|
||||
m_pFg[IConsole::eBrown] = FOREGROUND_GREEN|FOREGROUND_RED;
|
||||
m_pFg[IConsole::eLightGray] = FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED;
|
||||
m_pFg[IConsole::eDarkGray] = FOREGROUND_INTENSITY;
|
||||
m_pFg[IConsole::eLightBlue] = FOREGROUND_BLUE|FOREGROUND_INTENSITY;
|
||||
m_pFg[IConsole::eLightGreen] = FOREGROUND_GREEN|FOREGROUND_INTENSITY;
|
||||
m_pFg[IConsole::eLightCyan] = FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY;
|
||||
m_pFg[IConsole::eLightRed] = FOREGROUND_RED|FOREGROUND_INTENSITY;
|
||||
m_pFg[IConsole::eLightMagenta] = FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_INTENSITY;
|
||||
m_pFg[IConsole::eYellow] = FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY;
|
||||
m_pFg[IConsole::eWhite] = FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY;
|
||||
|
||||
m_pBg[IConsole::eBlack] = 0;
|
||||
m_pBg[IConsole::eBlue] = BACKGROUND_BLUE;
|
||||
m_pBg[IConsole::eGreen] = BACKGROUND_GREEN;
|
||||
m_pBg[IConsole::eCyan] = BACKGROUND_BLUE|BACKGROUND_GREEN;
|
||||
m_pBg[IConsole::eRed] = BACKGROUND_RED;
|
||||
m_pBg[IConsole::eMagenta] = BACKGROUND_BLUE|BACKGROUND_RED;
|
||||
m_pBg[IConsole::eBrown] = BACKGROUND_GREEN|BACKGROUND_RED;
|
||||
m_pBg[IConsole::eLightGray] = BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_RED;
|
||||
m_pBg[IConsole::eDarkGray] = BACKGROUND_INTENSITY;
|
||||
m_pBg[IConsole::eLightBlue] = BACKGROUND_BLUE|BACKGROUND_INTENSITY;
|
||||
m_pBg[IConsole::eLightGreen] = BACKGROUND_GREEN|BACKGROUND_INTENSITY;
|
||||
m_pBg[IConsole::eLightCyan] = BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_INTENSITY;
|
||||
m_pBg[IConsole::eLightRed] = BACKGROUND_RED|BACKGROUND_INTENSITY;
|
||||
m_pBg[IConsole::eLightMagenta] = BACKGROUND_BLUE|BACKGROUND_RED|BACKGROUND_INTENSITY;
|
||||
m_pBg[IConsole::eYellow] = BACKGROUND_GREEN|BACKGROUND_RED|BACKGROUND_INTENSITY;
|
||||
m_pBg[IConsole::eWhite] = BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_RED|BACKGROUND_INTENSITY;
|
||||
|
||||
m_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
m_hStdIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
SetConsoleMode(m_hStdIn, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT);
|
||||
|
||||
m_pKeys.Push(new stKeyMap(38, IConsole::eKeyArrowUp), 38);
|
||||
m_pKeys.Push(new stKeyMap(40, IConsole::eKeyArrowDown), 40);
|
||||
m_pKeys.Push(new stKeyMap(37, IConsole::eKeyArrowLeft), 37);
|
||||
m_pKeys.Push(new stKeyMap(39, IConsole::eKeyArrowRight), 39);
|
||||
m_pKeys.Push(new stKeyMap(35, IConsole::eKeyEnd), 35);
|
||||
m_pKeys.Push(new stKeyMap(36, IConsole::eKeyHome), 36);
|
||||
m_pKeys.Push(new stKeyMap(33, IConsole::eKeyPageUp), 33);
|
||||
m_pKeys.Push(new stKeyMap(34, IConsole::eKeyPageDown), 34);
|
||||
|
||||
m_pKeys.Push(new stKeyMap(112, IConsole::eKeyF1), 112);
|
||||
m_pKeys.Push(new stKeyMap(113, IConsole::eKeyF2), 113);
|
||||
m_pKeys.Push(new stKeyMap(114, IConsole::eKeyF3), 114);
|
||||
m_pKeys.Push(new stKeyMap(115, IConsole::eKeyF4), 115);
|
||||
m_pKeys.Push(new stKeyMap(116, IConsole::eKeyF5), 116);
|
||||
m_pKeys.Push(new stKeyMap(117, IConsole::eKeyF6), 117);
|
||||
m_pKeys.Push(new stKeyMap(118, IConsole::eKeyF7), 118);
|
||||
m_pKeys.Push(new stKeyMap(119, IConsole::eKeyF8), 119);
|
||||
m_pKeys.Push(new stKeyMap(120, IConsole::eKeyF9), 120);
|
||||
m_pKeys.Push(new stKeyMap(121, IConsole::eKeyF10), 121);
|
||||
m_pKeys.Push(new stKeyMap(122, IConsole::eKeyF11), 122);
|
||||
m_pKeys.Push(new stKeyMap(123, IConsole::eKeyF12), 123);
|
||||
m_pKeys.Push(new stKeyMap(45, IConsole::eKeyInsert), 45);
|
||||
m_pKeys.Push(new stKeyMap(46, IConsole::eKeyDel), 46);
|
||||
m_pKeys.Push(new stKeyMap(9, IConsole::eKeyTab), 9);
|
||||
m_pKeys.Push(new stKeyMap(8, IConsole::eKeyBackSpace), 8);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual ~CConsole()
|
||||
{
|
||||
if (m_pText)
|
||||
{
|
||||
free(m_pText);
|
||||
m_pText = NULL;
|
||||
}
|
||||
|
||||
if (m_pEmpty)
|
||||
{
|
||||
free(m_pEmpty);
|
||||
m_pEmpty = NULL;
|
||||
}
|
||||
|
||||
m_pKeys.Clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL SetCursor(tUINT32 i_uX, tUINT32 i_uY)
|
||||
{
|
||||
COORD l_cCoord = {(SHORT)i_uX, (SHORT)i_uY};
|
||||
return SetConsoleCursorPosition(m_hStdOut, l_cCoord);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tUINT32 GetCursorX()
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO l_sCsbi = {0};
|
||||
if (GetConsoleScreenBufferInfo(m_hStdOut, &l_sCsbi))
|
||||
{
|
||||
return l_sCsbi.dwCursorPosition.X;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL GetInput(IConsole::sInput &o_rInput)
|
||||
{
|
||||
INPUT_RECORD l_stRecord = {};
|
||||
DWORD l_dwRead = 0;
|
||||
|
||||
GetNumberOfConsoleInputEvents(m_hStdIn, &l_dwRead);
|
||||
|
||||
if (!l_dwRead)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ReadConsoleInput(m_hStdIn, &l_stRecord, 1, &l_dwRead);
|
||||
|
||||
if (!l_dwRead)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (FOCUS_EVENT == l_stRecord.EventType)
|
||||
{
|
||||
o_rInput.eEvent = IConsole::eEvent::eFocus;
|
||||
o_rInput.stFocus.bFocus = l_stRecord.Event.FocusEvent.bSetFocus;
|
||||
}
|
||||
else if (KEY_EVENT == l_stRecord.EventType)
|
||||
{
|
||||
o_rInput.eEvent = IConsole::eEvent::eKey;
|
||||
o_rInput.stKey.bDown = l_stRecord.Event.KeyEvent.bKeyDown;
|
||||
o_rInput.stKey.uControls = l_stRecord.Event.KeyEvent.dwControlKeyState;
|
||||
o_rInput.stKey.wCount = l_stRecord.Event.KeyEvent.wRepeatCount;
|
||||
|
||||
stKeyMap *l_pKey = m_pKeys.Find(l_stRecord.Event.KeyEvent.wVirtualKeyCode);
|
||||
if (l_pKey)
|
||||
{
|
||||
o_rInput.stKey.wKey = l_pKey->wValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
o_rInput.stKey.wKey = l_stRecord.Event.KeyEvent.wVirtualKeyCode;
|
||||
}
|
||||
}
|
||||
else if (MOUSE_EVENT == l_stRecord.EventType)
|
||||
{
|
||||
o_rInput.eEvent = IConsole::eEvent::eMouse;
|
||||
o_rInput.stMouse.uButton = l_stRecord.Event.MouseEvent.dwButtonState;
|
||||
o_rInput.stMouse.uX = l_stRecord.Event.MouseEvent.dwMousePosition.X;
|
||||
o_rInput.stMouse.uY = l_stRecord.Event.MouseEvent.dwMousePosition.Y;
|
||||
}
|
||||
else if (WINDOW_BUFFER_SIZE_EVENT == l_stRecord.EventType)
|
||||
{
|
||||
o_rInput.eEvent = IConsole::eEvent::eSize;
|
||||
o_rInput.stSize.uW = l_stRecord.Event.WindowBufferSizeEvent.dwSize.X;
|
||||
o_rInput.stSize.uH = l_stRecord.Event.WindowBufferSizeEvent.dwSize.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tUINT32 GetCursorY()
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO l_sCsbi = {0};
|
||||
if (GetConsoleScreenBufferInfo(m_hStdOut, &l_sCsbi))
|
||||
{
|
||||
return l_sCsbi.dwCursorPosition.Y;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tUINT32 GetWidth()
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO l_sCsbi = {0};
|
||||
if (GetConsoleScreenBufferInfo(m_hStdOut, &l_sCsbi))
|
||||
{
|
||||
return l_sCsbi.srWindow.Right - l_sCsbi.srWindow.Left + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tUINT32 GetHeight()
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO l_sCsbi = {0};
|
||||
if (GetConsoleScreenBufferInfo(m_hStdOut, &l_sCsbi))
|
||||
{
|
||||
return l_sCsbi.srWindow.Bottom - l_sCsbi.srWindow.Top + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL SetTextAttr(IConsole::eColor i_eFg, IConsole::eColor i_eBg)
|
||||
{
|
||||
if ( (i_eFg < 0)
|
||||
|| (i_eFg >= IConsole::eColorsMax)
|
||||
|| (i_eBg < 0)
|
||||
|| (i_eBg >= IConsole::eColorsMax)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return SetConsoleTextAttribute(m_hStdOut, m_pFg[i_eFg] | m_pBg[i_eBg]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Clear()
|
||||
{
|
||||
COORD l_sCoordScreen = { 0, 0 }; // home for the cursor
|
||||
DWORD l_dwCharsWritten = 0;
|
||||
DWORD l_dwConSize = 0;
|
||||
CONSOLE_SCREEN_BUFFER_INFO l_sCsbi = {0};
|
||||
|
||||
// Get the number of character cells in the current buffer.
|
||||
if( !GetConsoleScreenBufferInfo( m_hStdOut, &l_sCsbi ))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
l_dwConSize = l_sCsbi.dwSize.X * l_sCsbi.dwSize.Y;
|
||||
|
||||
// Fill the entire screen with blanks.
|
||||
if( !FillConsoleOutputCharacterW( m_hStdOut, // Handle to console screen buffer
|
||||
L' ', // Character to write to the buffer
|
||||
l_dwConSize, // Number of cells to write
|
||||
l_sCoordScreen, // Coordinates of first cell
|
||||
&l_dwCharsWritten )) // Receive number of characters written
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Get the current text attribute.
|
||||
if( !GetConsoleScreenBufferInfo( m_hStdOut, &l_sCsbi ))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Set the buffer's attributes accordingly.
|
||||
if( !FillConsoleOutputAttribute( m_hStdOut, // Handle to console screen buffer
|
||||
l_sCsbi.wAttributes, // Character attributes to use
|
||||
l_dwConSize, // Number of cells to set attribute
|
||||
l_sCoordScreen, // Coordinates of first cell
|
||||
&l_dwCharsWritten )) // Receive number of characters written
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Put the cursor at its home coordinates.
|
||||
return SetConsoleCursorPosition( m_hStdOut, l_sCoordScreen );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Clear(tUINT32 i_uX, tUINT32 i_uY, tUINT32 i_uW, tUINT32 i_uH, IConsole::eColor i_eBg)
|
||||
{
|
||||
tUINT32 l_uiW = GetWidth();
|
||||
tUINT32 l_uiH = GetHeight();
|
||||
|
||||
if ( (i_uX > l_uiW)
|
||||
|| (i_uY > l_uiH)
|
||||
|| (!i_uW)
|
||||
|| (!i_uH)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((i_uX + i_uW) > l_uiW)
|
||||
{
|
||||
i_uW = l_uiW - i_uX;
|
||||
}
|
||||
|
||||
if ((i_uY + i_uH) > l_uiH)
|
||||
{
|
||||
i_uH = l_uiH - i_uY;
|
||||
}
|
||||
|
||||
if (i_uW > m_szEmpty)
|
||||
{
|
||||
if (!AllocEmptyString((size_t)i_uW))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SetTextAttr(IConsole::eBlack, i_eBg))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tUINT32 l_uiX = GetCursorX();
|
||||
tUINT32 l_uiY = GetCursorY();
|
||||
tUINT32 l_uiYOld = l_uiY;
|
||||
while (i_uH--)
|
||||
{
|
||||
SetCursor(i_uX, i_uY++);
|
||||
WriteTextB(m_pEmpty, i_uW);
|
||||
}
|
||||
|
||||
SetCursor(l_uiX, l_uiYOld);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
size_t WriteTextB(const tXCHAR *i_pText, size_t i_szText)
|
||||
{
|
||||
DWORD l_dwWritten = 0;
|
||||
return WriteConsole(m_hStdOut, i_pText, (DWORD)i_szText, &l_dwWritten, NULL);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
size_t WriteTextB(IConsole::eColor i_eFg,
|
||||
IConsole::eColor i_eBg,
|
||||
size_t i_szLenMin,
|
||||
size_t i_szLenMax,
|
||||
size_t i_szOffset,
|
||||
tXCHAR *i_pText,
|
||||
size_t i_szText,
|
||||
size_t i_szTextMax
|
||||
)
|
||||
{
|
||||
if ( (i_szLenMin > i_szLenMax)
|
||||
|| (!i_pText)
|
||||
|| (8 >= i_szTextMax)
|
||||
|| (i_szText >= i_szTextMax)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!SetTextAttr(i_eFg, i_eBg))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
tXCHAR *l_pText = i_pText;
|
||||
|
||||
if (!i_szText)
|
||||
{
|
||||
i_szText = PStrLen(i_pText);
|
||||
}
|
||||
|
||||
//if there is offset, recalculate all inputs
|
||||
if (i_szOffset)
|
||||
{
|
||||
if (i_szOffset < i_szText) //set sext offset and recalculate all
|
||||
{
|
||||
l_pText = l_pText + i_szOffset;
|
||||
i_szText -= i_szOffset;
|
||||
i_szTextMax -= i_szOffset;
|
||||
i_szOffset = 0;
|
||||
*l_pText = TM('<');
|
||||
}
|
||||
else //if (i_szOffset >= i_szText)
|
||||
{
|
||||
l_pText = m_pText;
|
||||
*l_pText = TM('<');
|
||||
i_szText = 1;
|
||||
i_szTextMax= m_szText;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (i_szText > i_szLenMax)
|
||||
{
|
||||
i_szText = i_szLenMax;
|
||||
l_pText[i_szText-1] = TM('>');
|
||||
}
|
||||
else if (i_szText < i_szLenMin)
|
||||
{
|
||||
if (i_szTextMax < (i_szLenMin + 1))
|
||||
{
|
||||
PStrNCpy(m_pText, m_szText, l_pText, i_szText);
|
||||
l_pText = m_pText;
|
||||
i_szTextMax = m_szText;
|
||||
}
|
||||
|
||||
tXCHAR *l_pIter = l_pText + i_szText;
|
||||
|
||||
while (i_szText < i_szLenMin)
|
||||
{
|
||||
*l_pIter = TM(' ');
|
||||
l_pIter ++;
|
||||
i_szText++;
|
||||
}
|
||||
}
|
||||
|
||||
if (i_szText < i_szTextMax)
|
||||
{
|
||||
l_pText[i_szText] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_pText[i_szText-1] = 0;
|
||||
}
|
||||
|
||||
DWORD l_dwWritten = 0;
|
||||
if (!WriteConsole(m_hStdOut, l_pText, (DWORD)i_szText, &l_dwWritten, NULL))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (size_t)l_dwWritten;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
size_t WriteTextF(IConsole::eColor i_eFg,
|
||||
IConsole::eColor i_eBg,
|
||||
size_t i_szLenMin,
|
||||
size_t i_szLenMax,
|
||||
size_t i_szOffset,
|
||||
const tXCHAR *i_pFormat,
|
||||
va_list i_pVA
|
||||
)
|
||||
{
|
||||
int l_iReturn = PVsnprintf(m_pText, m_szText, i_pFormat, i_pVA);
|
||||
|
||||
if (0 > l_iReturn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return WriteTextB(i_eFg, i_eBg, i_szLenMin, i_szLenMax, i_szOffset, m_pText, (size_t)l_iReturn, m_szText);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Present()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
protected:
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL AllocEmptyString(size_t i_szEmpty)
|
||||
{
|
||||
if (m_pEmpty)
|
||||
{
|
||||
free(m_pEmpty);
|
||||
}
|
||||
|
||||
if (i_szEmpty > 4096)
|
||||
{
|
||||
i_szEmpty = 4096;
|
||||
}
|
||||
|
||||
m_szEmpty = i_szEmpty;
|
||||
m_pEmpty = (tXCHAR*)malloc(m_szEmpty * sizeof(tXCHAR));
|
||||
|
||||
if (!m_pEmpty)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tXCHAR *l_pEmpty = m_pEmpty;
|
||||
size_t l_szIterator = m_szEmpty;
|
||||
|
||||
while (l_szIterator--)
|
||||
{
|
||||
*l_pEmpty = TM(' ');
|
||||
l_pEmpty++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
};
|
||||
97
p7lib/Shared/Platforms/Windows_x86/PDnsTxtResolver.h
Normal file
97
p7lib/Shared/Platforms/Windows_x86/PDnsTxtResolver.h
Normal file
@ -0,0 +1,97 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <Windns.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "GTypes.h"
|
||||
#include "AList.h"
|
||||
|
||||
class CDnsTxt: public CAList<tACHAR*>
|
||||
{
|
||||
protected:
|
||||
virtual tBOOL Data_Release(tACHAR *i_pStr)
|
||||
{
|
||||
if (NULL == i_pStr)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
free(i_pStr);
|
||||
return TRUE;
|
||||
}//CListBase::Data_Release
|
||||
};
|
||||
|
||||
|
||||
tBOOL static inline GetDnsTxtRecords(const tACHAR *i_pDomain, CDnsTxt &io_rList)
|
||||
{
|
||||
DNS_RECORDA *l_pRecord = NULL;
|
||||
DNS_RECORDA *l_pIter = NULL;
|
||||
DNS_STATUS l_lStatus = 0;
|
||||
tACHAR *l_pReturn = NULL;
|
||||
|
||||
io_rList.Clear(TRUE);
|
||||
|
||||
l_lStatus = DnsQuery_A(i_pDomain,
|
||||
DNS_TYPE_TEXT,
|
||||
DNS_QUERY_STANDARD
|
||||
| DNS_QUERY_WIRE_ONLY
|
||||
| DNS_QUERY_NO_LOCAL_NAME
|
||||
| DNS_QUERY_BYPASS_CACHE
|
||||
//| DNS_QUERY_USE_TCP_ONLY
|
||||
| DNS_QUERY_NO_HOSTS_FILE,
|
||||
NULL,
|
||||
(DNS_RECORD**)&l_pRecord,
|
||||
NULL
|
||||
);
|
||||
if ( (0 == l_lStatus)
|
||||
&& (l_pRecord)
|
||||
)
|
||||
{
|
||||
l_pIter = l_pRecord;
|
||||
while (l_pIter)
|
||||
{
|
||||
if (DNS_TYPE_TEXT == l_pIter->wType)
|
||||
{
|
||||
if (l_pIter->Data.Txt.dwStringCount)
|
||||
{
|
||||
for (DWORD l_dwI = 0; l_dwI < l_pIter->Data.Txt.dwStringCount; l_dwI++)
|
||||
{
|
||||
if (l_pIter->Data.Txt.pStringArray[l_dwI])
|
||||
{
|
||||
io_rList.Push_Last(strdup(l_pIter->Data.Txt.pStringArray[l_dwI]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!l_pReturn)
|
||||
{
|
||||
l_pIter = l_pIter->pNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_pIter = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
DnsRecordListFree(l_pRecord, DnsFreeRecordList);
|
||||
}
|
||||
|
||||
return (io_rList.Count() != 0);
|
||||
}
|
||||
331
p7lib/Shared/Platforms/Windows_x86/PFile.h
Normal file
331
p7lib/Shared/Platforms/Windows_x86/PFile.h
Normal file
@ -0,0 +1,331 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PFILE_H
|
||||
#define PFILE_H
|
||||
|
||||
|
||||
//UTF-8 text file header - {0xEF, 0xBB, 0xBF}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class CPFile
|
||||
: public IFile //virtual
|
||||
{
|
||||
volatile tINT32 m_iRCnt;
|
||||
HANDLE m_hFile;
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
CPFile()
|
||||
: m_iRCnt(1)
|
||||
, m_hFile(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
virtual ~CPFile()
|
||||
{
|
||||
Close(FALSE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL IsOpened()
|
||||
{
|
||||
return (NULL != m_hFile);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Open(const tXCHAR *i_pName, tUINT32 i_dwFlags)
|
||||
{
|
||||
DWORD l_dwAccess = GENERIC_READ;
|
||||
DWORD l_dwShare = 0;
|
||||
|
||||
if (EACCESS_WRITE & i_dwFlags)
|
||||
{
|
||||
l_dwAccess |= GENERIC_WRITE;
|
||||
}
|
||||
|
||||
if (ESHARE_READ & i_dwFlags)
|
||||
{
|
||||
l_dwShare |= FILE_SHARE_READ;
|
||||
}
|
||||
|
||||
if (ESHARE_WRITE & i_dwFlags)
|
||||
{
|
||||
l_dwShare |= FILE_SHARE_WRITE;
|
||||
}
|
||||
|
||||
Close(TRUE);
|
||||
|
||||
m_hFile = CreateFileW(i_pName,
|
||||
l_dwAccess,
|
||||
l_dwShare,
|
||||
NULL,
|
||||
(i_dwFlags & EOPEN) ? OPEN_EXISTING : CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if ( (NULL == m_hFile)
|
||||
|| (INVALID_HANDLE_VALUE == m_hFile)
|
||||
)
|
||||
{
|
||||
m_hFile = NULL;
|
||||
}
|
||||
|
||||
return (NULL != m_hFile);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Close(tBOOL i_bFlush)
|
||||
{
|
||||
tBOOL l_bReturn = TRUE;
|
||||
HANDLE l_hTemp = NULL;
|
||||
|
||||
if (NULL == m_hFile)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (i_bFlush)
|
||||
{
|
||||
if (FALSE == FlushFileBuffers(m_hFile))
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lExit;
|
||||
}
|
||||
}
|
||||
|
||||
l_hTemp = m_hFile;
|
||||
m_hFile = NULL;
|
||||
|
||||
if (FALSE == CloseHandle(l_hTemp))
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lExit;
|
||||
}
|
||||
|
||||
l_lExit:
|
||||
return l_bReturn;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Set_Position(tUINT64 i_qwOffset)
|
||||
{
|
||||
if (NULL == m_hFile)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LONG l_lOffsetHi = (LONG)(i_qwOffset >> 32);
|
||||
|
||||
if ( (INVALID_SET_FILE_POINTER == SetFilePointer(m_hFile,
|
||||
(LONG)i_qwOffset,
|
||||
&l_lOffsetHi,
|
||||
FILE_BEGIN
|
||||
)
|
||||
|
||||
)
|
||||
&& (NO_ERROR != GetLastError())
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tUINT64 Get_Position()
|
||||
{
|
||||
if (INVALID_HANDLE_VALUE == m_hFile)
|
||||
{
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (NULL == m_hFile)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LONG l_lOffsetHi = 0;
|
||||
DWORD l_dwOffsetLow = SetFilePointer(m_hFile,
|
||||
0,
|
||||
&l_lOffsetHi,
|
||||
FILE_CURRENT
|
||||
);
|
||||
|
||||
if ( (INVALID_SET_FILE_POINTER != l_dwOffsetLow)
|
||||
|| (NO_ERROR == GetLastError())
|
||||
)
|
||||
{
|
||||
return (((tUINT64)l_lOffsetHi) << 32) + (tUINT64)l_dwOffsetLow;
|
||||
}
|
||||
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tUINT64 Get_Size()
|
||||
{
|
||||
if (INVALID_HANDLE_VALUE == m_hFile)
|
||||
{
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
LARGE_INTEGER l_qwSize;
|
||||
|
||||
if (FALSE == GetFileSizeEx(m_hFile, &l_qwSize))
|
||||
{
|
||||
l_qwSize.QuadPart = 0LL;
|
||||
}
|
||||
|
||||
return (tUINT64)l_qwSize.QuadPart;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
size_t Write(const tUINT8 *i_pBuffer, size_t i_szBuffer, tBOOL i_bFlush)
|
||||
{
|
||||
if ( (INVALID_HANDLE_VALUE == m_hFile)
|
||||
|| (NULL == i_pBuffer)
|
||||
|| (0 == i_szBuffer)
|
||||
)
|
||||
{
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
size_t l_szReturn = 0;
|
||||
DWORD l_dwWritten = 0;
|
||||
|
||||
while (l_szReturn < i_szBuffer)
|
||||
{
|
||||
l_dwWritten = 0;
|
||||
if (!WriteFile(m_hFile,
|
||||
i_pBuffer + l_szReturn,
|
||||
(DWORD)(i_szBuffer - l_szReturn),
|
||||
&l_dwWritten,
|
||||
NULL
|
||||
)
|
||||
)
|
||||
{
|
||||
l_szReturn += (size_t)l_dwWritten;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_szReturn += (size_t)l_dwWritten;
|
||||
}
|
||||
}
|
||||
|
||||
if ( (i_bFlush)
|
||||
&& (l_szReturn)
|
||||
)
|
||||
{
|
||||
FlushFileBuffers(m_hFile);
|
||||
}
|
||||
|
||||
return l_szReturn;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
size_t Read(tUINT8 *o_pBuffer, size_t i_szBuffer)
|
||||
{
|
||||
if ( (INVALID_HANDLE_VALUE == m_hFile)
|
||||
|| (NULL == o_pBuffer)
|
||||
|| (0 == i_szBuffer)
|
||||
)
|
||||
{
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
size_t l_szReturn = 0;
|
||||
DWORD l_dwRead = 0;
|
||||
|
||||
while (l_szReturn < i_szBuffer)
|
||||
{
|
||||
l_dwRead = 0;
|
||||
if (ReadFile(m_hFile,
|
||||
o_pBuffer + l_szReturn,
|
||||
(DWORD)(i_szBuffer - l_szReturn),
|
||||
&l_dwRead,
|
||||
NULL
|
||||
)
|
||||
)
|
||||
{
|
||||
l_szReturn += (size_t)l_dwRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_szReturn += (size_t)l_dwRead;
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 >= l_dwRead)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return l_szReturn;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tINT32 Add_Ref()
|
||||
{
|
||||
return ATOMIC_INC(&m_iRCnt);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tINT32 Release()
|
||||
{
|
||||
volatile tINT32 l_iReturn = ATOMIC_DEC(&m_iRCnt);
|
||||
|
||||
if (0 >= l_iReturn)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
return l_iReturn;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //PFILE_H
|
||||
|
||||
|
||||
|
||||
/*
|
||||
CPFile l_cFile;
|
||||
const tUINT8 l_pHeader[] = {0xEF, 0xBB, 0xBF};
|
||||
const char l_pText[] = "Some Text For me !\xD\xA Another Text\xD\xA Third Text";
|
||||
tUINT64 l_qwCount = 0;
|
||||
tUINT8 l_pBuffer[256] = {0};
|
||||
|
||||
l_cFile.Open("./ABC.txt", IFile::ECREATE | IFile::ESHARE_WRITE);
|
||||
|
||||
l_qwCount = l_cFile.Write(l_pHeader, LENGTH(l_pHeader), FALSE);
|
||||
l_qwCount = l_cFile.Write((tUINT8*)l_pText, LENGTH(l_pText) - 1, TRUE);
|
||||
|
||||
l_qwCount = l_cFile.Get_Size();
|
||||
|
||||
l_cFile.Set_Position(0);
|
||||
|
||||
l_qwCount = l_cFile.Read(l_pBuffer, LENGTH(l_pBuffer));
|
||||
|
||||
l_cFile.Close(TRUE);
|
||||
*/
|
||||
618
p7lib/Shared/Platforms/Windows_x86/PFileSystem.h
Normal file
618
p7lib/Shared/Platforms/Windows_x86/PFileSystem.h
Normal file
@ -0,0 +1,618 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#pragma warning(disable : 4091)
|
||||
|
||||
#include "Shlobj.h"
|
||||
|
||||
class CFSYS
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Directory_Exists
|
||||
static BOOL Directory_Exists(const wchar_t * i_pPath)
|
||||
{
|
||||
DWORD l_dwFile_Attr = 0;
|
||||
BOOL l_bRes = FALSE;
|
||||
|
||||
if (NULL == i_pPath)
|
||||
{
|
||||
return l_bRes;
|
||||
}
|
||||
|
||||
l_dwFile_Attr = GetFileAttributesW(i_pPath);
|
||||
//check if that directory is exist ...
|
||||
if ((FILE_ATTRIBUTE_DIRECTORY & l_dwFile_Attr) &&
|
||||
( ((DWORD)-1) != l_dwFile_Attr)
|
||||
)
|
||||
{
|
||||
l_bRes = TRUE;
|
||||
}
|
||||
|
||||
return l_bRes;
|
||||
}//Directory_Exists
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Directory_Create
|
||||
static BOOL Directory_Create(const wchar_t *i_pDirectory)
|
||||
{
|
||||
if (NULL == i_pDirectory)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wchar_t *l_pDirectory = _wcsdup(i_pDirectory);
|
||||
tBOOL l_bReturn = FALSE;
|
||||
|
||||
if (NULL == l_pDirectory)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size_t l_szLength = wcslen(l_pDirectory);
|
||||
|
||||
for (size_t l_dwI = 3; /*wcslen(L"C:\\")*/ l_dwI < l_szLength; l_dwI++)
|
||||
{
|
||||
if ( (L'\\' == l_pDirectory[l_dwI])
|
||||
|| (L'/' == l_pDirectory[l_dwI])
|
||||
)
|
||||
{
|
||||
l_pDirectory[l_dwI] = 0;
|
||||
if (FALSE == Directory_Exists(l_pDirectory))
|
||||
{
|
||||
CreateDirectoryW(l_pDirectory, NULL);
|
||||
}
|
||||
|
||||
l_pDirectory[l_dwI] = L'\\';
|
||||
}
|
||||
}
|
||||
|
||||
CreateDirectoryW(l_pDirectory, NULL);
|
||||
l_bReturn = Directory_Exists(l_pDirectory);
|
||||
|
||||
free(l_pDirectory);
|
||||
l_pDirectory = NULL;
|
||||
|
||||
return l_bReturn;
|
||||
}//Directory_Create
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Directory_Delete
|
||||
static BOOL Directory_Delete(const wchar_t *i_pDirectory)
|
||||
{
|
||||
if (NULL == i_pDirectory)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return RemoveDirectoryW(i_pDirectory);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//File_Exists
|
||||
static BOOL File_Exists(const wchar_t * i_pFileName)
|
||||
{
|
||||
HANDLE l_hFind_Handle = NULL;
|
||||
WIN32_FIND_DATAW l_tFind_Data;
|
||||
BOOL l_bRes = FALSE;
|
||||
|
||||
if (NULL == i_pFileName)
|
||||
{
|
||||
return l_bRes;
|
||||
}
|
||||
|
||||
memset(&l_tFind_Data, 0, sizeof(WIN32_FIND_DATAW));
|
||||
|
||||
l_hFind_Handle = FindFirstFileW(i_pFileName, &l_tFind_Data);
|
||||
if (INVALID_HANDLE_VALUE != l_hFind_Handle)
|
||||
{
|
||||
l_bRes = (0 == (l_tFind_Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
|
||||
FindClose(l_hFind_Handle);
|
||||
l_hFind_Handle = NULL;
|
||||
}
|
||||
|
||||
return l_bRes;
|
||||
}//File_Exists
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Enumerate_Files
|
||||
static void Enumerate_Files(CBList<CWString*> *io_pFilesList,
|
||||
CWString *i_pDirectory,
|
||||
const wchar_t *i_pMask, //for example L"*.dll"
|
||||
DWORD i_dwDepth = 0xFFFFFF
|
||||
)
|
||||
{
|
||||
WIN32_FIND_DATAW l_sFind_Info = {0};
|
||||
HANDLE l_hFind = INVALID_HANDLE_VALUE;
|
||||
DWORD l_dwLength = i_pDirectory->Length();
|
||||
CWString l_cSearch_Path;
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// Enumerate all files in current directory
|
||||
l_cSearch_Path.Set(i_pDirectory->Get());
|
||||
l_cSearch_Path.Append(2, L"\\", i_pMask);
|
||||
|
||||
l_hFind = FindFirstFileW(l_cSearch_Path.Get(), &l_sFind_Info);
|
||||
|
||||
while(INVALID_HANDLE_VALUE != l_hFind)
|
||||
{
|
||||
if (0 == (l_sFind_Info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
CWString *l_pFile = new CWString();
|
||||
if (l_pFile)
|
||||
{
|
||||
l_pFile->Set(i_pDirectory->Get());
|
||||
l_pFile->Append(2, L"\\", l_sFind_Info.cFileName);
|
||||
io_pFilesList->Add_After(io_pFilesList->Get_Last(), l_pFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (! FindNextFileW(l_hFind, &l_sFind_Info))
|
||||
{
|
||||
FindClose(l_hFind);
|
||||
l_hFind = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
} //while(INVALID_HANDLE_VALUE != hFind)
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// Enumerate all sub directories in current directory ....
|
||||
if (i_dwDepth)
|
||||
{
|
||||
l_cSearch_Path.Set(i_pDirectory->Get());
|
||||
l_cSearch_Path.Append(1, L"\\*");
|
||||
|
||||
l_hFind = FindFirstFileW(l_cSearch_Path.Get(), &l_sFind_Info);
|
||||
|
||||
while(INVALID_HANDLE_VALUE != l_hFind)
|
||||
{
|
||||
if ( (0 != (l_sFind_Info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
&& (0 != wcscmp(l_sFind_Info.cFileName, L"."))
|
||||
&& (0 != wcscmp(l_sFind_Info.cFileName, L".."))
|
||||
)
|
||||
{
|
||||
i_pDirectory->Append(2, L"\\", l_sFind_Info.cFileName);
|
||||
Enumerate_Files(io_pFilesList, i_pDirectory, i_pMask, i_dwDepth - 1);
|
||||
i_pDirectory->Trim(l_dwLength);
|
||||
}
|
||||
|
||||
if (! FindNextFileW(l_hFind, &l_sFind_Info))
|
||||
{
|
||||
FindClose(l_hFind);
|
||||
l_hFind = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
} //while(INVALID_HANDLE_VALUE != hFind)
|
||||
}
|
||||
}// Enumerate_Files
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Enumerate_Dirs
|
||||
static void Enumerate_Dirs(CBList<CWString*> *io_pFilesList, const tXCHAR *i_pRoot)
|
||||
{
|
||||
WIN32_FIND_DATAW l_sFind_Info = {0};
|
||||
HANDLE l_hFind = INVALID_HANDLE_VALUE;
|
||||
|
||||
if (!io_pFilesList)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (i_pRoot)
|
||||
&& (*i_pRoot)
|
||||
)
|
||||
{
|
||||
CWString l_cSearch_Path;
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// Enumerate all files in current directory
|
||||
l_cSearch_Path.Set(i_pRoot);
|
||||
l_cSearch_Path.Append(1, L"\\*");
|
||||
|
||||
l_hFind = FindFirstFileW(l_cSearch_Path.Get(), &l_sFind_Info);
|
||||
|
||||
while(INVALID_HANDLE_VALUE != l_hFind)
|
||||
{
|
||||
if ( (0 != (l_sFind_Info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
&& (0 != wcscmp(l_sFind_Info.cFileName, L"."))
|
||||
&& (0 != wcscmp(l_sFind_Info.cFileName, L".."))
|
||||
)
|
||||
{
|
||||
CWString *l_pFile = new CWString();
|
||||
if (l_pFile)
|
||||
{
|
||||
l_pFile->Set(i_pRoot);
|
||||
l_pFile->Append(2, L"\\", l_sFind_Info.cFileName);
|
||||
io_pFilesList->Add_After(io_pFilesList->Get_Last(), l_pFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (! FindNextFileW(l_hFind, &l_sFind_Info))
|
||||
{
|
||||
FindClose(l_hFind);
|
||||
l_hFind = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
} //while(INVALID_HANDLE_VALUE != hFind)
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD l_dwDrives = GetLogicalDrives();
|
||||
DWORD l_dwBit = 0;
|
||||
tXCHAR l_pDrive[4];
|
||||
|
||||
l_pDrive[0] = TM('A');
|
||||
l_pDrive[1] = TM(':');
|
||||
l_pDrive[2] = TM('\\');
|
||||
l_pDrive[3] = 0;
|
||||
|
||||
while (l_dwDrives)
|
||||
{
|
||||
if (l_dwDrives & 1)
|
||||
{
|
||||
l_pDrive[0] = (tXCHAR)(l_dwBit + TM('A'));
|
||||
|
||||
UINT l_uiType = GetDriveTypeW(l_pDrive);
|
||||
if ( (DRIVE_UNKNOWN != l_uiType)
|
||||
&& (DRIVE_NO_ROOT_DIR != l_uiType)
|
||||
)
|
||||
{
|
||||
CWString *l_pFile = new CWString();
|
||||
if (l_pFile)
|
||||
{
|
||||
l_pFile->Set(l_pDrive);
|
||||
io_pFilesList->Add_After(io_pFilesList->Get_Last(), l_pFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
l_dwDrives = l_dwDrives >> 1;
|
||||
l_dwBit ++;
|
||||
}
|
||||
}
|
||||
}// Enumerate_Dirs
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Version
|
||||
static UINT64 Get_Version(const wchar_t *i_pFile)
|
||||
{
|
||||
DWORD l_dwUnknown = 0;
|
||||
DWORD l_dwFileInfoSize = 0;
|
||||
UINT64 l_qwReturn = 0;
|
||||
CWString l_cPath;
|
||||
|
||||
if (!i_pFile)
|
||||
{
|
||||
l_cPath.Realloc(4096);
|
||||
if (GetModuleFileNameW(GetModuleHandleW(NULL),
|
||||
l_cPath.Get(),
|
||||
l_cPath.Max_Length()
|
||||
)
|
||||
)
|
||||
{
|
||||
i_pFile = l_cPath.Get();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0ull;
|
||||
}
|
||||
}
|
||||
|
||||
l_dwFileInfoSize = GetFileVersionInfoSizeW(i_pFile, &l_dwUnknown);
|
||||
|
||||
if (l_dwFileInfoSize)
|
||||
{
|
||||
BYTE * l_pFileInfo = new BYTE[l_dwFileInfoSize];
|
||||
if (l_pFileInfo)
|
||||
{
|
||||
memset(l_pFileInfo, 0, l_dwFileInfoSize);
|
||||
|
||||
if (GetFileVersionInfoW(i_pFile, 0, l_dwFileInfoSize, l_pFileInfo) )
|
||||
{
|
||||
VS_FIXEDFILEINFO * l_tVersion = NULL;
|
||||
UINT l_dwSize = 0;
|
||||
if (VerQueryValueW(l_pFileInfo, L"\\", (LPVOID *)&l_tVersion, &l_dwSize))
|
||||
{
|
||||
l_qwReturn = (((UINT64)l_tVersion->dwProductVersionMS) << 32) +
|
||||
l_tVersion->dwProductVersionLS;
|
||||
}
|
||||
}
|
||||
|
||||
if (l_pFileInfo)
|
||||
{
|
||||
delete [ ] l_pFileInfo;
|
||||
l_pFileInfo = NULL;
|
||||
}
|
||||
} //if (l_pFileInfo)
|
||||
} //if (l_dwFileInfoSize)
|
||||
|
||||
return l_qwReturn;
|
||||
}//Get_Version
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_TextResource
|
||||
static tBOOL Get_TextResource(const tXCHAR *i_pFile,
|
||||
const tXCHAR *i_pName,
|
||||
tXCHAR *o_pBuffer,
|
||||
size_t i_szBuffer
|
||||
)
|
||||
{
|
||||
tBOOL l_bReturn = FALSE;
|
||||
tUINT32 l_dwUnknown = 0;
|
||||
DWORD l_dwFileInfoSize = 0;
|
||||
tUINT32 *l_pCodePage = NULL;
|
||||
tUINT8 *l_pFileInfo = NULL;
|
||||
tUINT32 l_dwSize = 0;
|
||||
wchar_t *l_pValue = NULL;
|
||||
const size_t l_szName = 256;
|
||||
wchar_t l_pName[l_szName];
|
||||
|
||||
CWString l_cPath;
|
||||
|
||||
if ( (!i_pName)
|
||||
|| (!o_pBuffer)
|
||||
|| (32 > i_szBuffer)
|
||||
|| ((l_szName / 2) < wcslen(i_pName))
|
||||
)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
if (!i_pFile)
|
||||
{
|
||||
l_cPath.Realloc(4096);
|
||||
if (GetModuleFileNameW(GetModuleHandleW(NULL),
|
||||
l_cPath.Get(),
|
||||
l_cPath.Max_Length()
|
||||
)
|
||||
)
|
||||
{
|
||||
i_pFile = l_cPath.Get();
|
||||
}
|
||||
else
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
}
|
||||
|
||||
l_dwFileInfoSize = GetFileVersionInfoSizeW(i_pFile, (LPDWORD)&l_dwUnknown);
|
||||
|
||||
if (!l_dwFileInfoSize)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_pFileInfo = (tUINT8*)malloc(l_dwFileInfoSize);
|
||||
|
||||
if (!l_pFileInfo)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
memset(l_pFileInfo, 0, l_dwFileInfoSize);
|
||||
|
||||
if (!GetFileVersionInfoW(i_pFile, 0, l_dwFileInfoSize, l_pFileInfo) )
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
if (!VerQueryValueW(l_pFileInfo, L"\\VarFileInfo\\Translation", (LPVOID*) &l_pCodePage, &l_dwSize))
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
swprintf_s(l_pName, l_szName,
|
||||
L"\\StringFileInfo\\%08x\\%s",
|
||||
(tUINT32)((*l_pCodePage) << 16 | (*l_pCodePage) >> 16),
|
||||
i_pName
|
||||
);
|
||||
|
||||
if (!VerQueryValueW(l_pFileInfo, l_pName, (LPVOID *)&l_pValue, &l_dwSize))
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
|
||||
wcsncpy_s(o_pBuffer, i_szBuffer, l_pValue, (l_dwSize > i_szBuffer) ? i_szBuffer : l_dwSize);
|
||||
o_pBuffer[i_szBuffer-1] = 0;
|
||||
l_bReturn = TRUE;
|
||||
|
||||
l_lblExit:
|
||||
if (l_pFileInfo)
|
||||
{
|
||||
free(l_pFileInfo);
|
||||
l_pFileInfo = NULL;
|
||||
}
|
||||
return l_bReturn;
|
||||
}//Get_TextResource
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Process_Directory
|
||||
static BOOL Get_Process_Directory(CWString *o_pDirectory)
|
||||
{
|
||||
BOOL l_bReturn = FALSE;
|
||||
DWORD l_dwLength = 4096;
|
||||
|
||||
if ( (NULL == o_pDirectory)
|
||||
|| (FALSE == o_pDirectory->Realloc(l_dwLength))
|
||||
)
|
||||
{
|
||||
return l_bReturn;
|
||||
}
|
||||
|
||||
if (0 != GetModuleFileNameW(GetModuleHandleW(NULL),
|
||||
o_pDirectory->Get(),
|
||||
o_pDirectory->Max_Length())
|
||||
)
|
||||
{
|
||||
wchar_t *l_pExe_Name = NULL;
|
||||
|
||||
if ( (l_pExe_Name = wcsrchr(o_pDirectory->Get(), L'\\'))
|
||||
|| (l_pExe_Name = wcsrchr(o_pDirectory->Get(), L'/'))
|
||||
)
|
||||
{
|
||||
o_pDirectory->Trim((DWORD)(l_pExe_Name - o_pDirectory->Get()));
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}//Get_Process_Directory
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Process_Path
|
||||
static BOOL Get_Process_Path(CWString *o_pPath)
|
||||
{
|
||||
BOOL l_bReturn = FALSE;
|
||||
DWORD l_dwLength = 4096;
|
||||
|
||||
if ( (NULL == o_pPath)
|
||||
|| (FALSE == o_pPath->Realloc(l_dwLength))
|
||||
)
|
||||
{
|
||||
return l_bReturn;
|
||||
}
|
||||
|
||||
if (0 != GetModuleFileNameW(GetModuleHandleW(NULL),
|
||||
o_pPath->Get(),
|
||||
o_pPath->Max_Length())
|
||||
)
|
||||
{
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}//Get_Process_Path
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Get_File_Size
|
||||
static tUINT64 Get_File_Size(const wchar_t *i_pFile)
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA l_sFAD = {0};
|
||||
LARGE_INTEGER l_sSize = {0};
|
||||
|
||||
if (!GetFileAttributesExW(i_pFile, GetFileExInfoStandard, &l_sFAD))
|
||||
{
|
||||
return 0; // error condition, could call GetLastError to find out more
|
||||
}
|
||||
|
||||
l_sSize.HighPart = l_sFAD.nFileSizeHigh;
|
||||
l_sSize.LowPart = l_sFAD.nFileSizeLow;
|
||||
return l_sSize.QuadPart;
|
||||
}//Get_File_Size
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Delete_File
|
||||
static BOOL Delete_File(const wchar_t *i_pFile_Name)
|
||||
{
|
||||
if (NULL == i_pFile_Name)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD l_dwFAttr = GetFileAttributesW(i_pFile_Name);
|
||||
l_dwFAttr = l_dwFAttr & (~FILE_ATTRIBUTE_ARCHIVE);
|
||||
l_dwFAttr = l_dwFAttr & (~FILE_ATTRIBUTE_READONLY);
|
||||
l_dwFAttr = l_dwFAttr & (~FILE_ATTRIBUTE_SYSTEM);
|
||||
SetFileAttributesW(i_pFile_Name, l_dwFAttr);
|
||||
return DeleteFileW(i_pFile_Name);
|
||||
}//Delete_File
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//GetUserDirectory
|
||||
static tBOOL GetUserDirectory(CWString *o_pPath)
|
||||
{
|
||||
if ( (NULL == o_pPath)
|
||||
|| (FALSE == o_pPath->Realloc(4096))
|
||||
)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( S_OK != SHGetFolderPathW(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, o_pPath->Get()))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//GetUserDirectory
|
||||
static tBOOL GetDirectoryParent(CWString &i_rChild, CWString &o_rParent)
|
||||
{
|
||||
o_rParent.Set(i_rChild.Get());
|
||||
size_t l_szDir = o_rParent.Length();
|
||||
tXCHAR *l_pDir = o_rParent.Get();
|
||||
|
||||
//cut trailing '/' or '\'
|
||||
while ( (l_szDir)
|
||||
&& ( (TM('\\') == l_pDir[l_szDir - 1])
|
||||
|| (TM('/') == l_pDir[l_szDir - 1])
|
||||
)
|
||||
)
|
||||
{
|
||||
l_pDir[--l_szDir] = 0;
|
||||
}
|
||||
|
||||
tXCHAR *l_pTemp = wcsrchr(l_pDir, TM('\\'));
|
||||
if (!l_pTemp)
|
||||
{
|
||||
l_pTemp = wcsrchr(l_pDir, TM('/'));
|
||||
}
|
||||
|
||||
if (!l_pTemp)
|
||||
{
|
||||
o_rParent.Set(TM(""));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*l_pTemp = 0;
|
||||
l_pTemp--;
|
||||
//removing duplicates of '\' '/'
|
||||
while ( (TM('\\') == *l_pTemp)
|
||||
|| (TM('/') == *l_pTemp)
|
||||
)
|
||||
{
|
||||
*l_pTemp = 0;
|
||||
l_pTemp--;
|
||||
|
||||
if (l_pDir > l_pTemp)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
699
p7lib/Shared/Platforms/Windows_x86/PJournal.h
Normal file
699
p7lib/Shared/Platforms/Windows_x86/PJournal.h
Normal file
@ -0,0 +1,699 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#define FJOURNAL_FILE_BUFFER_LENGTH (0x20000)
|
||||
#define FJOURNAL_FILE_BUFFER_MINIMUM_REMAINDER (0x2000)
|
||||
#define FJOURNAL_THREAD_WAKEUP_INTERVAL (2500)
|
||||
#define FJOURNAL_FILE_EXTENSION L"log"
|
||||
#define FJOURNAL_DESCRIPTION_MAX_LENGTH (64)
|
||||
#define FJOURNAL_MAX_FILES (7)
|
||||
|
||||
|
||||
void __cdecl FJournal_Routine(void *i_pContext);
|
||||
|
||||
// 1. Dump to the file
|
||||
// 2. must have parameters and possibility to export them
|
||||
// 3. should have own thread to notify about writing, every 1-5 seconds.
|
||||
|
||||
class CJournal
|
||||
: virtual public IJournal
|
||||
{
|
||||
private:
|
||||
//put volatile variables at the top, to obtain 32 bit alignment.
|
||||
//Project has 8 bytes alignment by default
|
||||
volatile LONG m_lReference_Counter;
|
||||
|
||||
HANDLE m_hLog_File;
|
||||
wchar_t *m_pJournal_Buffer;
|
||||
wchar_t *m_pWrite_Buffer;
|
||||
DWORD m_dwBuffer_Used;
|
||||
|
||||
HANDLE m_hThread;
|
||||
HANDLE m_hEvent_Exit;
|
||||
HANDLE m_hEvent_Write;
|
||||
|
||||
CRITICAL_SECTION m_tCS;
|
||||
|
||||
SYSTEMTIME m_tTime;
|
||||
wchar_t m_pTypes_Description[IJournal::eLEVEL_COUNT][FJOURNAL_DESCRIPTION_MAX_LENGTH];
|
||||
CWString m_cFile_Name;
|
||||
UINT64 m_pCount[IJournal::eLEVEL_COUNT];
|
||||
|
||||
IJournal::eLevel m_eVerbosity;
|
||||
|
||||
IJournal::eTime m_eTime; //ignored for a while
|
||||
tBOOL m_bFunction;
|
||||
tBOOL m_bType;
|
||||
|
||||
BOOL m_bInitialized;
|
||||
BOOL m_bError;
|
||||
|
||||
DWORD m_dwMax_Files;
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
CJournal()
|
||||
: m_lReference_Counter(1)
|
||||
, m_hLog_File(INVALID_HANDLE_VALUE)
|
||||
, m_pJournal_Buffer(NULL)
|
||||
, m_pWrite_Buffer(NULL)
|
||||
, m_dwBuffer_Used(0)
|
||||
, m_hThread(NULL)
|
||||
, m_hEvent_Exit(NULL)
|
||||
, m_hEvent_Write(NULL)
|
||||
, m_eVerbosity(IJournal::eLEVEL_TRACE)
|
||||
, m_eTime(IJournal::eTIME_YYYYMMDDHHMMSSMS)
|
||||
, m_bFunction(TRUE)
|
||||
, m_bType(TRUE)
|
||||
, m_bInitialized(FALSE)
|
||||
, m_bError(FALSE)
|
||||
, m_dwMax_Files(FJOURNAL_MAX_FILES)
|
||||
{
|
||||
memset(&m_tCS, 0, sizeof(CRITICAL_SECTION));
|
||||
memset(&m_pCount, 0, sizeof(m_pCount));
|
||||
|
||||
InitializeCriticalSection(&m_tCS);
|
||||
|
||||
wcscpy_s(m_pTypes_Description[IJournal::eLEVEL_TRACE], FJOURNAL_DESCRIPTION_MAX_LENGTH, L"INFO : ");
|
||||
wcscpy_s(m_pTypes_Description[IJournal::eLEVEL_DEBUG], FJOURNAL_DESCRIPTION_MAX_LENGTH, L"DEBUG: ");
|
||||
wcscpy_s(m_pTypes_Description[IJournal::eLEVEL_INFO], FJOURNAL_DESCRIPTION_MAX_LENGTH, L"INFO : ");
|
||||
wcscpy_s(m_pTypes_Description[IJournal::eLEVEL_WARNING], FJOURNAL_DESCRIPTION_MAX_LENGTH, L"WARN.: ");
|
||||
wcscpy_s(m_pTypes_Description[IJournal::eLEVEL_ERROR], FJOURNAL_DESCRIPTION_MAX_LENGTH, L"ERROR: ");
|
||||
wcscpy_s(m_pTypes_Description[IJournal::eLEVEL_CRITICAL], FJOURNAL_DESCRIPTION_MAX_LENGTH, L"CRIT.: ");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
void Set_Files_Max_Count(DWORD i_dwVal)
|
||||
{
|
||||
m_dwMax_Files = i_dwVal;
|
||||
}//Set_Files_Max_Count
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Initialize(const tXCHAR *i_pName)
|
||||
{
|
||||
if (TRUE == m_bInitialized)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( (NULL == i_pName)
|
||||
|| (TRUE == m_bError)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CWString l_sDirectory;
|
||||
|
||||
if (FALSE == m_bError)
|
||||
{
|
||||
m_pJournal_Buffer = new wchar_t[FJOURNAL_FILE_BUFFER_LENGTH];
|
||||
m_pWrite_Buffer = new wchar_t[FJOURNAL_FILE_BUFFER_LENGTH];
|
||||
if ( (NULL == m_pJournal_Buffer) || (NULL == m_pWrite_Buffer) )
|
||||
{
|
||||
m_bError = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (FALSE == m_bError)
|
||||
{
|
||||
CFSYS::Get_Process_Directory(&l_sDirectory);
|
||||
l_sDirectory.Append(2, L"\\", i_pName);
|
||||
|
||||
if (FALSE == CFSYS::Directory_Exists(l_sDirectory.Get()))
|
||||
{
|
||||
m_bError = (! CFSYS::Directory_Create(l_sDirectory.Get()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (FALSE == m_bError)
|
||||
{
|
||||
Remove_Old_Journals(l_sDirectory.Get(),
|
||||
m_dwMax_Files,
|
||||
FJOURNAL_FILE_EXTENSION
|
||||
);
|
||||
|
||||
DWORD l_dwIterator = 0;
|
||||
SYSTEMTIME l_tTime;
|
||||
GetLocalTime(&l_tTime);
|
||||
do
|
||||
{
|
||||
swprintf_s(m_pJournal_Buffer,
|
||||
FJOURNAL_FILE_BUFFER_LENGTH,
|
||||
L"%s\\%04d_%02d_%02d-%02d_%02d_%02d-%d.%s",
|
||||
l_sDirectory.Get(),
|
||||
(int)l_tTime.wYear,
|
||||
(int)l_tTime.wMonth,
|
||||
(int)l_tTime.wDay,
|
||||
(int)l_tTime.wHour,
|
||||
(int)l_tTime.wMinute,
|
||||
(int)l_tTime.wSecond,
|
||||
(int)l_dwIterator++,
|
||||
FJOURNAL_FILE_EXTENSION
|
||||
);
|
||||
} while (CFSYS::File_Exists(m_pJournal_Buffer));
|
||||
|
||||
m_cFile_Name.Set((wchar_t*)m_pJournal_Buffer);
|
||||
|
||||
m_hLog_File = CreateFileW(m_pJournal_Buffer,
|
||||
GENERIC_WRITE | GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if ( (NULL == m_hLog_File)
|
||||
|| (INVALID_HANDLE_VALUE == m_hLog_File)
|
||||
)
|
||||
{
|
||||
m_hLog_File = INVALID_HANDLE_VALUE;
|
||||
m_bError = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (FALSE == m_bError)
|
||||
{
|
||||
m_hEvent_Exit = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
m_hEvent_Write = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||
if ( (NULL == m_hEvent_Exit) || (NULL == m_hEvent_Write) )
|
||||
{
|
||||
m_bError = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (FALSE == m_bError)
|
||||
{
|
||||
m_pJournal_Buffer[0] = 0xFEFF;
|
||||
m_dwBuffer_Used = 1;
|
||||
|
||||
m_hThread = (void*)_beginthread(&Routine_Entry_Point, 0, this);
|
||||
if (NULL == m_hThread)
|
||||
{
|
||||
m_bError = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (FALSE == m_bError)
|
||||
{
|
||||
m_bInitialized = TRUE;
|
||||
}
|
||||
|
||||
return (! m_bError);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
void Set_Verbosity(IJournal::eLevel i_eVerbosity)
|
||||
{
|
||||
EnterCriticalSection(&m_tCS);
|
||||
m_eVerbosity = i_eVerbosity;
|
||||
LeaveCriticalSection(&m_tCS);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
void Set_Format(IJournal::eTime i_eTime, tBOOL i_bFunction, tBOOL i_bType)
|
||||
{
|
||||
EnterCriticalSection(&m_tCS);
|
||||
m_eTime = i_eTime;
|
||||
m_bFunction = i_bFunction;
|
||||
m_bType = i_bType;
|
||||
LeaveCriticalSection(&m_tCS);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
IJournal::eLevel Get_Verbosity()
|
||||
{
|
||||
IJournal::eLevel l_eResult;
|
||||
EnterCriticalSection(&m_tCS);
|
||||
l_eResult = m_eVerbosity;
|
||||
LeaveCriticalSection(&m_tCS);
|
||||
|
||||
return l_eResult;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Log(IJournal::eLevel i_eType,
|
||||
IJournal::hModule i_hModule,
|
||||
const char *i_pFile,
|
||||
const char *i_pFunction,
|
||||
tUINT32 i_dwLine,
|
||||
const tXCHAR *i_pFormat,
|
||||
...
|
||||
)
|
||||
{
|
||||
tBOOL l_bResult = TRUE;
|
||||
int l_iCount = 0;
|
||||
wchar_t *l_pBuffer = NULL;
|
||||
|
||||
if ( (FALSE == m_bInitialized)
|
||||
|| (NULL == i_pFormat)
|
||||
|| (i_eType >= IJournal::eLEVEL_COUNT)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&m_tCS);
|
||||
|
||||
m_pCount[i_eType]++;
|
||||
|
||||
if (i_eType < m_eVerbosity)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
goto l_lExit;
|
||||
}
|
||||
|
||||
if ( (m_dwBuffer_Used >= FJOURNAL_FILE_BUFFER_LENGTH)
|
||||
|| (FJOURNAL_FILE_BUFFER_MINIMUM_REMAINDER >= (FJOURNAL_FILE_BUFFER_LENGTH - m_dwBuffer_Used) )
|
||||
)
|
||||
{
|
||||
SetEvent(m_hEvent_Write);
|
||||
|
||||
while (WAIT_OBJECT_0 == WaitForSingleObject(m_hEvent_Write, 0))
|
||||
{
|
||||
Sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( (l_bResult)
|
||||
&& (i_pFunction)
|
||||
&& (m_bFunction)
|
||||
)
|
||||
{
|
||||
l_pBuffer = m_pJournal_Buffer + m_dwBuffer_Used;
|
||||
|
||||
while (*i_pFunction)
|
||||
{
|
||||
(*l_pBuffer++) = (*i_pFunction++);
|
||||
m_dwBuffer_Used ++;
|
||||
}
|
||||
|
||||
l_iCount = swprintf_s(m_pJournal_Buffer + m_dwBuffer_Used,
|
||||
FJOURNAL_FILE_BUFFER_LENGTH - m_dwBuffer_Used,
|
||||
L"() Ln %04d : ", (int)i_dwLine
|
||||
);
|
||||
if (0 > l_iCount)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dwBuffer_Used += l_iCount;
|
||||
}
|
||||
|
||||
l_pBuffer = m_pJournal_Buffer + m_dwBuffer_Used;
|
||||
(*l_pBuffer++) = 13;
|
||||
(*l_pBuffer++) = 10;
|
||||
m_dwBuffer_Used += 2;
|
||||
}
|
||||
|
||||
if (l_bResult)
|
||||
{
|
||||
GetLocalTime(&m_tTime);
|
||||
l_iCount = swprintf_s(m_pJournal_Buffer + m_dwBuffer_Used,
|
||||
FJOURNAL_FILE_BUFFER_LENGTH - m_dwBuffer_Used,
|
||||
L"[%04d.%02d.%02d %02d:%02d:%02d.%03d] %s ",
|
||||
(int)m_tTime.wYear, (int)m_tTime.wMonth, (int)m_tTime.wDay,
|
||||
(int)m_tTime.wHour, (int)m_tTime.wMinute, (int)m_tTime.wSecond, (int)m_tTime.wMilliseconds,
|
||||
m_bType ? m_pTypes_Description[i_eType] : L""
|
||||
);
|
||||
if (0 > l_iCount)
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dwBuffer_Used += l_iCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (l_bResult)
|
||||
{
|
||||
va_list l_pArgList;
|
||||
va_start(l_pArgList, i_pFormat);
|
||||
size_t l_stRemaining = 0;
|
||||
|
||||
if (S_OK == StringCbVPrintfExW(m_pJournal_Buffer + m_dwBuffer_Used,
|
||||
(FJOURNAL_FILE_BUFFER_LENGTH - m_dwBuffer_Used) * sizeof(wchar_t),
|
||||
NULL,
|
||||
&l_stRemaining,
|
||||
STRSAFE_IGNORE_NULLS,
|
||||
i_pFormat,
|
||||
l_pArgList
|
||||
)
|
||||
)
|
||||
{
|
||||
m_dwBuffer_Used = FJOURNAL_FILE_BUFFER_LENGTH - (DWORD)(l_stRemaining / sizeof(wchar_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
l_bResult = FALSE;
|
||||
}
|
||||
|
||||
va_end(l_pArgList);
|
||||
}
|
||||
|
||||
if (l_bResult)
|
||||
{
|
||||
l_pBuffer = m_pJournal_Buffer + m_dwBuffer_Used;
|
||||
(*l_pBuffer++) = 13;
|
||||
(*l_pBuffer++) = 10;
|
||||
m_dwBuffer_Used += 2;
|
||||
}
|
||||
|
||||
l_lExit:
|
||||
|
||||
LeaveCriticalSection(&m_tCS);
|
||||
|
||||
return l_bResult;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
wchar_t *Get_File_Name()
|
||||
{
|
||||
if (FALSE == m_bInitialized)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return m_cFile_Name.Get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tUINT64 Get_Count(IJournal::eLevel i_eType)
|
||||
{
|
||||
UINT64 l_qwReturn = 0ULL;
|
||||
if (i_eType >= IJournal::eLEVEL_COUNT)
|
||||
{
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&m_tCS);
|
||||
l_qwReturn = m_pCount[i_eType];
|
||||
LeaveCriticalSection(&m_tCS);
|
||||
|
||||
return l_qwReturn;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tINT32 Add_Ref()
|
||||
{
|
||||
return InterlockedIncrement(&m_lReference_Counter);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tINT32 Release()
|
||||
{
|
||||
volatile tINT32 l_iRCnt = InterlockedDecrement(&m_lReference_Counter);
|
||||
|
||||
if ( 0 >= l_iRCnt)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
return l_iRCnt;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
BOOL Get_Initialized()
|
||||
{
|
||||
return m_bInitialized;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Register_Thread(const tXCHAR *i_pName, tUINT32 i_dwThreadId)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Unregister_Thread(tUINT32 i_dwThreadId)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Register_Module(const tXCHAR *i_pName, IJournal::hModule *o_hModule)
|
||||
{
|
||||
if (o_hModule)
|
||||
{
|
||||
*o_hModule = NULL;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
protected:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
static void __cdecl Routine_Entry_Point(void *i_pContext)
|
||||
{
|
||||
CJournal * l_pFJournal = (CJournal *)i_pContext;
|
||||
if (l_pFJournal)
|
||||
{
|
||||
l_pFJournal->Routine();
|
||||
}
|
||||
_endthread();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
void Routine()
|
||||
{
|
||||
BOOL l_bExit = FALSE;
|
||||
HANDLE l_pEvents[] = {m_hEvent_Exit, m_hEvent_Write};
|
||||
DWORD l_dwWFMO_result = 0;
|
||||
DWORD l_dwSize = 0;
|
||||
|
||||
while (FALSE == l_bExit)
|
||||
{
|
||||
l_dwWFMO_result = WaitForMultipleObjects(sizeof(l_pEvents)/sizeof(l_pEvents[0]),
|
||||
l_pEvents,
|
||||
FALSE,
|
||||
FJOURNAL_THREAD_WAKEUP_INTERVAL
|
||||
); //Process events
|
||||
|
||||
|
||||
// Exit signal
|
||||
if (WAIT_OBJECT_0 == l_dwWFMO_result)
|
||||
{
|
||||
l_dwSize = Copy_Bufer(TRUE);
|
||||
if (l_dwSize)
|
||||
{
|
||||
Write((BYTE*)m_pWrite_Buffer, l_dwSize);
|
||||
}
|
||||
|
||||
l_bExit = TRUE;
|
||||
}
|
||||
else if ( (WAIT_OBJECT_0 + 1) == l_dwWFMO_result)// we have received signal for write
|
||||
{
|
||||
l_dwSize = Copy_Bufer(FALSE);
|
||||
ResetEvent(m_hEvent_Write);
|
||||
|
||||
if ( (l_dwSize) && (FALSE == Write((BYTE*)m_pWrite_Buffer, l_dwSize)) )
|
||||
{
|
||||
l_bExit = TRUE;
|
||||
}
|
||||
}
|
||||
else if (WAIT_TIMEOUT == l_dwWFMO_result)
|
||||
{
|
||||
l_dwSize = Copy_Bufer(TRUE);
|
||||
|
||||
if ( (l_dwSize) && (FALSE == Write((BYTE*)m_pWrite_Buffer, l_dwSize)) )
|
||||
{
|
||||
l_bExit = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_hThread = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
DWORD Copy_Bufer(BOOL i_bLock)
|
||||
{
|
||||
DWORD l_dwResult = 0;
|
||||
|
||||
if (i_bLock)
|
||||
{
|
||||
EnterCriticalSection(&m_tCS);
|
||||
}
|
||||
|
||||
if (m_dwBuffer_Used)
|
||||
{
|
||||
l_dwResult = m_dwBuffer_Used * sizeof(wchar_t);
|
||||
memcpy_s(m_pWrite_Buffer, FJOURNAL_FILE_BUFFER_LENGTH * sizeof(wchar_t), m_pJournal_Buffer, l_dwResult);
|
||||
m_dwBuffer_Used = 0;
|
||||
}
|
||||
|
||||
if (i_bLock)
|
||||
{
|
||||
LeaveCriticalSection(&m_tCS);
|
||||
}
|
||||
|
||||
return l_dwResult;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
BOOL Write(BYTE *i_pBuffer, DWORD i_dwSize)
|
||||
{
|
||||
BOOL l_bResult = TRUE;
|
||||
DWORD l_dwReturned = 0;
|
||||
DWORD l_dwWriten = 0;
|
||||
|
||||
if ( (0 >= i_dwSize) || (NULL == i_pBuffer) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while ( l_dwWriten != i_dwSize )
|
||||
{
|
||||
l_dwReturned = 0;
|
||||
if ( 0 == WriteFile(m_hLog_File,
|
||||
i_pBuffer + l_dwWriten,
|
||||
i_dwSize - l_dwWriten,
|
||||
&l_dwReturned,
|
||||
NULL)
|
||||
)
|
||||
{
|
||||
i_dwSize = 0;
|
||||
l_dwWriten = 0;
|
||||
l_bResult = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_dwWriten += l_dwReturned;
|
||||
}
|
||||
} //while
|
||||
|
||||
return l_bResult;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
BOOL Remove_Old_Journals(wchar_t *i_pFolder, DWORD i_dwMax_Files, const wchar_t *i_pExtension)
|
||||
{
|
||||
wchar_t l_pFileName[ MAX_PATH ] = L"9999";
|
||||
DWORD l_dwPrev_Error_Mode = 0;
|
||||
WIN32_FIND_DATAW l_tFind_Info;
|
||||
HANDLE l_hFind = INVALID_HANDLE_VALUE;
|
||||
DWORD l_dwCount = 0;
|
||||
BOOL l_bResult = TRUE;
|
||||
|
||||
if ( (NULL == i_pFolder) || (NULL == i_pExtension) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
l_dwPrev_Error_Mode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
||||
|
||||
l_dwCount = i_dwMax_Files + 1;
|
||||
|
||||
while ( (l_dwCount > i_dwMax_Files) && (l_bResult) )
|
||||
{
|
||||
l_dwCount = 0;
|
||||
|
||||
swprintf_s(m_pJournal_Buffer, FJOURNAL_FILE_BUFFER_LENGTH, L"%s\\*.%s", i_pFolder, i_pExtension);
|
||||
|
||||
l_hFind = FindFirstFileW(m_pJournal_Buffer, &l_tFind_Info);
|
||||
|
||||
while(INVALID_HANDLE_VALUE != l_hFind)
|
||||
{
|
||||
if (0 == (l_tFind_Info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
l_dwCount ++;
|
||||
if (0 <= _wcsicmp(l_pFileName, l_tFind_Info.cFileName))
|
||||
{
|
||||
wcscpy_s(l_pFileName, MAX_PATH, l_tFind_Info.cFileName);
|
||||
}
|
||||
|
||||
if ( ! FindNextFileW(l_hFind, &l_tFind_Info))
|
||||
{
|
||||
FindClose(l_hFind);
|
||||
l_hFind = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
} //while(INVALID_HANDLE_VALUE != hFind)
|
||||
|
||||
SetErrorMode(l_dwPrev_Error_Mode);
|
||||
|
||||
if (l_dwCount > i_dwMax_Files)
|
||||
{
|
||||
swprintf_s(m_pJournal_Buffer, FJOURNAL_FILE_BUFFER_LENGTH, L"%s\\%s", i_pFolder, l_pFileName);
|
||||
|
||||
DWORD l_dwFAttr = GetFileAttributesW(m_pJournal_Buffer);
|
||||
l_dwFAttr = l_dwFAttr & (~FILE_ATTRIBUTE_ARCHIVE);
|
||||
l_dwFAttr = l_dwFAttr & (~FILE_ATTRIBUTE_READONLY);
|
||||
l_dwFAttr = l_dwFAttr & (~FILE_ATTRIBUTE_SYSTEM);
|
||||
SetFileAttributesW(m_pJournal_Buffer, l_dwFAttr);
|
||||
l_bResult = DeleteFileW(m_pJournal_Buffer);
|
||||
l_dwCount --;
|
||||
wcscpy_s(l_pFileName, MAX_PATH, L"9999");
|
||||
}
|
||||
}
|
||||
|
||||
return l_bResult;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
virtual ~CJournal() //use Release() instead
|
||||
{
|
||||
if (m_hThread)
|
||||
{
|
||||
if (m_hEvent_Exit)
|
||||
{
|
||||
SetEvent(m_hEvent_Exit);
|
||||
if (WAIT_TIMEOUT == WaitForSingleObject(m_hThread, 150000))
|
||||
{
|
||||
OutputDebugStringW(L"~CFJournal::Thread exit failed !\n");
|
||||
}
|
||||
CloseHandle(m_hEvent_Exit);
|
||||
m_hEvent_Exit = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_hEvent_Write)
|
||||
{
|
||||
CloseHandle(m_hEvent_Write);
|
||||
m_hEvent_Write = NULL;
|
||||
}
|
||||
|
||||
if (INVALID_HANDLE_VALUE != m_hLog_File)
|
||||
{
|
||||
CloseHandle(m_hLog_File);
|
||||
m_hLog_File = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (m_pJournal_Buffer)
|
||||
{
|
||||
delete [] m_pJournal_Buffer;
|
||||
m_pJournal_Buffer = NULL;
|
||||
}
|
||||
|
||||
if (m_pWrite_Buffer)
|
||||
{
|
||||
delete [] m_pWrite_Buffer;
|
||||
m_pWrite_Buffer = NULL;
|
||||
}
|
||||
|
||||
DeleteCriticalSection(&m_tCS);
|
||||
}
|
||||
|
||||
};
|
||||
30
p7lib/Shared/Platforms/Windows_x86/PLock.h
Normal file
30
p7lib/Shared/Platforms/Windows_x86/PLock.h
Normal file
@ -0,0 +1,30 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typedef CRITICAL_SECTION tLOCK;
|
||||
|
||||
|
||||
#define LOCK_CREATE(i_Lock) InitializeCriticalSection(&i_Lock)
|
||||
#define LOCK_DESTROY(i_Lock) DeleteCriticalSection(&i_Lock)
|
||||
|
||||
#define LOCK_ENTER(i_Lock) EnterCriticalSection(&i_Lock)
|
||||
#define LOCK_EXIT(i_Lock) LeaveCriticalSection(&i_Lock)
|
||||
#define LOCK_TRY(i_Lock) TryEnterCriticalSection(&i_Lock)
|
||||
216
p7lib/Shared/Platforms/Windows_x86/PMEvent.h
Normal file
216
p7lib/Shared/Platforms/Windows_x86/PMEvent.h
Normal file
@ -0,0 +1,216 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class CMEvent
|
||||
: virtual public IMEvent
|
||||
{
|
||||
struct sMEvent
|
||||
{
|
||||
eMEvent_Type eType;
|
||||
HANDLE hEvent;
|
||||
};
|
||||
|
||||
tUINT8 m_bCount;
|
||||
sMEvent *m_pEvents;
|
||||
tBOOL m_bInit;
|
||||
HANDLE *m_pHandles;
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CMEvent
|
||||
CMEvent()
|
||||
: m_bCount(0)
|
||||
, m_pEvents(NULL)
|
||||
, m_bInit(FALSE)
|
||||
, m_pHandles(NULL)
|
||||
{
|
||||
}//CMEvent
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//~CMEvent
|
||||
virtual ~CMEvent()
|
||||
{
|
||||
Cleanup();
|
||||
|
||||
m_bCount = 0;
|
||||
}//~CMEvent
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Init
|
||||
tBOOL Init(tUINT8 i_bCount, ...)
|
||||
{
|
||||
if ( (TRUE == m_bInit)
|
||||
|| (0 >= i_bCount)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
va_list l_pVA;
|
||||
tUINT8 l_bIDX = 0;
|
||||
|
||||
m_pEvents = new sMEvent[i_bCount];
|
||||
if (NULL == m_pEvents)
|
||||
{
|
||||
goto l_lExit;
|
||||
}
|
||||
|
||||
m_pHandles = new HANDLE[i_bCount];
|
||||
if (NULL == m_pHandles)
|
||||
{
|
||||
goto l_lExit;
|
||||
}
|
||||
|
||||
memset(m_pEvents, 0, sizeof(sMEvent) * i_bCount);
|
||||
|
||||
va_start(l_pVA, i_bCount);
|
||||
while (l_bIDX < i_bCount)
|
||||
{
|
||||
m_pEvents[l_bIDX].eType = (eMEvent_Type)va_arg(l_pVA, int); //Real type is "eMEvent_Type", MinGW warning
|
||||
|
||||
if (EMEVENT_SINGLE_AUTO == m_pEvents[l_bIDX].eType)
|
||||
{
|
||||
m_pEvents[l_bIDX].hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
}
|
||||
else if (EMEVENT_SINGLE_MANUAL == m_pEvents[l_bIDX].eType)
|
||||
{
|
||||
m_pEvents[l_bIDX].hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
}
|
||||
else if (EMEVENT_MULTI == m_pEvents[l_bIDX].eType)
|
||||
{
|
||||
m_pEvents[l_bIDX].hEvent = CreateSemaphore(NULL, 0, 0xFFFFFF, NULL);
|
||||
}
|
||||
|
||||
m_pHandles[l_bIDX] = m_pEvents[l_bIDX].hEvent;
|
||||
|
||||
l_bIDX++;
|
||||
}
|
||||
|
||||
va_end(l_pVA);
|
||||
|
||||
m_bInit = TRUE;
|
||||
m_bCount = i_bCount;
|
||||
|
||||
l_lExit:
|
||||
|
||||
if (FALSE == m_bInit)
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
return m_bInit;
|
||||
}//Init
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Set
|
||||
tBOOL Set(tUINT32 i_dwID)
|
||||
{
|
||||
if (i_dwID >= m_bCount)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (EMEVENT_MULTI == m_pEvents[i_dwID].eType)
|
||||
{
|
||||
ReleaseSemaphore(m_pEvents[i_dwID].hEvent, 1, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetEvent(m_pEvents[i_dwID].hEvent);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}//Set
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Clr
|
||||
tBOOL Clr(tUINT32 i_dwID)
|
||||
{
|
||||
if ( (i_dwID >= m_bCount)
|
||||
|| (EMEVENT_SINGLE_MANUAL != m_pEvents[i_dwID].eType)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ResetEvent(m_pEvents[i_dwID].hEvent);
|
||||
return TRUE;
|
||||
}//Clr
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Wait
|
||||
tUINT32 Wait()
|
||||
{
|
||||
return Wait(INFINITE);
|
||||
}//Wait
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Wait
|
||||
tUINT32 Wait(tUINT32 i_dwMSec)
|
||||
{
|
||||
DWORD l_dwRes = WaitForMultipleObjects(m_bCount,
|
||||
m_pHandles,
|
||||
FALSE,
|
||||
i_dwMSec
|
||||
);
|
||||
|
||||
if ( (WAIT_TIMEOUT == l_dwRes)
|
||||
|| (WAIT_FAILED == l_dwRes)
|
||||
)
|
||||
{
|
||||
return MEVENT_TIME_OUT;
|
||||
}
|
||||
|
||||
|
||||
return (MEVENT_SIGNAL_0 + (l_dwRes - WAIT_OBJECT_0));
|
||||
}//Wait
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Cleanup
|
||||
void Cleanup()
|
||||
{
|
||||
if (m_pHandles)
|
||||
{
|
||||
delete [] m_pHandles;
|
||||
m_pHandles = NULL;
|
||||
}
|
||||
|
||||
if (m_pEvents)
|
||||
{
|
||||
for (tUINT32 l_dwI = 0; l_dwI < m_bCount; l_dwI++)
|
||||
{
|
||||
if (m_pEvents[l_dwI].hEvent)
|
||||
{
|
||||
CloseHandle(m_pEvents[l_dwI].hEvent);
|
||||
m_pEvents[l_dwI].hEvent = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
delete [] m_pEvents;
|
||||
m_pEvents = NULL;
|
||||
}
|
||||
}//Cleanup
|
||||
};
|
||||
215
p7lib/Shared/Platforms/Windows_x86/PPerformanceInfo.h
Normal file
215
p7lib/Shared/Platforms/Windows_x86/PPerformanceInfo.h
Normal file
@ -0,0 +1,215 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PPERFORMANCE_INFO_H
|
||||
#define PPERFORMANCE_INFO_H
|
||||
|
||||
#include "IPerformanceInfo.h"
|
||||
|
||||
#include <Pdh.h>
|
||||
#include <pdhmsg.h>
|
||||
#include <Psapi.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
class CPerformanceInfo
|
||||
: public IPerformanceInfo
|
||||
{
|
||||
volatile tINT32 m_iRCnt;
|
||||
PDH_STATUS m_hPdhStatus;
|
||||
HQUERY m_hPdhQuery;
|
||||
HCOUNTER m_hPdhCounter[IPerformanceInfo::eCounterTotal];
|
||||
SYSTEM_INFO m_sSysInfo;
|
||||
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
CPerformanceInfo(const tXCHAR *i_pProcessName)
|
||||
: m_iRCnt(1)
|
||||
, m_hPdhStatus(ERROR_SUCCESS)
|
||||
, m_hPdhQuery(NULL)
|
||||
{
|
||||
tXCHAR l_pExeName[256];
|
||||
CWString l_cPhdPath;
|
||||
GetSystemInfo( &m_sSysInfo );
|
||||
memset(m_hPdhCounter, 0, sizeof(m_hPdhCounter));
|
||||
if (!m_sSysInfo.dwNumberOfProcessors)
|
||||
{
|
||||
m_sSysInfo.dwNumberOfProcessors = 1;
|
||||
}
|
||||
|
||||
if (GetModuleBaseNameW(GetCurrentProcess(), NULL, l_pExeName, LENGTH(l_pExeName)))
|
||||
{
|
||||
tXCHAR *l_pExt = wcsrchr(l_pExeName, TM('.'));
|
||||
if (l_pExt)
|
||||
{
|
||||
*l_pExt = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PStrCpy(l_pExeName, LENGTH(l_pExeName), i_pProcessName);
|
||||
}
|
||||
|
||||
l_cPhdPath.Realloc(4096);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//create PHD counters
|
||||
//If counters is missing == PDH_CSTATUS_NO_OBJECT
|
||||
//http://blogs.msdn.com/b/martinv/archive/2008/11/18/missing-performance-counters.aspx
|
||||
//C:\Windows\System32> lodctr /R
|
||||
//After that all Performance Counters were available again!
|
||||
if (ERROR_SUCCESS == PdhOpenQuery(NULL, NULL, &m_hPdhQuery))
|
||||
{
|
||||
m_hPdhStatus = PdhAddEnglishCounterW(m_hPdhQuery,
|
||||
TM("\\Processor(_Total)\\% Processor Time"),
|
||||
0,
|
||||
&m_hPdhCounter[IPerformanceInfo::eCounterSystemCpu]);
|
||||
if (ERROR_SUCCESS != m_hPdhStatus)
|
||||
{
|
||||
m_hPdhCounter[IPerformanceInfo::eCounterSystemCpu] = NULL;
|
||||
}
|
||||
|
||||
l_cPhdPath.Set(TM(""));
|
||||
swprintf_s(l_cPhdPath.Get(), l_cPhdPath.Max_Length(), TM("\\Process(%s)\\%% Processor Time"), l_pExeName);
|
||||
if (ERROR_SUCCESS != PdhAddEnglishCounterW(m_hPdhQuery, l_cPhdPath.Get(), 0, &m_hPdhCounter[IPerformanceInfo::eCounterProcessCpu]))
|
||||
{
|
||||
m_hPdhCounter[IPerformanceInfo::eCounterProcessCpu] = NULL;
|
||||
}
|
||||
|
||||
l_cPhdPath.Set(TM(""));
|
||||
swprintf_s(l_cPhdPath.Get(), l_cPhdPath.Max_Length(), TM("\\Process(%s)\\Handle Count"), l_pExeName);
|
||||
if (ERROR_SUCCESS != PdhAddEnglishCounterW(m_hPdhQuery, l_cPhdPath.Get(), 0, &m_hPdhCounter[IPerformanceInfo::eCounterProcessHandles]))
|
||||
{
|
||||
m_hPdhCounter[IPerformanceInfo::eCounterProcessHandles] = NULL;
|
||||
}
|
||||
|
||||
l_cPhdPath.Set(TM(""));
|
||||
swprintf_s(l_cPhdPath.Get(), l_cPhdPath.Max_Length(), TM("\\Process(%s)\\Thread Count"), l_pExeName);
|
||||
if (ERROR_SUCCESS != PdhAddEnglishCounterW(m_hPdhQuery, l_cPhdPath.Get(), 0, &m_hPdhCounter[IPerformanceInfo::eCounterProcessThreads]))
|
||||
{
|
||||
m_hPdhCounter[IPerformanceInfo::eCounterProcessThreads] = NULL;
|
||||
}
|
||||
|
||||
l_cPhdPath.Set(TM(""));
|
||||
swprintf_s(l_cPhdPath.Get(), l_cPhdPath.Max_Length(), TM("\\Process(%s)\\Working Set"), l_pExeName);
|
||||
if (ERROR_SUCCESS != PdhAddEnglishCounterW(m_hPdhQuery, l_cPhdPath.Get(), 0, &m_hPdhCounter[IPerformanceInfo::eCounterProcessMemory]))
|
||||
{
|
||||
m_hPdhCounter[IPerformanceInfo::eCounterProcessMemory] = NULL;
|
||||
}
|
||||
}//if (ERROR_SUCCESS == PdhOpenQuery(NULL, NULL, &m_hPdhQuery))
|
||||
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual ~CPerformanceInfo()
|
||||
{
|
||||
if (m_hPdhCounter[IPerformanceInfo::eCounterProcessCpu])
|
||||
{
|
||||
PdhRemoveCounter(m_hPdhCounter[IPerformanceInfo::eCounterProcessCpu]);
|
||||
m_hPdhCounter[IPerformanceInfo::eCounterProcessCpu] = NULL;
|
||||
}
|
||||
|
||||
if (m_hPdhCounter[IPerformanceInfo::eCounterSystemCpu])
|
||||
{
|
||||
PdhRemoveCounter(m_hPdhCounter[IPerformanceInfo::eCounterSystemCpu]);
|
||||
m_hPdhCounter[IPerformanceInfo::eCounterSystemCpu] = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (m_hPdhCounter[IPerformanceInfo::eCounterProcessHandles])
|
||||
{
|
||||
PdhRemoveCounter(m_hPdhCounter[IPerformanceInfo::eCounterProcessHandles]);
|
||||
m_hPdhCounter[IPerformanceInfo::eCounterProcessHandles] = NULL;
|
||||
}
|
||||
|
||||
if (m_hPdhCounter[IPerformanceInfo::eCounterProcessThreads])
|
||||
{
|
||||
PdhRemoveCounter(m_hPdhCounter[IPerformanceInfo::eCounterProcessThreads]);
|
||||
m_hPdhCounter[IPerformanceInfo::eCounterProcessThreads] = NULL;
|
||||
}
|
||||
|
||||
if (m_hPdhCounter[IPerformanceInfo::eCounterProcessMemory])
|
||||
{
|
||||
PdhRemoveCounter(m_hPdhCounter[IPerformanceInfo::eCounterProcessMemory]);
|
||||
m_hPdhCounter[IPerformanceInfo::eCounterProcessMemory] = NULL;
|
||||
}
|
||||
|
||||
if (m_hPdhQuery)
|
||||
{
|
||||
PdhCloseQuery(m_hPdhQuery);
|
||||
m_hPdhQuery = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tBOOL Refresh()
|
||||
{
|
||||
if ( (m_hPdhQuery)
|
||||
&& (ERROR_SUCCESS == PdhCollectQueryData(m_hPdhQuery))
|
||||
)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tINT64 Get(IPerformanceInfo::eCounter i_eCounter)
|
||||
{
|
||||
PDH_FMT_COUNTERVALUE l_tPdhValue = {0};
|
||||
|
||||
if ( (i_eCounter >= IPerformanceInfo::eCounterTotal)
|
||||
|| (!m_hPdhCounter[i_eCounter])
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ERROR_SUCCESS == PdhGetFormattedCounterValue(m_hPdhCounter[i_eCounter], PDH_FMT_LARGE, NULL, &l_tPdhValue))
|
||||
{
|
||||
if (IPerformanceInfo::eCounterProcessCpu == i_eCounter)
|
||||
{
|
||||
l_tPdhValue.largeValue /= m_sSysInfo.dwNumberOfProcessors;
|
||||
}
|
||||
}
|
||||
|
||||
return l_tPdhValue.largeValue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tINT32 Add_Ref()
|
||||
{
|
||||
return ATOMIC_INC(&m_iRCnt);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tINT32 Release()
|
||||
{
|
||||
volatile tINT32 l_iReturn = ATOMIC_DEC(&m_iRCnt);
|
||||
|
||||
if (0 >= l_iReturn)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
return l_iReturn;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //PPERFORMANCE_INFO_H
|
||||
312
p7lib/Shared/Platforms/Windows_x86/PProcess.h
Normal file
312
p7lib/Shared/Platforms/Windows_x86/PProcess.h
Normal file
@ -0,0 +1,312 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
class CProc
|
||||
{
|
||||
public:
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//Get_ArgV
|
||||
static tXCHAR **Get_ArgV(tINT32 *o_pCount)
|
||||
{
|
||||
return Get_ArgV(GetCommandLineW(), o_pCount);
|
||||
}//Get_ArgV
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//Get_ArgV
|
||||
static tXCHAR **Get_ArgV(const tXCHAR *i_pCmdLine, tINT32 *o_pCount)
|
||||
{
|
||||
tINT32 l_iLen = 0;//strlen(i_pCmdLine);
|
||||
tXCHAR *l_pBuffer = NULL;//new tXCHAR[l_iLen];
|
||||
tXCHAR **l_pReturn = NULL;
|
||||
tBOOL l_bNew = TRUE;
|
||||
tBOOL l_bStr = FALSE;
|
||||
tINT32 l_iIDX = 0;
|
||||
|
||||
if ( (NULL == i_pCmdLine)
|
||||
|| (NULL == o_pCount)
|
||||
)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_iLen = (tINT32)wcslen(i_pCmdLine) + 1;
|
||||
l_pBuffer = new tXCHAR[l_iLen];
|
||||
|
||||
if (NULL == l_pBuffer)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
for (tINT32 l_iI = 0; l_iI < l_iLen; l_iI++)
|
||||
{
|
||||
if (TM('\"') == i_pCmdLine[l_iI])
|
||||
{
|
||||
l_bStr = ! l_bStr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (TM(' ') == i_pCmdLine[l_iI])
|
||||
&& (!l_bStr)
|
||||
)
|
||||
{
|
||||
l_pBuffer[l_iIDX++] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_pBuffer[l_iIDX++] = i_pCmdLine[l_iI];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
l_iLen = l_iIDX;
|
||||
|
||||
//calculate count of items//////////////////////////////////////////////////
|
||||
*o_pCount = 0;
|
||||
for (tINT32 l_iI = 0; l_iI < l_iLen; l_iI++)
|
||||
{
|
||||
if ( (0 == l_pBuffer[l_iI])
|
||||
|| ((l_iI + 1) == l_iLen)
|
||||
)
|
||||
{
|
||||
(*o_pCount) ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 >= *o_pCount)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
//allocate result///////////////////////////////////////////////////////////
|
||||
l_pReturn = new tXCHAR*[*o_pCount];
|
||||
|
||||
if (NULL == l_pReturn)
|
||||
{
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
//fill result///////////////////////////////////////////////////////////////
|
||||
l_bNew = TRUE;
|
||||
l_iIDX = 0;
|
||||
for (tINT32 l_iI = 0; l_iI < l_iLen; l_iI++)
|
||||
{
|
||||
if (l_bNew)
|
||||
{
|
||||
l_pReturn[l_iIDX++] = &l_pBuffer[l_iI];
|
||||
l_bNew = FALSE;
|
||||
}
|
||||
|
||||
if (0 == l_pBuffer[l_iI])
|
||||
{
|
||||
l_bNew = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
l_lblExit:
|
||||
|
||||
return l_pReturn;
|
||||
// return = CommandLineToArgvW(i_pCmdLine, o_pCount);
|
||||
}//Get_ArgV
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//Free_ArgV
|
||||
static void Free_ArgV(tXCHAR **i_pArgV)
|
||||
{
|
||||
if (NULL == i_pArgV)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (i_pArgV[0])
|
||||
{
|
||||
delete [] i_pArgV[0];
|
||||
}
|
||||
|
||||
delete [] i_pArgV;
|
||||
//LocalFree(i_pArgV);
|
||||
}//Free_ArgV
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Process_Time()
|
||||
//return a 64-bit value divided into 2 parts representing the number of
|
||||
//100-nanosecond intervals since January 1, 1601 (UTC).
|
||||
static tBOOL Get_Process_Time(tUINT32 *o_pHTime, tUINT32 *o_pLTime)
|
||||
{
|
||||
FILETIME l_tProcess_Time = {0};
|
||||
FILETIME l_tStub_01 = {0};
|
||||
FILETIME l_tStub_02 = {0};
|
||||
FILETIME l_tStub_03 = {0};
|
||||
|
||||
GetProcessTimes(GetCurrentProcess(),
|
||||
&l_tProcess_Time,
|
||||
&l_tStub_01,
|
||||
&l_tStub_02,
|
||||
&l_tStub_03
|
||||
);
|
||||
|
||||
*o_pHTime = l_tProcess_Time.dwHighDateTime;
|
||||
*o_pLTime = l_tProcess_Time.dwLowDateTime;
|
||||
|
||||
return TRUE;
|
||||
}//Get_Process_Time()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Process_Name
|
||||
static tBOOL Get_Process_Name(tWCHAR *o_pName, tINT32 i_iMax_Len)
|
||||
{
|
||||
BOOL l_bReturn = FALSE;
|
||||
const tUINT32 l_dwMax_Len = 32768;
|
||||
wchar_t *l_pProcess_Path = NULL;
|
||||
wchar_t *l_pProcess_Name = NULL;
|
||||
|
||||
if ( (NULL == o_pName)
|
||||
|| (64 >= i_iMax_Len)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
l_pProcess_Path = new wchar_t[l_dwMax_Len];
|
||||
|
||||
if (NULL == l_pProcess_Path)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (GetModuleFileNameW(GetModuleHandleW(NULL),
|
||||
l_pProcess_Path,
|
||||
l_dwMax_Len
|
||||
)
|
||||
)
|
||||
{
|
||||
if ( (l_pProcess_Name = wcsrchr(l_pProcess_Path, L'\\'))
|
||||
|| (l_pProcess_Name = wcsrchr(l_pProcess_Path, L'/'))
|
||||
)
|
||||
{
|
||||
l_pProcess_Name ++;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (l_bReturn)
|
||||
{
|
||||
wcscpy_s((wchar_t*)o_pName, i_iMax_Len, l_pProcess_Name);
|
||||
}
|
||||
|
||||
delete [] l_pProcess_Path;
|
||||
|
||||
return l_bReturn;
|
||||
}//Get_Process_Name
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Process_Name
|
||||
static tBOOL Get_Process_Name(tACHAR *o_pName, tINT32 i_iMax_Len)
|
||||
{
|
||||
const tINT32 l_iSize = 128;
|
||||
tWCHAR l_pName[l_iSize];
|
||||
|
||||
if (Get_Process_Name(l_pName, l_iSize))
|
||||
{
|
||||
Convert_UTF16_To_UTF8(l_pName, o_pName, (tUINT32)i_iMax_Len);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy_s(o_pName, (rsize_t)i_iMax_Len, "Unknown:Error");
|
||||
}
|
||||
|
||||
return true;
|
||||
}//Get_Process_Name
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Process_Path
|
||||
static tBOOL Get_Process_Path(tXCHAR *o_pPath, size_t i_szName)
|
||||
{
|
||||
BOOL l_bReturn = FALSE;
|
||||
wchar_t *l_pName = NULL;
|
||||
|
||||
if ( (NULL == o_pPath)
|
||||
|| (256 >= i_szName)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (GetModuleFileNameW(GetModuleHandleW(NULL),
|
||||
o_pPath,
|
||||
(DWORD)i_szName
|
||||
)
|
||||
)
|
||||
{
|
||||
if ( (l_pName = wcsrchr(o_pPath, L'\\'))
|
||||
|| (l_pName = wcsrchr(o_pPath, L'/'))
|
||||
)
|
||||
{
|
||||
l_pName ++;
|
||||
l_pName[0] = 0;
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}//Get_Process_Path
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Process_ID
|
||||
static tUINT32 Get_Process_ID()
|
||||
{
|
||||
return GetCurrentProcessId();
|
||||
}//Get_Process_ID
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Thread_Id
|
||||
static tUINT32 Get_Thread_Id()
|
||||
{
|
||||
return GetCurrentThreadId();
|
||||
}//Get_Thread_Id
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Processor
|
||||
static __forceinline tUINT32 Get_Processor()
|
||||
{
|
||||
#if defined(GTX64) || !defined(_MSC_VER)
|
||||
//return 0xFFFF; //don't know how to get processor number ... yet.
|
||||
return GetCurrentProcessorNumber();
|
||||
#else
|
||||
_asm
|
||||
{
|
||||
mov eax, 1
|
||||
cpuid
|
||||
shr ebx, 24
|
||||
mov eax, ebx
|
||||
}
|
||||
#endif
|
||||
}//Get_Processor
|
||||
};
|
||||
607
p7lib/Shared/Platforms/Windows_x86/PShared.h
Normal file
607
p7lib/Shared/Platforms/Windows_x86/PShared.h
Normal file
@ -0,0 +1,607 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#define SHARED_SEM_NULL NULL
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//CShared
|
||||
class CShared
|
||||
{
|
||||
struct sShared
|
||||
{
|
||||
HANDLE hMemory;
|
||||
HANDLE hMutex;
|
||||
tXCHAR *pName;
|
||||
};
|
||||
|
||||
enum eType
|
||||
{
|
||||
ETYPE_MUTEX = 0,
|
||||
ETYPE_FILE ,
|
||||
ETYPE_MAX
|
||||
};
|
||||
|
||||
public:
|
||||
typedef sShared *hShared;
|
||||
typedef HANDLE hSem;
|
||||
|
||||
enum eLock
|
||||
{
|
||||
E_OK,
|
||||
E_TIMEOUT,
|
||||
E_ERROR,
|
||||
E_NOT_EXISTS
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//CShared::Create
|
||||
static tBOOL Create(CShared::hShared *o_pHandle,
|
||||
const tXCHAR *i_pName,
|
||||
const tUINT8 *i_pData,
|
||||
tUINT16 i_wSize
|
||||
)
|
||||
{
|
||||
sShared *l_pShared = NULL;
|
||||
tBOOL l_bReturn = TRUE;
|
||||
DWORD l_dwLen = 0;
|
||||
wchar_t *l_pName = NULL;
|
||||
BOOL l_bRelease = FALSE;
|
||||
tUINT8 *l_pBuffer = NULL;
|
||||
|
||||
|
||||
if ( (NULL == i_pName)
|
||||
|| (NULL == i_pData)
|
||||
|| (0 >= i_wSize)
|
||||
|| (NULL == o_pHandle)
|
||||
)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_pShared = new sShared;
|
||||
if (NULL == l_pShared)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
memset(l_pShared, 0, sizeof(sShared));
|
||||
|
||||
l_dwLen = (DWORD)wcslen(i_pName) + 128;
|
||||
l_pName = (wchar_t*)malloc(sizeof(wchar_t) * l_dwLen);
|
||||
l_pShared->pName = PStrDub(i_pName);
|
||||
|
||||
if ( (NULL == l_pName)
|
||||
|| (NULL == l_pShared->pName)
|
||||
)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//create mutex and own it
|
||||
Create_Name(l_pName, l_dwLen, ETYPE_MUTEX, i_pName);
|
||||
|
||||
l_pShared->hMutex = CreateMutexW(NULL, TRUE, l_pName);
|
||||
if ( (NULL == l_pShared->hMutex)
|
||||
|| (ERROR_ALREADY_EXISTS == GetLastError())
|
||||
)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_bRelease = TRUE;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//create shared memory object
|
||||
Create_Name(l_pName, l_dwLen, ETYPE_FILE, i_pName);
|
||||
|
||||
l_pShared->hMemory = CreateFileMappingW(INVALID_HANDLE_VALUE, // use paging file
|
||||
NULL, // default security
|
||||
PAGE_READWRITE, // read/write access
|
||||
0, // maximum object size (high-order tUINT32)
|
||||
i_wSize, // maximum object size (low-order tUINT32)
|
||||
l_pName // name of mapping object
|
||||
);
|
||||
|
||||
if ( (NULL == l_pShared->hMemory)
|
||||
|| (ERROR_ALREADY_EXISTS == GetLastError())
|
||||
)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_pBuffer = (tUINT8*)MapViewOfFile(l_pShared->hMemory,
|
||||
FILE_MAP_ALL_ACCESS,
|
||||
0,
|
||||
0,
|
||||
i_wSize
|
||||
);
|
||||
|
||||
if (NULL == l_pBuffer)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
*o_pHandle = (CShared::hShared)l_pShared;
|
||||
|
||||
__try
|
||||
{
|
||||
memcpy(l_pBuffer, i_pData, i_wSize);
|
||||
}
|
||||
|
||||
__except ( GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR
|
||||
? EXCEPTION_EXECUTE_HANDLER
|
||||
: EXCEPTION_CONTINUE_SEARCH
|
||||
)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_lblExit:
|
||||
if (l_pName)
|
||||
{
|
||||
free(l_pName);
|
||||
l_pName = NULL;
|
||||
}
|
||||
|
||||
if (l_pBuffer)
|
||||
{
|
||||
UnmapViewOfFile(l_pBuffer);
|
||||
l_pBuffer = NULL;
|
||||
}
|
||||
|
||||
if (l_bRelease)
|
||||
{
|
||||
ReleaseMutex(l_pShared->hMutex);
|
||||
}
|
||||
|
||||
if (FALSE == l_bReturn)
|
||||
{
|
||||
Close((hShared)l_pShared);
|
||||
l_pShared = NULL;
|
||||
|
||||
if (o_pHandle)
|
||||
{
|
||||
*o_pHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}//Shared_Create
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Read
|
||||
static tBOOL Read(const tXCHAR *i_pName,
|
||||
tUINT8 *o_pData,
|
||||
tUINT16 i_wSize
|
||||
)
|
||||
{
|
||||
HANDLE l_hMemory = NULL;
|
||||
tBOOL l_bReturn = TRUE;
|
||||
DWORD l_dwLen = 0;
|
||||
wchar_t *l_pName = NULL;
|
||||
tUINT8 *l_pBuffer = NULL;
|
||||
|
||||
if ( (NULL == i_pName)
|
||||
|| (NULL == o_pData)
|
||||
|| (0 >= i_wSize)
|
||||
)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_dwLen = (DWORD)wcslen(i_pName) + 128;
|
||||
l_pName = (wchar_t*)malloc(sizeof(wchar_t) * l_dwLen);
|
||||
|
||||
if (NULL == l_pName)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//open shared memory object
|
||||
Create_Name(l_pName, l_dwLen, ETYPE_FILE, i_pName);
|
||||
|
||||
l_hMemory = OpenFileMappingW(FILE_MAP_ALL_ACCESS, // read/write access
|
||||
FALSE, // do not inherit the name
|
||||
l_pName // name of mapping object
|
||||
);
|
||||
|
||||
if (NULL == l_hMemory)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_pBuffer = (tUINT8*)MapViewOfFile(l_hMemory,
|
||||
FILE_MAP_READ,
|
||||
0,
|
||||
0,
|
||||
i_wSize
|
||||
);
|
||||
|
||||
if (NULL == l_pBuffer)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
__try
|
||||
{
|
||||
memcpy(o_pData, l_pBuffer, i_wSize);
|
||||
}
|
||||
|
||||
__except ( (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR)
|
||||
? EXCEPTION_EXECUTE_HANDLER
|
||||
: EXCEPTION_CONTINUE_SEARCH
|
||||
)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_lblExit:
|
||||
if (l_pName)
|
||||
{
|
||||
free(l_pName);
|
||||
l_pName = NULL;
|
||||
}
|
||||
|
||||
if (l_pBuffer)
|
||||
{
|
||||
UnmapViewOfFile(l_pBuffer);
|
||||
l_pBuffer = NULL;
|
||||
}
|
||||
|
||||
if (l_hMemory)
|
||||
{
|
||||
CloseHandle(l_hMemory);
|
||||
l_hMemory = NULL;
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}//Read
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Write
|
||||
static tBOOL Write(const tXCHAR *i_pName,
|
||||
const tUINT8 *i_pData,
|
||||
tUINT16 i_wSize
|
||||
)
|
||||
{
|
||||
HANDLE l_hMemory = NULL;
|
||||
tBOOL l_bReturn = TRUE;
|
||||
DWORD l_dwLen = 0;
|
||||
wchar_t *l_pName = NULL;
|
||||
tUINT8 *l_pBuffer = NULL;
|
||||
|
||||
if ( (NULL == i_pName)
|
||||
|| (NULL == i_pData)
|
||||
|| (0 >= i_wSize)
|
||||
)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_dwLen = (DWORD)wcslen(i_pName) + 128;
|
||||
l_pName = (wchar_t*)malloc(sizeof(wchar_t) * l_dwLen);
|
||||
|
||||
if (NULL == l_pName)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//open shared memory object
|
||||
Create_Name(l_pName, l_dwLen, ETYPE_FILE, i_pName);
|
||||
|
||||
l_hMemory = OpenFileMappingW(FILE_MAP_ALL_ACCESS, // read/write access
|
||||
FALSE, // do not inherit the name
|
||||
l_pName // name of mapping object
|
||||
);
|
||||
|
||||
if (NULL == l_hMemory)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_pBuffer = (tUINT8*)MapViewOfFile(l_hMemory,
|
||||
FILE_MAP_WRITE,
|
||||
0,
|
||||
0,
|
||||
i_wSize
|
||||
);
|
||||
|
||||
if (NULL == l_pBuffer)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
__try
|
||||
{
|
||||
memcpy(l_pBuffer, i_pData, i_wSize);
|
||||
}
|
||||
|
||||
__except ( (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR)
|
||||
? EXCEPTION_EXECUTE_HANDLER
|
||||
: EXCEPTION_CONTINUE_SEARCH
|
||||
)
|
||||
{
|
||||
l_bReturn = FALSE;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_lblExit:
|
||||
if (l_pName)
|
||||
{
|
||||
free(l_pName);
|
||||
l_pName = NULL;
|
||||
}
|
||||
|
||||
if (l_pBuffer)
|
||||
{
|
||||
UnmapViewOfFile(l_pBuffer);
|
||||
l_pBuffer = NULL;
|
||||
}
|
||||
|
||||
if (l_hMemory)
|
||||
{
|
||||
CloseHandle(l_hMemory);
|
||||
l_hMemory = NULL;
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}//Write
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Lock
|
||||
static eLock Lock(const tXCHAR *i_pName, CShared::hSem &o_rSem, tUINT32 i_dwTimeout_ms)
|
||||
{
|
||||
HANDLE l_hMutex = NULL;
|
||||
eLock l_eReturn = CShared::E_OK;
|
||||
DWORD l_dwLen = 0;
|
||||
wchar_t *l_pName = NULL;
|
||||
|
||||
o_rSem = SHARED_SEM_NULL;
|
||||
|
||||
if (NULL == i_pName)
|
||||
{
|
||||
l_eReturn = CShared::E_ERROR;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_dwLen = (DWORD)wcslen(i_pName) + 128;
|
||||
l_pName = (wchar_t*)malloc(sizeof(wchar_t) * l_dwLen);
|
||||
|
||||
if (NULL == l_pName)
|
||||
{
|
||||
l_eReturn = CShared::E_ERROR;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//open mutex and own it
|
||||
Create_Name(l_pName, l_dwLen, ETYPE_MUTEX, i_pName);
|
||||
|
||||
l_hMutex = OpenMutexW(MUTEX_ALL_ACCESS, FALSE, l_pName);
|
||||
if (NULL == l_hMutex)
|
||||
{
|
||||
l_eReturn = CShared::E_NOT_EXISTS;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
if (WAIT_OBJECT_0 != WaitForSingleObject(l_hMutex, i_dwTimeout_ms))
|
||||
{
|
||||
l_eReturn = CShared::E_TIMEOUT;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
l_lblExit:
|
||||
if (l_pName)
|
||||
{
|
||||
free(l_pName);
|
||||
l_pName = NULL;
|
||||
}
|
||||
|
||||
if (SHARED_SEM_NULL != l_hMutex)
|
||||
{
|
||||
if (CShared::E_OK == l_eReturn)
|
||||
{
|
||||
o_rSem = l_hMutex;
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseHandle(l_hMutex);
|
||||
l_hMutex = SHARED_SEM_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return l_eReturn;
|
||||
}//Lock
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//UnLock
|
||||
static eLock UnLock(CShared::hSem &io_rSem)
|
||||
{
|
||||
HANDLE l_hMutex = NULL;
|
||||
eLock l_eReturn = CShared::E_ERROR;
|
||||
|
||||
if (SHARED_SEM_NULL == io_rSem)
|
||||
{
|
||||
l_eReturn = CShared::E_NOT_EXISTS;
|
||||
goto l_lblExit;
|
||||
}
|
||||
|
||||
ReleaseMutex(io_rSem);
|
||||
|
||||
l_lblExit:
|
||||
if (io_rSem)
|
||||
{
|
||||
CloseHandle(io_rSem);
|
||||
io_rSem = SHARED_SEM_NULL;
|
||||
}
|
||||
|
||||
return l_eReturn;
|
||||
}//UnLock
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//GetSemName
|
||||
static const tXCHAR* GetName(hShared i_pShared)
|
||||
{
|
||||
if (NULL == i_pShared)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return i_pShared->pName;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Close
|
||||
static tBOOL Close(hShared i_hShared)
|
||||
{
|
||||
if (NULL == i_hShared)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//if (i_hShared->hMutex)
|
||||
//{
|
||||
// WaitForSingleObject(i_hShared->hMutex, 3000);
|
||||
//}
|
||||
|
||||
if (i_hShared->hMemory)
|
||||
{
|
||||
CloseHandle(i_hShared->hMemory);
|
||||
i_hShared->hMemory = NULL;
|
||||
}
|
||||
|
||||
if (i_hShared->hMutex)
|
||||
{
|
||||
CloseHandle(i_hShared->hMutex);
|
||||
i_hShared->hMutex = NULL;
|
||||
}
|
||||
|
||||
if (i_hShared->pName)
|
||||
{
|
||||
PStrFreeDub(i_hShared->pName);
|
||||
i_hShared->pName = NULL;
|
||||
}
|
||||
|
||||
delete i_hShared;
|
||||
|
||||
return TRUE;
|
||||
}//Shared_Close
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//UnLink - linux required it due to fact that life time of shared object is
|
||||
//almost infinit, and cleanup should be done manually
|
||||
static tBOOL UnLink(const tXCHAR *i_pName)
|
||||
{
|
||||
UNUSED_ARG(i_pName);
|
||||
return TRUE;
|
||||
}//UnLink
|
||||
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Create_Name
|
||||
static tBOOL Create_Name(tXCHAR *o_pName,
|
||||
size_t i_szName,
|
||||
eType i_eType,
|
||||
const tXCHAR *i_pPostfix
|
||||
)
|
||||
{
|
||||
if ( (NULL == o_pName)
|
||||
|| (16 >= i_szName)
|
||||
|| (ETYPE_MAX <= i_eType)
|
||||
|| (NULL == i_pPostfix)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FILETIME l_tProcess_Time = {0};
|
||||
FILETIME l_tStub_01 = {0};
|
||||
FILETIME l_tStub_02 = {0};
|
||||
FILETIME l_tStub_03 = {0};
|
||||
|
||||
GetProcessTimes(GetCurrentProcess(),
|
||||
&l_tProcess_Time,
|
||||
&l_tStub_01,
|
||||
&l_tStub_02,
|
||||
&l_tStub_03
|
||||
);
|
||||
|
||||
if (ETYPE_MUTEX == i_eType)
|
||||
{
|
||||
swprintf_s(o_pName,
|
||||
i_szName,
|
||||
L"Local\\m%d%d%d%s",
|
||||
GetCurrentProcessId(),
|
||||
l_tProcess_Time.dwHighDateTime,
|
||||
l_tProcess_Time.dwLowDateTime,
|
||||
i_pPostfix
|
||||
);
|
||||
}
|
||||
else if (ETYPE_FILE == i_eType)
|
||||
{
|
||||
swprintf_s(o_pName,
|
||||
i_szName,
|
||||
L"Local\\f%d%d%d%s",
|
||||
GetCurrentProcessId(),
|
||||
l_tProcess_Time.dwHighDateTime,
|
||||
l_tProcess_Time.dwLowDateTime,
|
||||
i_pPostfix
|
||||
);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}//Create_Name
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
64
p7lib/Shared/Platforms/Windows_x86/PSharedLib.h
Normal file
64
p7lib/Shared/Platforms/Windows_x86/PSharedLib.h
Normal file
@ -0,0 +1,64 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef IPSHARED_LIB_H
|
||||
#define IPSHARED_LIB_H
|
||||
|
||||
#include "GTypes.h"
|
||||
|
||||
#include "Length.h"
|
||||
#include "PString.h"
|
||||
#include "WString.h"
|
||||
#include "SharedLib.h"
|
||||
#include "PAtomic.h"
|
||||
|
||||
class CPSharedLib
|
||||
: public CSharedLib
|
||||
{
|
||||
protected:
|
||||
HMODULE m_pDll;
|
||||
|
||||
public:
|
||||
CPSharedLib(const tXCHAR *i_pPath)
|
||||
: CSharedLib(i_pPath)
|
||||
, m_pDll(NULL)
|
||||
{
|
||||
m_pDll = LoadLibraryW(i_pPath);
|
||||
|
||||
if (m_pDll)
|
||||
{
|
||||
m_bState = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void *GetFunction(const tACHAR *i_pName)
|
||||
{
|
||||
return (void*)(GetProcAddress(m_pDll, i_pName));
|
||||
}
|
||||
|
||||
virtual ~CPSharedLib()
|
||||
{
|
||||
if (m_pDll)
|
||||
{
|
||||
FreeLibrary(m_pDll);
|
||||
m_pDll = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif //IPSHARED_LIB_H
|
||||
294
p7lib/Shared/Platforms/Windows_x86/PSignal.h
Normal file
294
p7lib/Shared/Platforms/Windows_x86/PSignal.h
Normal file
@ -0,0 +1,294 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//http://www.codeproject.com/Articles/207464/Exception-Handling-in-Visual-Cplusplus
|
||||
|
||||
#ifndef PSIGNAL_H
|
||||
#define PSIGNAL_H
|
||||
|
||||
#include <new.h>
|
||||
#include <crtdbg.h>
|
||||
#include "signal.h"
|
||||
#include "ISignal.h"
|
||||
|
||||
|
||||
static stChContext g_stContext = {0};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChSignalHandler
|
||||
static void __cdecl ChSignalHandler(int i_iSignal)
|
||||
{
|
||||
if (g_stContext.iProcessed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_stContext.iProcessed ++;
|
||||
|
||||
const char *l_pText = "unknown signal";
|
||||
|
||||
if (SIGABRT == i_iSignal)
|
||||
{
|
||||
l_pText = "SIGABRT";
|
||||
}
|
||||
else if (SIGFPE == i_iSignal)
|
||||
{
|
||||
l_pText = "SIGFPE";
|
||||
}
|
||||
else if (SIGILL == i_iSignal)
|
||||
{
|
||||
l_pText = "SIGILL";
|
||||
}
|
||||
else if (SIGINT == i_iSignal)
|
||||
{
|
||||
l_pText = "SIGINT";
|
||||
}
|
||||
else if (SIGSEGV == i_iSignal)
|
||||
{
|
||||
l_pText = "SIGSEGV";
|
||||
}
|
||||
else if (SIGTERM == i_iSignal)
|
||||
{
|
||||
l_pText = "SIGTERM";
|
||||
}
|
||||
|
||||
|
||||
if (g_stContext.pUserHandler)
|
||||
{
|
||||
g_stContext.pUserHandler((eCrashCode)(eCrashSignal + i_iSignal), l_pText, g_stContext.pUserContext);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}//ChSignalHandler
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChUnhandledExceptionFilter
|
||||
static LONG WINAPI ChUnhandledExceptionFilter(__in struct _EXCEPTION_POINTERS *i_pException)
|
||||
{
|
||||
if (g_stContext.iProcessed)
|
||||
{
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
if ( (STATUS_ACCESS_VIOLATION == i_pException->ExceptionRecord->ExceptionCode)
|
||||
|| (EXCEPTION_ARRAY_BOUNDS_EXCEEDED == i_pException->ExceptionRecord->ExceptionCode)
|
||||
|| (EXCEPTION_DATATYPE_MISALIGNMENT == i_pException->ExceptionRecord->ExceptionCode)
|
||||
|| (EXCEPTION_FLT_DIVIDE_BY_ZERO == i_pException->ExceptionRecord->ExceptionCode)
|
||||
|| (EXCEPTION_FLT_STACK_CHECK == i_pException->ExceptionRecord->ExceptionCode)
|
||||
|| (EXCEPTION_ILLEGAL_INSTRUCTION == i_pException->ExceptionRecord->ExceptionCode)
|
||||
|| (EXCEPTION_INT_DIVIDE_BY_ZERO == i_pException->ExceptionRecord->ExceptionCode)
|
||||
|| (EXCEPTION_NONCONTINUABLE_EXCEPTION == i_pException->ExceptionRecord->ExceptionCode)
|
||||
|| (EXCEPTION_PRIV_INSTRUCTION == i_pException->ExceptionRecord->ExceptionCode)
|
||||
|| (EXCEPTION_STACK_OVERFLOW == i_pException->ExceptionRecord->ExceptionCode)
|
||||
//|| ( == i_pException->ExceptionRecord.ExceptionCode)
|
||||
)
|
||||
{
|
||||
g_stContext.iProcessed ++;
|
||||
|
||||
if (g_stContext.pUserHandler)
|
||||
{
|
||||
g_stContext.pUserHandler(eCrashException, i_pException, g_stContext.pUserContext);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}//ChUnhandledExceptionFilter
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChPurecallHandler
|
||||
static void ChPurecallHandler(void)
|
||||
{
|
||||
if (g_stContext.iProcessed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_stContext.iProcessed ++;
|
||||
|
||||
if (g_stContext.pUserHandler)
|
||||
{
|
||||
g_stContext.pUserHandler(eCrashPureCall, "Pure call", g_stContext.pUserContext);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}//ChPurecallHandler
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChMemoryAllocationHandler
|
||||
static int ChMemoryAllocationHandler(size_t i_szSize)
|
||||
{
|
||||
if (g_stContext.iProcessed)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_stContext.iProcessed ++;
|
||||
|
||||
char l_pText[32];
|
||||
|
||||
sprintf_s(l_pText, "%lld", (tINT64)i_szSize);
|
||||
|
||||
if (g_stContext.pUserHandler)
|
||||
{
|
||||
g_stContext.pUserHandler(eCrashMemAlloc, l_pText, g_stContext.pUserContext);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
|
||||
return 0;
|
||||
}//ChMemoryAllocationHandler
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChInvalidParameterHandler
|
||||
static void ChInvalidParameterHandler(const wchar_t* i_pExpression,
|
||||
const wchar_t* i_pFunction,
|
||||
const wchar_t* i_pFile,
|
||||
unsigned int i_dwLine,
|
||||
uintptr_t i_pReserved
|
||||
)
|
||||
{
|
||||
if (g_stContext.iProcessed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_stContext.iProcessed ++;
|
||||
|
||||
char l_pText[148];
|
||||
const wchar_t *l_pFunction = i_pFunction ? i_pFunction : L"Func:Unk";
|
||||
const wchar_t *l_pFile = i_pFile ? i_pFile : L"File:Unk";
|
||||
size_t l_szFile = i_pFile ? wcslen(i_pFile) : 0;
|
||||
size_t l_szFunc = i_pFunction ? wcslen(i_pFunction) : 0;
|
||||
|
||||
if ( l_szFile > 64 )
|
||||
{
|
||||
l_szFile -= 64;
|
||||
}
|
||||
|
||||
if ( l_szFunc > 64 )
|
||||
{
|
||||
l_szFunc -= 64;
|
||||
}
|
||||
|
||||
sprintf_s(l_pText, "{%S}{%S}{%d}", l_pFunction + l_szFunc, l_pFile + l_szFile, (int)i_dwLine);
|
||||
|
||||
if (g_stContext.pUserHandler)
|
||||
{
|
||||
g_stContext.pUserHandler(eCrashInvalidParameter, l_pText, g_stContext.pUserContext);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}//ChInvalidParameterHandler
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChInstallPrivate
|
||||
static tBOOL ChInstallPrivate()
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//initialize handlers for all possible cases
|
||||
signal(SIGABRT, ChSignalHandler);
|
||||
signal(SIGFPE, ChSignalHandler);
|
||||
signal(SIGILL, ChSignalHandler);
|
||||
signal(SIGINT, ChSignalHandler);
|
||||
signal(SIGSEGV, ChSignalHandler);
|
||||
signal(SIGTERM, ChSignalHandler);
|
||||
|
||||
//SetUnhandledExceptionFilter(ChUnhandledExceptionFilter);
|
||||
AddVectoredExceptionHandler(1, ChUnhandledExceptionFilter);
|
||||
|
||||
_set_purecall_handler(ChPurecallHandler);
|
||||
|
||||
_set_new_mode(1);
|
||||
_set_new_handler(ChMemoryAllocationHandler);
|
||||
|
||||
_set_invalid_parameter_handler(ChInvalidParameterHandler);
|
||||
|
||||
_CrtSetReportMode(_CRT_ERROR, 0);
|
||||
_CrtSetReportMode(_CRT_ASSERT, 0);
|
||||
|
||||
return TRUE;
|
||||
}//ChInstallPrivate
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChInstall
|
||||
static tBOOL ChInstall()
|
||||
{
|
||||
if (g_stContext.iInstalled)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//initialize parameters
|
||||
memset(&g_stContext, 0, sizeof(g_stContext));
|
||||
g_stContext.iInstalled = 1;
|
||||
g_stContext.iProcessed = 0;
|
||||
|
||||
ChInstallPrivate();
|
||||
|
||||
return TRUE;
|
||||
}//ChInstall
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChSetHandler
|
||||
static tBOOL ChSetHandler(fnCrashHandler i_fnHandler)
|
||||
{
|
||||
if (!g_stContext.iInstalled)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_stContext.pUserHandler = i_fnHandler;
|
||||
|
||||
return TRUE;
|
||||
}//ChSetHandler
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChSetContext
|
||||
static tBOOL ChSetContext(void *i_pContext)
|
||||
{
|
||||
if (!g_stContext.iInstalled)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_stContext.pUserContext = i_pContext;
|
||||
|
||||
return TRUE;
|
||||
}//ChSetContext
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//ChUnInstall
|
||||
static tBOOL ChUnInstall()
|
||||
{
|
||||
return TRUE;
|
||||
}//ChUnInstall
|
||||
|
||||
#endif //PSIGNAL_H
|
||||
220
p7lib/Shared/Platforms/Windows_x86/PSocket.h
Normal file
220
p7lib/Shared/Platforms/Windows_x86/PSocket.h
Normal file
@ -0,0 +1,220 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <mswsock.h>
|
||||
#include "GTypes.h"
|
||||
#include "AList.h"
|
||||
|
||||
//256k
|
||||
#define CLIENT_RECV_BUFFER_SIZE (0x40000)
|
||||
//2m
|
||||
#define CLIENT_SEND_BUFFER_SIZE (0x200000)
|
||||
|
||||
//2m
|
||||
#define SERVER_RECV_BUFFER_SIZE (0x200000)
|
||||
//256k
|
||||
#define SERVER_SEND_BUFFER_SIZE (0x40000)
|
||||
|
||||
|
||||
typedef SOCKET tSOCKET;
|
||||
|
||||
typedef int tADDR_LEN;
|
||||
|
||||
typedef addrinfoW tADDR_INFO;
|
||||
|
||||
#define INVALID_SOCKET_VAL (INVALID_SOCKET)
|
||||
#define CONNECTION_IN_PROGRESS (WSAEWOULDBLOCK)
|
||||
|
||||
#define CLOSE_SOCKET(i_Socket) closesocket(m_hSocket)
|
||||
|
||||
|
||||
#define GET_SOCKET_ERROR() WSAGetLastError()
|
||||
|
||||
//#define SOCKET_ERROR (-1)
|
||||
|
||||
#define GET_ADDR_INFO(i_Node, i_Service, i_Hints, o_Res) GetAddrInfoW(i_Node,\
|
||||
i_Service,\
|
||||
i_Hints,\
|
||||
o_Res)
|
||||
|
||||
#define FREE_ADDR_INFO(i_Info) FreeAddrInfoW(i_Info)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//WSA_Init
|
||||
static inline tBOOL WSA_Init()
|
||||
{
|
||||
WSADATA l_tWSA;
|
||||
|
||||
if (0 != WSAStartup(MAKEWORD(1,1), &l_tWSA))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}//WSA_Init
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//WSA_UnInit
|
||||
static inline void WSA_UnInit()
|
||||
{
|
||||
WSACleanup();
|
||||
}//WSA_UnInit
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Print_SAddr
|
||||
static tBOOL Print_SAddr(sockaddr *i_pAddress, XCHAR *o_pIP, tUINT32 i_dwLen)
|
||||
{
|
||||
tBOOL l_bReturn = FALSE;
|
||||
tUINT32 l_dwSize = 0;
|
||||
|
||||
if (NULL == i_pAddress)
|
||||
{
|
||||
return l_bReturn;
|
||||
}
|
||||
|
||||
if (AF_INET6 == i_pAddress->sa_family)
|
||||
{
|
||||
l_dwSize = sizeof(sockaddr_in6);
|
||||
}
|
||||
else if (AF_INET == i_pAddress->sa_family)
|
||||
{
|
||||
l_dwSize = sizeof(sockaddr_in);
|
||||
}
|
||||
|
||||
if (0 == WSAAddressToStringW(i_pAddress,
|
||||
l_dwSize,
|
||||
NULL,
|
||||
o_pIP,
|
||||
(LPDWORD)&i_dwLen
|
||||
)
|
||||
)
|
||||
{
|
||||
l_bReturn = TRUE;
|
||||
}
|
||||
|
||||
return l_bReturn;
|
||||
}//Print_SAddr
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PEnumIpsHlp
|
||||
static tBOOL PEnumIpsHlp(const char *i_pHost, CBList<sockaddr_storage*> *io_pList)
|
||||
{
|
||||
char l_pPort[16]= TOSTR(9009);
|
||||
addrinfo *l_pInfo = NULL;
|
||||
addrinfo *l_pNext = NULL;
|
||||
addrinfo l_tHint = {0};
|
||||
|
||||
l_tHint.ai_family = AF_UNSPEC;
|
||||
l_tHint.ai_socktype = SOCK_DGRAM;
|
||||
l_tHint.ai_protocol = IPPROTO_UDP;
|
||||
|
||||
//http://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx
|
||||
if (0 == getaddrinfo(i_pHost, l_pPort, &l_tHint, &l_pInfo))
|
||||
{
|
||||
for(l_pNext = l_pInfo; l_pNext != NULL; l_pNext = l_pNext->ai_next)
|
||||
{
|
||||
if ( ( (AF_INET == l_pNext->ai_family)
|
||||
|| (AF_INET6 == l_pNext->ai_family)
|
||||
)
|
||||
&& (SOCK_DGRAM == l_pNext->ai_socktype)
|
||||
&& (IPPROTO_UDP == l_pNext->ai_protocol)
|
||||
)
|
||||
{
|
||||
sockaddr_storage *l_pNew = new sockaddr_storage;
|
||||
if (AF_INET == l_pNext->ai_family)
|
||||
{
|
||||
memcpy(l_pNew, l_pNext->ai_addr, sizeof(sockaddr_in));
|
||||
}
|
||||
else if (AF_INET6 == l_pNext->ai_family)
|
||||
{
|
||||
memcpy(l_pNew, l_pNext->ai_addr, sizeof(sockaddr_in6));
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(l_pNew, 0, sizeof(sockaddr_storage));
|
||||
}
|
||||
|
||||
io_pList->Add_After(NULL, l_pNew);
|
||||
}
|
||||
}
|
||||
|
||||
freeaddrinfo(l_pInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}//PEnumIpsHlp
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PEnumIps
|
||||
static tBOOL PEnumIps(CBList<sockaddr_storage*> *io_pList)
|
||||
{
|
||||
if (!io_pList)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
io_pList->Clear(TRUE);
|
||||
|
||||
const size_t l_szHost = 256;
|
||||
char l_pHost[l_szHost];
|
||||
|
||||
if (0 == gethostname(l_pHost, l_szHost))
|
||||
{
|
||||
PEnumIpsHlp(l_pHost, io_pList);
|
||||
}
|
||||
|
||||
PEnumIpsHlp("127.0.0.1", io_pList);
|
||||
PEnumIpsHlp("::1", io_pList);
|
||||
|
||||
return TRUE;
|
||||
}//PEnumIps
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Disable_PortUnreachable_ICMP
|
||||
static tBOOL Disable_PortUnreachable_ICMP(tSOCKET i_hSocket)
|
||||
{
|
||||
tUINT32 l_dwBytesReturned = 0;
|
||||
tBOOL l_bNewBehavior = FALSE;
|
||||
tINT32 l_iStatus = 0;
|
||||
|
||||
|
||||
l_iStatus = WSAIoctl(i_hSocket,
|
||||
SIO_UDP_CONNRESET,
|
||||
&l_bNewBehavior,
|
||||
sizeof(l_bNewBehavior),
|
||||
NULL,
|
||||
0,
|
||||
(LPDWORD)&l_dwBytesReturned,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
return (SOCKET_ERROR == l_iStatus) ? FALSE : TRUE;
|
||||
}//Disable_PortUnreachable_ICMP
|
||||
232
p7lib/Shared/Platforms/Windows_x86/PString.h
Normal file
232
p7lib/Shared/Platforms/Windows_x86/PString.h
Normal file
@ -0,0 +1,232 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include <strsafe.h>
|
||||
|
||||
#define PRINTF(...) wprintf(__VA_ARGS__)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrLen
|
||||
static inline tUINT32 PStrLen(const tXCHAR *i_pText)
|
||||
{
|
||||
return (tUINT32)wcslen(i_pText);
|
||||
}//PStrLen
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PUStrLen
|
||||
static inline tUINT32 PUStrLen(const tXCHAR *i_pText)
|
||||
{
|
||||
return (tUINT32)wcslen(i_pText);
|
||||
}//PUStrLen
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PStrCpy
|
||||
static inline tXCHAR* PStrCpy(tXCHAR *i_pDst,
|
||||
size_t i_szDst,
|
||||
const tXCHAR *i_pSrc
|
||||
)
|
||||
{
|
||||
wcscpy_s((wchar_t*)i_pDst, i_szDst, (wchar_t*)i_pSrc);
|
||||
return i_pDst;
|
||||
}//PStrLen
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PWStrCpy
|
||||
static inline tXCHAR* PWStrCpy(tWCHAR *i_pDst,
|
||||
size_t i_szDst,
|
||||
const tWCHAR *i_pSrc
|
||||
)
|
||||
{
|
||||
wcscpy_s((wchar_t*)i_pDst, i_szDst, (wchar_t*)i_pSrc);
|
||||
return i_pDst;
|
||||
}//PWStrCpy
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PStrCpy
|
||||
static inline tXCHAR* PStrNCpy(tXCHAR *i_pDst,
|
||||
size_t i_szDst,
|
||||
const tXCHAR *i_pSrc,
|
||||
size_t i_pSrcMaxCount
|
||||
)
|
||||
{
|
||||
wcsncpy_s((wchar_t*)i_pDst, i_szDst, (wchar_t*)i_pSrc, i_pSrcMaxCount);
|
||||
return i_pDst;
|
||||
}//PStrLen
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrNCmp
|
||||
static inline tINT32 PStrNCmp(const tXCHAR *i_pS1, const tXCHAR *i_pS2, size_t i_szLen)
|
||||
{
|
||||
return wcsncmp(i_pS1, i_pS2, i_szLen);
|
||||
}//PStrNCmp
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PStrNCmp
|
||||
static inline tINT32 PStrNiCmp(const tXCHAR *i_pS1,
|
||||
const tXCHAR *i_pS2,
|
||||
size_t i_szLen
|
||||
)
|
||||
{
|
||||
return _wcsnicmp(i_pS1, i_pS2, i_szLen);
|
||||
}//PStrNCmp
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PStrNCmp
|
||||
static inline tINT32 PStrICmp(const tXCHAR *i_pS1, const tXCHAR *i_pS2)
|
||||
{
|
||||
return _wcsicmp(i_pS1, i_pS2);
|
||||
}//PStrNCmp
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PStrCmp
|
||||
static inline tINT32 PStrCmp(const tXCHAR *i_pS1, const tXCHAR *i_pS2)
|
||||
{
|
||||
return wcscmp(i_pS1, i_pS2);
|
||||
}//PStrCmp
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrToInt
|
||||
static inline tINT32 PStrToInt(const tXCHAR *i_pS1)
|
||||
{
|
||||
return _wtoi(i_pS1);
|
||||
}//PStrToInt
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrCpy
|
||||
static inline void PUStrCpy(tWCHAR *i_pDst, tUINT32 i_dwMax_Len, const tXCHAR *i_pSrc)
|
||||
{
|
||||
wcscpy_s((wchar_t *)i_pDst, i_dwMax_Len, i_pSrc);
|
||||
}//PStrCpy
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PSPrint
|
||||
static inline tINT32 PSPrint(tXCHAR *o_pBuffer,
|
||||
size_t i_szBuffer,
|
||||
const tXCHAR *i_pFormat,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list l_pVA;
|
||||
int l_iReturn = 0;
|
||||
|
||||
va_start(l_pVA, i_pFormat);
|
||||
l_iReturn = _vsnwprintf_s(o_pBuffer, i_szBuffer, _TRUNCATE, i_pFormat, l_pVA);
|
||||
va_end(l_pVA);
|
||||
|
||||
return (tINT32)l_iReturn;
|
||||
}//PSPrint
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PSPrint
|
||||
static inline tINT32 PSPrint(tACHAR *o_pBuffer,
|
||||
size_t i_szBuffer,
|
||||
const tACHAR *i_pFormat,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list l_pVA;
|
||||
int l_iReturn = 0;
|
||||
|
||||
va_start(l_pVA, i_pFormat);
|
||||
l_iReturn = _vsnprintf_s(o_pBuffer, i_szBuffer, _TRUNCATE, i_pFormat, l_pVA);
|
||||
va_end(l_pVA);
|
||||
|
||||
return (tINT32)l_iReturn;
|
||||
}//PSPrint
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PVsnprintf
|
||||
static inline int PVsnprintf(tXCHAR *o_pBuffer, size_t i_szBuffer, const tXCHAR *i_pFormat, va_list i_pArgs)
|
||||
{
|
||||
//size_t l_szRem = 0;
|
||||
//StringCbVPrintfExW(o_pBuffer,
|
||||
// i_szBuffer,
|
||||
// NULL,
|
||||
// &l_szRem,
|
||||
// STRSAFE_IGNORE_NULLS,
|
||||
// i_pFormat,
|
||||
// i_pArgs
|
||||
// );
|
||||
//return (int)i_szBuffer - (int)l_szRem;
|
||||
return _vsnwprintf_s(o_pBuffer, i_szBuffer, _TRUNCATE, i_pFormat, i_pArgs);
|
||||
}//PVsnprintf
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrDub
|
||||
static inline tXCHAR *PStrDub(const tXCHAR *i_pStr)
|
||||
{
|
||||
return _wcsdup(i_pStr);
|
||||
}//PStrDub
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrFreeDub
|
||||
static inline void PStrFreeDub(tXCHAR *i_pStr)
|
||||
{
|
||||
free(i_pStr);
|
||||
}//PStrFreeDub
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrChr
|
||||
static inline const tXCHAR *PStrChr(const tXCHAR * i_pStr, tXCHAR i_cCh)
|
||||
{
|
||||
return wcschr(i_pStr, i_cCh);
|
||||
}//PStrChr
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrChr
|
||||
static inline tXCHAR *PStrChr(tXCHAR * i_pStr, tXCHAR i_cCh)
|
||||
{
|
||||
return wcschr(i_pStr, i_cCh);
|
||||
}//PStrChr
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrrChr
|
||||
static inline tXCHAR *PStrrChr(tXCHAR * i_pStr, tXCHAR i_cCh)
|
||||
{
|
||||
return wcsrchr(i_pStr, i_cCh);
|
||||
}//PStrrChr
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrrChr
|
||||
static inline const tXCHAR *PStrrChr(const tXCHAR * i_pStr, const tXCHAR i_cCh)
|
||||
{
|
||||
return wcsrchr(i_pStr, i_cCh);
|
||||
}//PStrrChr
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//PStrScan
|
||||
#define PStrScan(i_pBuffer, i_pFormat, ...) swscanf_s(i_pBuffer, i_pFormat, __VA_ARGS__)
|
||||
90
p7lib/Shared/Platforms/Windows_x86/PSystem.h
Normal file
90
p7lib/Shared/Platforms/Windows_x86/PSystem.h
Normal file
@ -0,0 +1,90 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef PSYSTEM_H
|
||||
#define PSYSTEM_H
|
||||
|
||||
class CSys
|
||||
{
|
||||
public:
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Host_Name
|
||||
static tBOOL Get_Host_Name(tWCHAR *o_pName, size_t i_szName)
|
||||
{
|
||||
if ( (NULL == o_pName)
|
||||
|| (32 >= i_szName)
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD l_dwMax_Len = (DWORD)i_szName;
|
||||
return GetComputerNameW((wchar_t*)o_pName, &l_dwMax_Len);
|
||||
}//Get_Host_Name
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//Get_Host_Name
|
||||
static tBOOL Get_Host_Name(tACHAR *o_pName, size_t i_szName)
|
||||
{
|
||||
const size_t l_szName = 256;
|
||||
DWORD l_dwSize = (DWORD)l_szName;
|
||||
wchar_t l_pName[l_szName];
|
||||
|
||||
if (GetComputerNameW((wchar_t*)l_pName, &l_dwSize))
|
||||
{
|
||||
Convert_UTF16_To_UTF8(l_pName, o_pName, (tUINT32)i_szName);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy_s(o_pName, i_szName, "Unknown:Error");
|
||||
}
|
||||
return TRUE;
|
||||
}//Get_Host_Name
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//Get_DateTime
|
||||
static tBOOL Get_DateTime(tUINT32 &o_rYear,
|
||||
tUINT32 &o_rMonth,
|
||||
tUINT32 &o_rDay,
|
||||
tUINT32 &o_rHour,
|
||||
tUINT32 &o_rMinute,
|
||||
tUINT32 &o_rSecond,
|
||||
tUINT32 &o_rmSec
|
||||
)
|
||||
{
|
||||
SYSTEMTIME l_sTitem = {0};
|
||||
GetLocalTime(&l_sTitem);
|
||||
|
||||
o_rYear = (tUINT32)l_sTitem.wYear;
|
||||
o_rMonth = (tUINT32)l_sTitem.wMonth;
|
||||
o_rDay = (tUINT32)l_sTitem.wDay;
|
||||
o_rHour = (tUINT32)l_sTitem.wHour;
|
||||
o_rMinute = (tUINT32)l_sTitem.wMinute;
|
||||
o_rSecond = (tUINT32)l_sTitem.wSecond;
|
||||
o_rmSec = (tUINT32)l_sTitem.wMilliseconds;
|
||||
|
||||
return TRUE;
|
||||
}//Get_Host_Name
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //PSYSTEM_H
|
||||
103
p7lib/Shared/Platforms/Windows_x86/PThreadShell.h
Normal file
103
p7lib/Shared/Platforms/Windows_x86/PThreadShell.h
Normal file
@ -0,0 +1,103 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include <process.h>
|
||||
|
||||
#define THSHELL_CALL_TYPE __stdcall
|
||||
#define THSHELL_RET_TYPE tUINT32
|
||||
|
||||
#define THSHELL_RET_OK 0
|
||||
#define THSHELL_RET_NOK 1
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class CThShell
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Base types
|
||||
typedef HANDLE tTHREAD;
|
||||
typedef THSHELL_RET_TYPE (THSHELL_CALL_TYPE *tpThreadProc)(void *i_pParameter);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Create
|
||||
static tBOOL Create(tpThreadProc i_pThread_Proc,
|
||||
void *i_pPrm,
|
||||
tTHREAD *o_pThread,
|
||||
const tXCHAR *i_pName
|
||||
)
|
||||
{
|
||||
if ( ( NULL == i_pThread_Proc )
|
||||
|| ( NULL == o_pThread )
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*o_pThread = (tTHREAD)_beginthreadex( NULL,
|
||||
0,
|
||||
i_pThread_Proc,
|
||||
i_pPrm,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
|
||||
//SetThreadName( *pThread_id, thread_name);
|
||||
|
||||
return (*o_pThread) ? TRUE : FALSE;
|
||||
}//Create
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Cleanup
|
||||
static void Cleanup()
|
||||
{
|
||||
_endthreadex( 0 );
|
||||
}//Thread_Cleanup
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Close
|
||||
static tBOOL Close(tTHREAD i_hThread, tUINT32 i_dwTimeOut)
|
||||
{
|
||||
if (NULL == i_hThread)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( WAIT_OBJECT_0 == WaitForSingleObject( i_hThread, i_dwTimeOut ) )
|
||||
{
|
||||
CloseHandle(i_hThread);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}//Close
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Sleep
|
||||
static void Sleep(tUINT32 i_dwTimeOut)
|
||||
{
|
||||
::Sleep(i_dwTimeOut);
|
||||
}//Sleep
|
||||
};
|
||||
|
||||
204
p7lib/Shared/Platforms/Windows_x86/PTime.h
Normal file
204
p7lib/Shared/Platforms/Windows_x86/PTime.h
Normal file
@ -0,0 +1,204 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#define TIME_HRS_100NS 36000000000ull
|
||||
#define TIME_MIN_100NS 600000000ull
|
||||
#define TIME_SEC_100NS 10000000ull
|
||||
#define TIME_MSC_100NS 10000ull
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetTickCount - exist in OS
|
||||
//tUINT32 GetTickCount()
|
||||
//{
|
||||
//}//GetTickCount
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetPerformanceCounter
|
||||
static inline tUINT64 GetPerformanceCounter()
|
||||
{
|
||||
LARGE_INTEGER l_qwValue;
|
||||
l_qwValue.QuadPart = 0;
|
||||
QueryPerformanceCounter(&l_qwValue);
|
||||
return l_qwValue.QuadPart;
|
||||
}//GetPerformanceCounter
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetPerformanceFrequency
|
||||
static inline tUINT64 GetPerformanceFrequency()
|
||||
{
|
||||
LARGE_INTEGER l_qwValue;
|
||||
l_qwValue.QuadPart = 0;
|
||||
QueryPerformanceFrequency(&l_qwValue);
|
||||
return l_qwValue.QuadPart;
|
||||
}//GetPerformanceFrequency
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetEpochTime
|
||||
//return a 64-bit value of 100-nanosecond intervals since January 1, 1601 (UTC).
|
||||
static inline void GetEpochTime(tUINT32 *o_pHi, tUINT32 *o_pLow)
|
||||
{
|
||||
SYSTEMTIME l_sSTime = {0};
|
||||
FILETIME l_sFTime = {0};
|
||||
GetSystemTime(&l_sSTime);
|
||||
|
||||
SystemTimeToFileTime(&l_sSTime, &l_sFTime);
|
||||
if (o_pHi)
|
||||
{
|
||||
*o_pHi = l_sFTime.dwHighDateTime;
|
||||
}
|
||||
|
||||
if (o_pLow)
|
||||
{
|
||||
*o_pLow = l_sFTime.dwLowDateTime;
|
||||
}
|
||||
}//GetEpochTime
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//UnpackLocalTime
|
||||
//convert a 64-bit value of 100-nanosecond intervals since January 1, 1601 (UTC)
|
||||
//to readable form
|
||||
static inline void UnpackLocalTime(tUINT64 i_qwTime,
|
||||
tUINT32 &o_rYear,
|
||||
tUINT32 &o_rMonth,
|
||||
tUINT32 &o_rDay,
|
||||
tUINT32 &o_rHour,
|
||||
tUINT32 &o_rMinutes,
|
||||
tUINT32 &o_rSeconds,
|
||||
tUINT32 &o_rMilliseconds,
|
||||
tUINT32 &o_rMicroseconds,
|
||||
tUINT32 &o_rNanoseconds
|
||||
)
|
||||
{
|
||||
tUINT32 l_dwReminder = i_qwTime % TIME_MSC_100NS; //micro & 100xNanoseconds
|
||||
tUINT32 l_dwNano = i_qwTime % 10;
|
||||
tUINT32 l_dwMicro = l_dwReminder / 10;
|
||||
|
||||
i_qwTime -= l_dwReminder;
|
||||
|
||||
SYSTEMTIME l_sTime = {0};
|
||||
FILETIME l_sLocalTime = {0};
|
||||
|
||||
FileTimeToLocalFileTime((FILETIME*)&i_qwTime, &l_sLocalTime);
|
||||
FileTimeToSystemTime(&l_sLocalTime, &l_sTime);
|
||||
|
||||
o_rYear = l_sTime.wYear;
|
||||
o_rMonth = l_sTime.wMonth;
|
||||
o_rDay = l_sTime.wDay;
|
||||
o_rHour = l_sTime.wHour;
|
||||
o_rMinutes = l_sTime.wMinute;
|
||||
o_rSeconds = l_sTime.wSecond;
|
||||
o_rMilliseconds = l_sTime.wMilliseconds;
|
||||
o_rMicroseconds = l_dwMicro;
|
||||
o_rNanoseconds = l_dwNano;
|
||||
}//UnpackLocalTime
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//PackLocalTime
|
||||
//convert date & time to 64-bit value of 100-nanosecond intervals since January 1, 1601 (UTC)
|
||||
tUINT64 static inline PackLocalTime(tUINT32 i_uiYear,
|
||||
tUINT32 i_uiMonth,
|
||||
tUINT32 i_uiDay,
|
||||
tUINT32 i_uiHour,
|
||||
tUINT32 i_uiMinutes,
|
||||
tUINT32 i_uiSeconds,
|
||||
tUINT32 i_uiMilliseconds,
|
||||
tUINT32 i_uiMicroseconds,
|
||||
tUINT32 i_uiNanoseconds
|
||||
)
|
||||
{
|
||||
FILETIME l_sLocal = {0};
|
||||
FILETIME l_sSystem = {0};
|
||||
SYSTEMTIME l_sTime = {0};
|
||||
|
||||
l_sTime.wYear = (WORD)i_uiYear;
|
||||
l_sTime.wMonth = (WORD)i_uiMonth;
|
||||
l_sTime.wDay = (WORD)i_uiDay;
|
||||
l_sTime.wHour = (WORD)i_uiHour;
|
||||
l_sTime.wMinute = (WORD)i_uiMinutes;
|
||||
l_sTime.wSecond = (WORD)i_uiSeconds;
|
||||
l_sTime.wMilliseconds = (WORD)i_uiMilliseconds;
|
||||
|
||||
SystemTimeToFileTime(&l_sTime, &l_sLocal);
|
||||
LocalFileTimeToFileTime(&l_sLocal, &l_sSystem);
|
||||
|
||||
tUINT64 l_qwReturn = ((tUINT64)(l_sSystem.dwHighDateTime) << 32) + (tUINT64)(l_sSystem.dwLowDateTime);
|
||||
|
||||
l_qwReturn += (i_uiMicroseconds * 10ull) + (i_uiNanoseconds / 100ull);
|
||||
|
||||
return l_qwReturn;
|
||||
}//PackLocalTime
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetSecondOfDay
|
||||
static inline tUINT32 GetSecondOfDay()
|
||||
{
|
||||
SYSTEMTIME l_sTime = {0};
|
||||
|
||||
GetLocalTime(&l_sTime);
|
||||
|
||||
return 3600 * (tUINT32)l_sTime.wHour + (tUINT32)l_sTime.wMinute * 60 + (tUINT32)l_sTime.wSecond;
|
||||
}//GetSecondOfDay
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetEpochTime
|
||||
//return a 64-bit value of 100-nanosecond intervals since January 1, 1601 (UTC).
|
||||
static inline tUINT64 GetEpochTime()
|
||||
{
|
||||
SYSTEMTIME l_sSTime = {0};
|
||||
FILETIME l_sFTime = {0};
|
||||
GetSystemTime(&l_sSTime);
|
||||
|
||||
SystemTimeToFileTime(&l_sSTime, &l_sFTime);
|
||||
|
||||
return (((tUINT64)l_sFTime.dwHighDateTime) << 32ull) + (tUINT64)l_sFTime.dwLowDateTime;
|
||||
}//GetEpochTime
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetEpochLocalTime
|
||||
//return a 64-bit value of 100-nanosecond intervals since January 1, 1601 (UTC).
|
||||
static inline tUINT64 GetEpochLocalTime()
|
||||
{
|
||||
SYSTEMTIME l_sSTime = {0};
|
||||
FILETIME l_sFTime = {0};
|
||||
GetLocalTime(&l_sSTime);
|
||||
|
||||
SystemTimeToFileTime(&l_sSTime, &l_sFTime);
|
||||
|
||||
return (((tUINT64)l_sFTime.dwHighDateTime) << 32ull) + (tUINT64)l_sFTime.dwLowDateTime;
|
||||
}//GetEpochTime
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//GetUtcOffsetSeconds
|
||||
//return UTC0 offset in seconds
|
||||
static inline tINT32 GetUtcOffsetSeconds()
|
||||
{
|
||||
TIME_ZONE_INFORMATION l_sTZ = {};
|
||||
GetTimeZoneInformation(&l_sTZ);
|
||||
return (tINT32)l_sTZ.Bias * -60;
|
||||
}
|
||||
421
p7lib/Shared/Predicate.h
Normal file
421
p7lib/Shared/Predicate.h
Normal file
@ -0,0 +1,421 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#define PR_USE_REGEXP
|
||||
|
||||
#if defined(PR_USE_REGEXP)
|
||||
#pragma warning(disable : 4995 )
|
||||
#include <QRegExp>
|
||||
#include <QString>
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
enum ePr_VType
|
||||
{
|
||||
EPR_VTYPE_UNK = -1,
|
||||
EPR_VTYPE_INT = 0,
|
||||
EPR_VTYPE_FLOAT ,
|
||||
EPR_VTYPE_DATE ,
|
||||
EPR_VTYPE_WTEXT ,
|
||||
EPR_VTYPE_ENUM //user enumes +1, +2, +3, ... etc
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
enum ePr_Op
|
||||
{
|
||||
EPR_OP_UNK = -1, //
|
||||
EPR_OP_EQUAL = 0, //=
|
||||
EPR_OP_NOT_EQUAL , //!=
|
||||
EPR_OP_GREATER , //>
|
||||
EPR_OP_GREATER_OR_EQUAL , //>=
|
||||
EPR_OP_LESS , //<
|
||||
EPR_OP_LESS_OR_EQUAL , //<=
|
||||
EPR_OP_LEFT_INCLUDE , //<<
|
||||
EPR_OP_RIGHT_INCLUDE , //>>
|
||||
EPR_OP_LEFT_NOT_INCLUDE , //<!
|
||||
EPR_OP_RIGHT_NOT_INCLUDE , //!>
|
||||
|
||||
#if defined(PR_USE_REGEXP)
|
||||
EPR_OP_REG_EXP , //r=
|
||||
EPR_OP_WILD_CARD //w=
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
struct sPr_Op_Text
|
||||
{
|
||||
const tXCHAR *pText;
|
||||
tUINT32 dwLen;
|
||||
ePr_Op eType;
|
||||
ePr_Op eRevers;
|
||||
tBOOL bDigit;
|
||||
};
|
||||
|
||||
static const sPr_Op_Text g_pOperators[] =
|
||||
{
|
||||
{ TM("<="), 2, EPR_OP_LESS_OR_EQUAL, EPR_OP_GREATER_OR_EQUAL, TRUE },
|
||||
{ TM("<<"), 2, EPR_OP_LEFT_INCLUDE, EPR_OP_RIGHT_INCLUDE, FALSE},
|
||||
{ TM(">>"), 2, EPR_OP_RIGHT_INCLUDE, EPR_OP_LEFT_INCLUDE, FALSE},
|
||||
{ TM("<!"), 2, EPR_OP_LEFT_NOT_INCLUDE, EPR_OP_RIGHT_NOT_INCLUDE, FALSE},
|
||||
{ TM("!>"), 2, EPR_OP_RIGHT_NOT_INCLUDE,EPR_OP_LEFT_NOT_INCLUDE, FALSE},
|
||||
{ TM("!="), 2, EPR_OP_NOT_EQUAL, EPR_OP_NOT_EQUAL, TRUE },
|
||||
{ TM(">="), 2, EPR_OP_GREATER_OR_EQUAL, EPR_OP_LESS_OR_EQUAL, TRUE },
|
||||
{ TM("="), 1, EPR_OP_EQUAL, EPR_OP_EQUAL, TRUE },
|
||||
{ TM(">"), 1, EPR_OP_GREATER, EPR_OP_LESS, TRUE },
|
||||
{ TM("<"), 1, EPR_OP_LESS, EPR_OP_GREATER, TRUE },
|
||||
|
||||
#if defined(PR_USE_REGEXP)
|
||||
{ TM("r="), 2, EPR_OP_REG_EXP, EPR_OP_REG_EXP, FALSE},
|
||||
{ TM("w="), 2, EPR_OP_WILD_CARD, EPR_OP_WILD_CARD, FALSE},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
struct sPr_Var
|
||||
{
|
||||
tXCHAR *m_pName;
|
||||
ePr_VType m_eType;
|
||||
tUINT32 m_dwLength; //length of the text if it is
|
||||
tBOOL m_bUsed;
|
||||
|
||||
union
|
||||
{
|
||||
tXCHAR *m_pValue;
|
||||
tUINT64 m_qwValue;
|
||||
double m_dbValue;
|
||||
};
|
||||
|
||||
sPr_Var(tXCHAR *i_pName, ePr_VType i_eType)
|
||||
: m_pName(NULL)
|
||||
, m_eType(i_eType)
|
||||
, m_dwLength(0)
|
||||
, m_bUsed(FALSE)
|
||||
, m_qwValue(0) //the largest value in union
|
||||
{
|
||||
tUINT32 l_dwLen = (i_pName) ? PStrLen(i_pName) : 0;
|
||||
|
||||
if (l_dwLen)
|
||||
{
|
||||
m_pName = new tXCHAR[l_dwLen + 1];
|
||||
if (m_pName)
|
||||
{
|
||||
PStrCpy(m_pName, l_dwLen + 1, i_pName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~sPr_Var()
|
||||
{
|
||||
if (m_pName)
|
||||
{
|
||||
delete [] m_pName;
|
||||
m_pName = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
struct sPr_Enum_Item
|
||||
{
|
||||
tXCHAR *m_pName;
|
||||
int m_iValue;
|
||||
|
||||
sPr_Enum_Item(tXCHAR *i_pName, int i_iValue)
|
||||
: m_pName(NULL)
|
||||
, m_iValue(i_iValue)
|
||||
{
|
||||
tUINT32 l_dwLen = (i_pName) ? PStrLen(i_pName) : 0;
|
||||
|
||||
if (l_dwLen)
|
||||
{
|
||||
m_pName = new tXCHAR[l_dwLen + 1];
|
||||
if (m_pName)
|
||||
{
|
||||
PStrCpy(m_pName, l_dwLen + 1, i_pName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~sPr_Enum_Item()
|
||||
{
|
||||
if (m_pName)
|
||||
{
|
||||
delete [] m_pName;
|
||||
m_pName = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
struct sPr_Enum
|
||||
{
|
||||
tUINT32 m_dwID;
|
||||
CBList<sPr_Enum_Item*> m_cItems;
|
||||
|
||||
sPr_Enum(tUINT32 i_dwID) : m_dwID(i_dwID) {}
|
||||
~sPr_Enum()
|
||||
{
|
||||
m_cItems.Clear(TRUE);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
struct sPr_Group;
|
||||
|
||||
struct sPr_Node
|
||||
{
|
||||
union
|
||||
{
|
||||
sPr_Group *m_pGroup;
|
||||
tXCHAR *m_pValue;
|
||||
tUINT64 m_qwValue;
|
||||
double m_dbValue;
|
||||
};
|
||||
|
||||
tBOOL m_bLink; //if TRUE we use m_pGroup, otherwise - values
|
||||
ePr_Op m_eOperator;
|
||||
tUINT32 m_dwLength; //length of the text if it is
|
||||
sPr_Var *m_pVariable;
|
||||
#if defined(PR_USE_REGEXP)
|
||||
QRegExp *m_pRE;
|
||||
#endif
|
||||
|
||||
sPr_Node();
|
||||
~sPr_Node();
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
struct sPr_OrGroup
|
||||
{
|
||||
CBList<sPr_Node*> m_cNodes;
|
||||
|
||||
~sPr_OrGroup()
|
||||
{
|
||||
m_cNodes.Clear(TRUE);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
struct sPr_Group
|
||||
{
|
||||
CBList<sPr_OrGroup*> m_cOrGroups;
|
||||
|
||||
~sPr_Group()
|
||||
{
|
||||
m_cOrGroups.Clear(TRUE);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//Normal class usage
|
||||
//1. Create child class with yours structure
|
||||
//2. Implement abstract function Set_Data()
|
||||
//3. Set variables list using Set_Variables()
|
||||
//4. If you are using enums - use Set_Enum()
|
||||
//5. Set predicate string - Set_Predicate()
|
||||
//6. Use Compare() to compare you structure using predicate
|
||||
//
|
||||
//See usage example at the end of this header file
|
||||
class CPredicate
|
||||
{
|
||||
protected:
|
||||
tXCHAR *m_pPr;
|
||||
tUINT32 m_dwPr_Max;
|
||||
tUINT32 m_dwPr_Len;
|
||||
|
||||
CBList<sPr_Var*> m_cVars;
|
||||
CBList<sPr_Enum*> m_cEnums;
|
||||
sPr_Group m_cGroup;
|
||||
tXCHAR m_cError[512];
|
||||
public:
|
||||
CPredicate();
|
||||
virtual ~CPredicate();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Predicate (i_pPr) consist of next part
|
||||
//Variables - %MyVariable%
|
||||
//Constants - "0x20" possible values Int, Float, Date, String, Enum. Date
|
||||
// has simple format "DD.MM.YYYY HH:MM:SS.MS"
|
||||
//Atoms - atom is working block, you compare variable and constant. It
|
||||
// is not possible to compare 2 variables, only variable and
|
||||
// constant, next operators are available: "<=", "<<", ">>", "<!"
|
||||
// "!>", "!=", ">=", "=", ">", "<". Operators "<<", ">>" used
|
||||
// only for text ("T1 << T2" - T1 contains T2)
|
||||
//Grouping - "(" and ")"
|
||||
//Operators - "&", "|"
|
||||
//Examples:
|
||||
//$Var1$ >="0x10" & "Text" >> $Var2$
|
||||
//$Var1$ >="500" & ("Text" >> $Var2$ | "Text1" >> $Var2$)
|
||||
virtual tBOOL Set_Predicate(const tXCHAR *i_pPr);
|
||||
tXCHAR *Get_Error();
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Set_Variables()
|
||||
// i_dwCount - count of the variables, each variable has 2 values
|
||||
// tXCHAR - name of the variable, allowed any characters
|
||||
// ePr_VType - type of the variable
|
||||
// ... - variables (2 value: name & type)
|
||||
tBOOL Set_Variables(tUINT32 i_dwCount, ...);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//Set_Enum()
|
||||
// i_dwEnum_ID - ID of the enum, EPR_VTYPE_ENUM, EPR_VTYPE_ENUM + 1, ... etc
|
||||
// i_dwCount - count of the enum values. Each value has 2 fields
|
||||
// tXCHAR - text value representation
|
||||
// int - int value representation
|
||||
// ... - enum values (2 fields: text & int)
|
||||
tBOOL Set_Enum(tUINT32 i_dwEnum_ID, tUINT32 i_dwCount, ...);
|
||||
|
||||
|
||||
tBOOL Check(const void *i_pData);
|
||||
protected:
|
||||
tBOOL Check(sPr_Group *i_pGroup);
|
||||
|
||||
tBOOL Build(sPr_Group *i_pGroup, tUINT32 *io_pOffset);
|
||||
tBOOL Add_Node(CBList<sPr_Node*> *i_pNodes, tUINT32 *io_pOffset);
|
||||
tBOOL Fill_Node(sPr_Node *i_pNode,
|
||||
tXCHAR *i_pVariable,
|
||||
tXCHAR *i_pConst
|
||||
);
|
||||
|
||||
tBOOL Is_True(sPr_Node *i_pNode);
|
||||
|
||||
tBOOL Is_Sub(tXCHAR *i_pString,
|
||||
tUINT32 i_dwLenght,
|
||||
tXCHAR *i_pSearch,
|
||||
tUINT32 i_dwSub_Len
|
||||
);
|
||||
|
||||
//re-implement this function, you should get yours input structure and
|
||||
//every field put to the m_cVars list.
|
||||
virtual tBOOL Fill_Variables(const void *i_pData) = 0;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Predicate Example
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
// enum eTest1
|
||||
// {
|
||||
// ETEST1_ENUM0 = 0,
|
||||
// ETEST1_ENUM1 = 1,
|
||||
// ETEST1_ENUM2 = 2,
|
||||
// ETEST1_ENUM3 = 3
|
||||
// };
|
||||
//
|
||||
// struct sTest1
|
||||
// {
|
||||
// tUINT32 m_dwInt;
|
||||
// eTest1 m_eEnum;
|
||||
// tXCHAR *m_pText;
|
||||
// };
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// class CMy_Pred:
|
||||
// public CPredicate
|
||||
// {
|
||||
// public:
|
||||
// CMy_Pred():
|
||||
// CPredicate()
|
||||
// {
|
||||
// Set_Variables(3,
|
||||
// TM("Int"), EPR_VTYPE_INT, //Index = 0;
|
||||
// TM("Enum"), EPR_VTYPE_ENUM + 0, //Index = 1;
|
||||
// TM("Text"), EPR_VTYPE_WTEXT //Index = 2;
|
||||
// );
|
||||
//
|
||||
// Set_Enum(EPR_VTYPE_ENUM + 0,
|
||||
// 4,
|
||||
// TM("ENUM0"), 0, //ETEST1_ENUM0 = 0,
|
||||
// TM("ENUM1"), 1, //ETEST1_ENUM1 = 1,
|
||||
// TM("ENUM2"), 2, //ETEST1_ENUM2 = 2,
|
||||
// TM("ENUM3"), 3 //ETEST1_ENUM3 = 3
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// protected:
|
||||
// BOOL Fill_Variables(void *i_pData)
|
||||
// {
|
||||
// sPr_Var *l_pVar = m_cVars[0];//Index = 0, first declared variable "Int"
|
||||
// if (l_pVar->m_bUsed)
|
||||
// {
|
||||
// l_pVar->m_qwValue = ((sTest1*)i_pData)->m_dwInt;
|
||||
// }
|
||||
//
|
||||
// l_pVar = m_cVars[1]; //Index = 1, second declared variable "Enum"
|
||||
// if (l_pVar->m_bUsed)
|
||||
// {
|
||||
// l_pVar->m_qwValue = ((sTest1*)i_pData)->m_eEnum;
|
||||
// }
|
||||
//
|
||||
// l_pVar = m_cVars[2]; //Index = 2, third declared variable "Text"
|
||||
// if (l_pVar->m_bUsed)
|
||||
// {
|
||||
// l_pVar->m_pValue = ((sTest1*)i_pData)->m_pText;
|
||||
//
|
||||
// //Very important to set Text length !!!!
|
||||
// if (l_pVar->m_pValue)
|
||||
// {
|
||||
// l_pVar->m_dwLength = PStrLen(l_pVar->m_pValue);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// l_pVar->m_dwLength = 0;
|
||||
// }
|
||||
// }
|
||||
// return TRUE;
|
||||
// }
|
||||
// };
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// int wmain(int i_iArgC, tXCHAR* i_pArgV[])
|
||||
// {
|
||||
// CMy_Pred l_cPred;
|
||||
// sTest1 l_sTest = {10, ETEST1_ENUM2, TM("My Name")};
|
||||
//
|
||||
// if (FALSE == l_cPred.Set_Predicate(TM("$Enum$ <= \"ENUM2\" & ($Int$ >= \"0x9\" | $Text$ >> \"Andrey is My Name\")")))
|
||||
// {
|
||||
// wprintf(l_cPred.Get_Error());
|
||||
// }
|
||||
//
|
||||
// if (l_cPred.Check(&l_sTest))
|
||||
// {
|
||||
// wprintf(TM("TRUE\n"));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// wprintf(TM("FALSE\n"));
|
||||
// }
|
||||
//
|
||||
// return 0;
|
||||
// }
|
||||
41
p7lib/Shared/QStringHelper.h
Normal file
41
p7lib/Shared/QStringHelper.h
Normal file
@ -0,0 +1,41 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// /
|
||||
// 2012-2020 (c) Baical /
|
||||
// /
|
||||
// This library is free software; you can redistribute it and/or /
|
||||
// modify it under the terms of the GNU Lesser General Public /
|
||||
// License as published by the Free Software Foundation; either /
|
||||
// version 3.0 of the License, or (at your option) any later version. /
|
||||
// /
|
||||
// This library is distributed in the hope that it will be useful, /
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
||||
// Lesser General Public License for more details. /
|
||||
// /
|
||||
// You should have received a copy of the GNU Lesser General Public /
|
||||
// License along with this library. /
|
||||
// /
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef QSTRING_HELPER_H
|
||||
#define QSTRING_HELPER_H
|
||||
|
||||
#if defined(UTF8_ENCODING)
|
||||
#define XCHAR_TO_QSTRING(X) QString::fromUtf8(X)
|
||||
#else
|
||||
#define XCHAR_TO_QSTRING(X) QString::fromWCharArray(X)
|
||||
#endif
|
||||
|
||||
#if defined(UTF8_ENCODING)
|
||||
#define QSTRING_TO_XCHAR_TRANSLATE(QbAUniq, QStr, XChar)\
|
||||
QByteArray QbAUniq = QStr.toUtf8();\
|
||||
XChar = (const tXCHAR*)QbAUniq.constData()
|
||||
#define QSTRING_TO_XCHAR(QStr, XChar) QSTRING_TO_XCHAR_TRANSLATE(MAKE_UNIQUE(QbA), QStr, XChar)
|
||||
#else
|
||||
#define QSTRING_TO_XCHAR_TRANSLATE(QbAUniq, QStr, XChar)\
|
||||
QString QbAUniq = QStr;\
|
||||
XChar = (const tXCHAR*)QbAUniq.utf16()
|
||||
#define QSTRING_TO_XCHAR(QStr, XChar) QSTRING_TO_XCHAR_TRANSLATE(MAKE_UNIQUE(QbA), QStr, XChar)
|
||||
#endif
|
||||
|
||||
|
||||
#endif //QSTRING_HELPER_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user