From 850210a9b2a41152f50ee69027ca56e823966901 Mon Sep 17 00:00:00 2001 From: Duc Date: Fri, 14 Mar 2025 14:19:50 -0700 Subject: [PATCH] Initial check-in --- .gitattributes | 63 +++ .gitignore | 366 ++++++++++++++- CommonLib/.cproject | 146 ++++++ CommonLib/.project | 27 ++ CommonLib/.settings/language.settings.xml | 25 + .../.settings/org.eclipse.cdt.core.prefs | 6 + .../org.eclipse.core.resources.prefs | 2 + .../AutomationMsgHandler.cpp | 176 +++++++ .../AutomationMsgHandler.hpp | 98 ++++ .../AutomationMsgParser.cpp | 164 +++++++ .../AutomationMsgParser.hpp | 78 ++++ .../AutomationMessages/GenericRspMessage.cpp | 103 ++++ .../AutomationMessages/GenericRspMessage.hpp | 122 +++++ .../src/Common/AutomationMessages/Message.cpp | 176 +++++++ .../src/Common/AutomationMessages/Message.hpp | 241 ++++++++++ .../AutomationMessages/MessageHeader.cpp | 86 ++++ .../AutomationMessages/MessageHeader.hpp | 145 ++++++ .../Common/AutomationMessages/MessageIDs.hpp | 16 + .../MoveGutsVideosToSubFolderCmdMessage.cpp | 117 +++++ .../MoveGutsVideosToSubFolderCmdMessage.hpp | 104 +++++ .../TransferAFileCmdMessage.cpp | 123 +++++ .../TransferAFileCmdMessage.hpp | 108 +++++ .../TransferGutsVideosCmdMessage.cpp | 153 ++++++ .../TransferGutsVideosCmdMessage.hpp | 126 +++++ .../WaitForLastTaskCompletionCmdMessage.cpp | 82 ++++ .../WaitForLastTaskCompletionCmdMessage.hpp | 105 +++++ CommonLib/src/Common/Comm/CommInterface.hpp | 70 +++ CommonLib/src/Common/Comm/UdpSocket.cpp | 131 ++++++ CommonLib/src/Common/Comm/UdpSocket.hpp | 93 ++++ CommonLib/src/Common/Exceptions/Exception.cpp | 110 +++++ CommonLib/src/Common/Exceptions/Exception.hpp | 106 +++++ .../src/Common/Exceptions/TimeoutError.cpp | 17 + .../src/Common/Exceptions/TimeoutError.hpp | 37 ++ CommonLib/src/Common/Lib/Condition.cpp | 333 +++++++++++++ CommonLib/src/Common/Lib/Condition.hpp | 106 +++++ CommonLib/src/Common/Lib/Constants.hpp | 9 + CommonLib/src/Common/Lib/ErrorLog.cpp | 87 ++++ CommonLib/src/Common/Lib/ErrorLog.hpp | 40 ++ CommonLib/src/Common/Lib/IniFile.cpp | 439 ++++++++++++++++++ CommonLib/src/Common/Lib/IniFile.hpp | 224 +++++++++ CommonLib/src/Common/Lib/LockMutex.cpp | 39 ++ CommonLib/src/Common/Lib/LockMutex.hpp | 37 ++ CommonLib/src/Common/Lib/Mutex.cpp | 110 +++++ CommonLib/src/Common/Lib/Mutex.hpp | 71 +++ CommonLib/src/Common/Lib/OSObject.cpp | 20 + CommonLib/src/Common/Lib/OSObject.hpp | 73 +++ CommonLib/src/Common/Lib/Semaphore.cpp | 103 ++++ CommonLib/src/Common/Lib/Semaphore.hpp | 61 +++ CommonLib/src/Common/Lib/Thread.cpp | 123 +++++ CommonLib/src/Common/Lib/Thread.hpp | 146 ++++++ CommonLib/src/Common/Lib/Timestamp.cpp | 153 ++++++ CommonLib/src/Common/Lib/Timestamp.hpp | 169 +++++++ .../src/Common/Lib/Util/DateTimeUtil.cpp | 30 ++ .../src/Common/Lib/Util/DateTimeUtil.hpp | 25 + .../src/Common/Lib/Util/FileSystemUtil.cpp | 291 ++++++++++++ .../src/Common/Lib/Util/FileSystemUtil.hpp | 147 ++++++ CommonLib/src/Common/Lib/Util/MiscUtil.cpp | 139 ++++++ CommonLib/src/Common/Lib/Util/MiscUtil.hpp | 72 +++ CommonLib/src/Common/Lib/Util/NetworkUtil.cpp | 100 ++++ CommonLib/src/Common/Lib/Util/NetworkUtil.hpp | 35 ++ .../src/Common/Lib/Util/PosixRegexUtil.cpp | 107 +++++ .../src/Common/Lib/Util/PosixRegexUtil.hpp | 46 ++ CommonLib/src/Common/Lib/Util/StringUtil.cpp | 304 ++++++++++++ CommonLib/src/Common/Lib/Util/StringUtil.hpp | 145 ++++++ CommonLib/src/Common/Mail/AckMail.cpp | 67 +++ CommonLib/src/Common/Mail/AckMail.hpp | 39 ++ CommonLib/src/Common/Mail/Mail.cpp | 123 +++++ CommonLib/src/Common/Mail/Mail.hpp | 48 ++ CommonLib/src/Common/Mail/MailHeader.cpp | 111 +++++ CommonLib/src/Common/Mail/MailHeader.hpp | 74 +++ CommonLib/src/Common/Mail/MailQueue.cpp | 128 +++++ CommonLib/src/Common/Mail/MailQueue.hpp | 35 ++ CommonLib/src/Common/Mail/Mailslot.cpp | 157 +++++++ CommonLib/src/Common/Mail/Mailslot.hpp | 32 ++ CommonLib/src/Common/Names/EventNames.cpp | 42 ++ CommonLib/src/Common/Names/EventNames.hpp | 30 ++ CommonLib/src/Common/Names/MailboxNames.cpp | 38 ++ CommonLib/src/Common/Names/MailboxNames.hpp | 27 ++ CommonLib/src/Common/Names/SemaphoreNames.cpp | 38 ++ CommonLib/src/Common/Names/SemaphoreNames.hpp | 28 ++ CommonLib/src/Common/Names/ThreadNames.cpp | 42 ++ CommonLib/src/Common/Names/ThreadNames.hpp | 29 ++ CommonLib/src/Common/Proc/Proc.cpp | 113 +++++ CommonLib/src/Common/Proc/Proc.hpp | 74 +++ CommonLib/src/LinuxProc.cpp | 61 +++ CommonLib/src/LinuxProc.hpp | 60 +++ CommonLib/src/main.cpp | 35 ++ git_scripts/ignore_a_tracked_file.sh | 11 + .../list_tracked_files_under_main_branch.sh | 3 + git_scripts/unignore_a_tracked_file.sh | 11 + 90 files changed, 8753 insertions(+), 9 deletions(-) create mode 100644 .gitattributes create mode 100644 CommonLib/.cproject create mode 100644 CommonLib/.project create mode 100644 CommonLib/.settings/language.settings.xml create mode 100644 CommonLib/.settings/org.eclipse.cdt.core.prefs create mode 100644 CommonLib/.settings/org.eclipse.core.resources.prefs create mode 100644 CommonLib/src/Common/AutomationMessages/AutomationMsgHandler.cpp create mode 100644 CommonLib/src/Common/AutomationMessages/AutomationMsgHandler.hpp create mode 100644 CommonLib/src/Common/AutomationMessages/AutomationMsgParser.cpp create mode 100644 CommonLib/src/Common/AutomationMessages/AutomationMsgParser.hpp create mode 100644 CommonLib/src/Common/AutomationMessages/GenericRspMessage.cpp create mode 100644 CommonLib/src/Common/AutomationMessages/GenericRspMessage.hpp create mode 100644 CommonLib/src/Common/AutomationMessages/Message.cpp create mode 100644 CommonLib/src/Common/AutomationMessages/Message.hpp create mode 100644 CommonLib/src/Common/AutomationMessages/MessageHeader.cpp create mode 100644 CommonLib/src/Common/AutomationMessages/MessageHeader.hpp create mode 100644 CommonLib/src/Common/AutomationMessages/MessageIDs.hpp create mode 100644 CommonLib/src/Common/AutomationMessages/MoveGutsVideosToSubFolderCmdMessage.cpp create mode 100644 CommonLib/src/Common/AutomationMessages/MoveGutsVideosToSubFolderCmdMessage.hpp create mode 100644 CommonLib/src/Common/AutomationMessages/TransferAFileCmdMessage.cpp create mode 100644 CommonLib/src/Common/AutomationMessages/TransferAFileCmdMessage.hpp create mode 100644 CommonLib/src/Common/AutomationMessages/TransferGutsVideosCmdMessage.cpp create mode 100644 CommonLib/src/Common/AutomationMessages/TransferGutsVideosCmdMessage.hpp create mode 100644 CommonLib/src/Common/AutomationMessages/WaitForLastTaskCompletionCmdMessage.cpp create mode 100644 CommonLib/src/Common/AutomationMessages/WaitForLastTaskCompletionCmdMessage.hpp create mode 100644 CommonLib/src/Common/Comm/CommInterface.hpp create mode 100644 CommonLib/src/Common/Comm/UdpSocket.cpp create mode 100644 CommonLib/src/Common/Comm/UdpSocket.hpp create mode 100644 CommonLib/src/Common/Exceptions/Exception.cpp create mode 100644 CommonLib/src/Common/Exceptions/Exception.hpp create mode 100644 CommonLib/src/Common/Exceptions/TimeoutError.cpp create mode 100644 CommonLib/src/Common/Exceptions/TimeoutError.hpp create mode 100644 CommonLib/src/Common/Lib/Condition.cpp create mode 100644 CommonLib/src/Common/Lib/Condition.hpp create mode 100644 CommonLib/src/Common/Lib/Constants.hpp create mode 100644 CommonLib/src/Common/Lib/ErrorLog.cpp create mode 100644 CommonLib/src/Common/Lib/ErrorLog.hpp create mode 100644 CommonLib/src/Common/Lib/IniFile.cpp create mode 100644 CommonLib/src/Common/Lib/IniFile.hpp create mode 100644 CommonLib/src/Common/Lib/LockMutex.cpp create mode 100644 CommonLib/src/Common/Lib/LockMutex.hpp create mode 100644 CommonLib/src/Common/Lib/Mutex.cpp create mode 100644 CommonLib/src/Common/Lib/Mutex.hpp create mode 100644 CommonLib/src/Common/Lib/OSObject.cpp create mode 100644 CommonLib/src/Common/Lib/OSObject.hpp create mode 100644 CommonLib/src/Common/Lib/Semaphore.cpp create mode 100644 CommonLib/src/Common/Lib/Semaphore.hpp create mode 100644 CommonLib/src/Common/Lib/Thread.cpp create mode 100644 CommonLib/src/Common/Lib/Thread.hpp create mode 100644 CommonLib/src/Common/Lib/Timestamp.cpp create mode 100644 CommonLib/src/Common/Lib/Timestamp.hpp create mode 100644 CommonLib/src/Common/Lib/Util/DateTimeUtil.cpp create mode 100644 CommonLib/src/Common/Lib/Util/DateTimeUtil.hpp create mode 100644 CommonLib/src/Common/Lib/Util/FileSystemUtil.cpp create mode 100644 CommonLib/src/Common/Lib/Util/FileSystemUtil.hpp create mode 100644 CommonLib/src/Common/Lib/Util/MiscUtil.cpp create mode 100644 CommonLib/src/Common/Lib/Util/MiscUtil.hpp create mode 100644 CommonLib/src/Common/Lib/Util/NetworkUtil.cpp create mode 100644 CommonLib/src/Common/Lib/Util/NetworkUtil.hpp create mode 100644 CommonLib/src/Common/Lib/Util/PosixRegexUtil.cpp create mode 100644 CommonLib/src/Common/Lib/Util/PosixRegexUtil.hpp create mode 100644 CommonLib/src/Common/Lib/Util/StringUtil.cpp create mode 100644 CommonLib/src/Common/Lib/Util/StringUtil.hpp create mode 100644 CommonLib/src/Common/Mail/AckMail.cpp create mode 100644 CommonLib/src/Common/Mail/AckMail.hpp create mode 100644 CommonLib/src/Common/Mail/Mail.cpp create mode 100644 CommonLib/src/Common/Mail/Mail.hpp create mode 100644 CommonLib/src/Common/Mail/MailHeader.cpp create mode 100644 CommonLib/src/Common/Mail/MailHeader.hpp create mode 100644 CommonLib/src/Common/Mail/MailQueue.cpp create mode 100644 CommonLib/src/Common/Mail/MailQueue.hpp create mode 100644 CommonLib/src/Common/Mail/Mailslot.cpp create mode 100644 CommonLib/src/Common/Mail/Mailslot.hpp create mode 100644 CommonLib/src/Common/Names/EventNames.cpp create mode 100644 CommonLib/src/Common/Names/EventNames.hpp create mode 100644 CommonLib/src/Common/Names/MailboxNames.cpp create mode 100644 CommonLib/src/Common/Names/MailboxNames.hpp create mode 100644 CommonLib/src/Common/Names/SemaphoreNames.cpp create mode 100644 CommonLib/src/Common/Names/SemaphoreNames.hpp create mode 100644 CommonLib/src/Common/Names/ThreadNames.cpp create mode 100644 CommonLib/src/Common/Names/ThreadNames.hpp create mode 100644 CommonLib/src/Common/Proc/Proc.cpp create mode 100644 CommonLib/src/Common/Proc/Proc.hpp create mode 100644 CommonLib/src/LinuxProc.cpp create mode 100644 CommonLib/src/LinuxProc.hpp create mode 100644 CommonLib/src/main.cpp create mode 100644 git_scripts/ignore_a_tracked_file.sh create mode 100644 git_scripts/list_tracked_files_under_main_branch.sh create mode 100644 git_scripts/unignore_a_tracked_file.sh diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore index c674098..9491a2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,363 @@ -# ---> Linux +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* *~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs -# temporary files which can be created if a process still has a handle open of a deleted file -.fuse_hidden* +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk -# KDE directory preferences -.directory +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ -# Linux trash folder which might appear on any partition or disk -.Trash-* +# RIA/Silverlight projects +Generated_Code/ -# .nfs files are created when an open file is removed but is still being accessed -.nfs* +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/CommonLib/.cproject b/CommonLib/.cproject new file mode 100644 index 0000000..63a0516 --- /dev/null +++ b/CommonLib/.cproject @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CommonLib/.project b/CommonLib/.project new file mode 100644 index 0000000..b243fd8 --- /dev/null +++ b/CommonLib/.project @@ -0,0 +1,27 @@ + + + CommonLib + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/CommonLib/.settings/language.settings.xml b/CommonLib/.settings/language.settings.xml new file mode 100644 index 0000000..a955046 --- /dev/null +++ b/CommonLib/.settings/language.settings.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CommonLib/.settings/org.eclipse.cdt.core.prefs b/CommonLib/.settings/org.eclipse.cdt.core.prefs new file mode 100644 index 0000000..c8ec5df --- /dev/null +++ b/CommonLib/.settings/org.eclipse.cdt.core.prefs @@ -0,0 +1,6 @@ +doxygen/doxygen_new_line_after_brief=true +doxygen/doxygen_use_brief_tag=false +doxygen/doxygen_use_javadoc_tags=true +doxygen/doxygen_use_pre_tag=false +doxygen/doxygen_use_structural_commands=false +eclipse.preferences.version=1 diff --git a/CommonLib/.settings/org.eclipse.core.resources.prefs b/CommonLib/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/CommonLib/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/CommonLib/src/Common/AutomationMessages/AutomationMsgHandler.cpp b/CommonLib/src/Common/AutomationMessages/AutomationMsgHandler.cpp new file mode 100644 index 0000000..c7db484 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/AutomationMsgHandler.cpp @@ -0,0 +1,176 @@ +#include +#include +#include +#include +#include + +#include "AutomationMsgHandler.hpp" +#include "Exception.hpp" +#include "MessageHeader.hpp" +#include "MessageIDs.hpp" +#include "ErrorLog.hpp" +#include "LinuxProc.hpp" +#include "IniFile.hpp" +#include "GenericRspMessage.hpp" +#include "Condition.hpp" + +#include "TransferGutsVideosCmdMessage.hpp" +#include "TransferAFileCmdMessage.hpp" +#include "MoveGutsVideosToSubFolderCmdMessage.hpp" +#include "WaitForLastTaskCompletionCmdMessage.hpp" +//----------------------------------------------------------------------------- + +AutomationMsgHandler::AutomationMsgHandler() +{ +} + +//----------------------------------------------------------------------------- + +AutomationMsgHandler::~AutomationMsgHandler(){} + +//----------------------------------------------------------------------------- + +AutomationMsgHandler& AutomationMsgHandler::Instance() +{ + static AutomationMsgHandler handler; + return handler; +} + +//----------------------------------------------------------------------------- + +void AutomationMsgHandler::handleMsg(const unsigned char* pData, const unsigned int& id) +{ + bool selfThrown = false; + try + { + MessageIDs::MsgIds msgId = (MessageIDs::MsgIds)id; + + if (msgId != MessageIDs::WAIT_FOR_COMPLETION_CMD) + WaitForLastTaskCompletionCmdMessage::s_commandCompletionSuccess = true; + + if (msgId == MessageIDs::TRANSFER_GUTS_VIDEOS_CMD) + { + handleTransferGutsVideosMessage(pData); + } + else if (msgId == MessageIDs::TRANSFER_A_FILE_CMD) + { + handleTransferAFileMessage(pData); + } + else if (msgId == MessageIDs::MOVE_GUTS_VIDEOS_TO_SUB_FOLDER_CMD) + { + handleMoveGutsVideosToSubFolderMessage(pData); + } + else if (msgId == MessageIDs::WAIT_FOR_COMPLETION_CMD) + { + handleWaitForLastTaskCompletionMessage(pData); + } + else + { + std::stringstream ss; + ss << "unknown message id: " << id; + + selfThrown = true; + throw Exception(__PRETTY_FUNCTION__," - " + ss.str()); + } + } + catch (Exception& e) + { + LinuxProc::Instance().getEvent(EventNames::COMMAND_EXECUTTION_IN_PROGRESS).reset(); + LinuxProc::Instance().getEvent(EventNames::COMMAND_EXECUTION_COMPLETE).signal(); + + WaitForLastTaskCompletionCmdMessage::s_commandCompletionSuccess = false; + + if (!selfThrown) + e.buildStackTrace(__PRETTY_FUNCTION__); + + throw e; + } +} + +//----------------------------------------------------------------------------- + +void AutomationMsgHandler::handleTransferGutsVideosMessage(const unsigned char* pData) +{ + try { + TransferGutsVideosCmdMessage cmd(""); + + cmd.parse(pData); + + if (LinuxProc::Instance().getConfig().getBool("GENERAL", "VERBOSE_LOGGING")) + ErrorLog::Instance().log(cmd.toString(), false, ErrorLog::INFO); + + cmd.executeMessage(); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + + throw e; + } +} + +//----------------------------------------------------------------------------- + +void AutomationMsgHandler::handleTransferAFileMessage(const unsigned char* pData) +{ + try { + TransferAFileCmdMessage cmd; + + cmd.parse(pData); + + if (LinuxProc::Instance().getConfig().getBool("GENERAL", "VERBOSE_LOGGING")) + ErrorLog::Instance().log(cmd.toString(), false, ErrorLog::INFO); + + cmd.executeMessage(); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + + throw e; + } +} + +//----------------------------------------------------------------------------- + +void AutomationMsgHandler::handleMoveGutsVideosToSubFolderMessage(const unsigned char* pData) +{ + try { + MoveGutsVideosToSubFolderCmdMessage cmd; + + cmd.parse(pData); + + if (LinuxProc::Instance().getConfig().getBool("GENERAL", "VERBOSE_LOGGING")) + ErrorLog::Instance().log(cmd.toString(), false, ErrorLog::INFO); + + cmd.executeMessage(); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + + throw e; + } +} + +//----------------------------------------------------------------------------- + +void AutomationMsgHandler::handleWaitForLastTaskCompletionMessage(const unsigned char* pData) +{ + try { + WaitForLastTaskCompletionCmdMessage cmd; + + cmd.parse(pData); + + if (LinuxProc::Instance().getConfig().getBool("GENERAL", "VERBOSE_LOGGING")) + ErrorLog::Instance().log(cmd.toString(), false, ErrorLog::INFO); + + cmd.executeMessage(); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + + throw e; + } +} diff --git a/CommonLib/src/Common/AutomationMessages/AutomationMsgHandler.hpp b/CommonLib/src/Common/AutomationMessages/AutomationMsgHandler.hpp new file mode 100644 index 0000000..c33d3b2 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/AutomationMsgHandler.hpp @@ -0,0 +1,98 @@ +#pragma once + +#include "MessageIDs.hpp" +#include + +class AutomationMsgHandler +{ +public: + //>--------------------------------------------------------------------------- + // Function: instance + // + // Purpose: singleton + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + static AutomationMsgHandler& Instance(); + + //>--------------------------------------------------------------------------- + // Function: ~Proc + // + // Purpose: Destroyer + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + ~AutomationMsgHandler(); + + //>--------------------------------------------------------------------------- + // Function: parseMsg + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + void handleMsg(const unsigned char* pData, const unsigned int& id); + + private: + //>--------------------------------------------------------------------------- + // Function: AutomationMsgHandler + // + // Purpose: Ctor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + AutomationMsgHandler(); + + //>--------------------------------------------------------------------------- + // Function: HandleTransferGutsVideosMessage + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + void handleTransferGutsVideosMessage(const unsigned char* pData); + + //>--------------------------------------------------------------------------- + // Function: HandleTransferAFileMessage + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + void handleTransferAFileMessage(const unsigned char* pData); + + //>--------------------------------------------------------------------------- + // Function: HandleMoveGutsVideosToSubFolderMessage + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + void handleMoveGutsVideosToSubFolderMessage(const unsigned char* pData); + + //>--------------------------------------------------------------------------- + // Function: HandleWaitForLastTaskCompletionMessage + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + void handleWaitForLastTaskCompletionMessage(const unsigned char* pData); +}; + diff --git a/CommonLib/src/Common/AutomationMessages/AutomationMsgParser.cpp b/CommonLib/src/Common/AutomationMessages/AutomationMsgParser.cpp new file mode 100644 index 0000000..e532da4 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/AutomationMsgParser.cpp @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include +#include + +#include "AutomationMsgParser.hpp" +#include "Exception.hpp" +#include "MessageHeader.hpp" +#include "MessageIDs.hpp" +#include "StringUtil.hpp" + +//----------------------------------------------------------------------------- + +AutomationMsgParser::AutomationMsgParser() +{ + gatherCmdMessageIds(); +} + +//----------------------------------------------------------------------------- + +AutomationMsgParser::~AutomationMsgParser(){} + +//----------------------------------------------------------------------------- + +AutomationMsgParser& AutomationMsgParser::Instance() +{ + static AutomationMsgParser parser; + return parser; +} + +//----------------------------------------------------------------------------- + +void AutomationMsgParser::gatherCmdMessageIds() +{ + try { + msgIdsVec.push_back(MessageIDs::TRANSFER_A_FILE_CMD); + msgIdsVec.push_back(MessageIDs::TRANSFER_A_FOLDER_CMD); + msgIdsVec.push_back(MessageIDs::TRANSFER_GUTS_VIDEOS_CMD); + msgIdsVec.push_back(MessageIDs::MOVE_GUTS_VIDEOS_TO_SUB_FOLDER_CMD); + msgIdsVec.push_back(MessageIDs::WAIT_FOR_COMPLETION_CMD); + + } catch (Exception& e) { + e.buildStackTrace(__PRETTY_FUNCTION__); + + throw e; + } +} + +//----------------------------------------------------------------------------- + +void AutomationMsgParser::parseMsg(unsigned char* pData, unsigned int numBytes, unsigned int* pMsgId) +{ + bool selfThrown = false; + try + { + MessageHeader header; + + if (numBytes < header.getHeaderLength()) + { + std::stringstream ss; + ss << "Number of bytes received: " << numBytes << ". Expected minimum: " << header.getHeaderLength(); + + selfThrown = true; + throw Exception(__PRETTY_FUNCTION__," - " + ss.str()); + } + + // check to see if we recognize the header + unsigned int msgId = 0; + unsigned int msgLen = 0; + + memcpy(&msgId, &pData[0], 4); + memcpy(&msgLen, &pData[4], 4); + + if (std::find(msgIdsVec.begin(), msgIdsVec.end(), msgId) == msgIdsVec.end()) + { + std::stringstream ss; + ss << "unexpected msg id: " << msgId; + + selfThrown = true; + throw Exception(__PRETTY_FUNCTION__," - " + ss.str()); + } + + if ( msgLen != numBytes) + { + std::stringstream ss; + ss << "Number of bytes received: " << numBytes << ". Expected only: " << msgLen; + + selfThrown = true; + throw Exception(__PRETTY_FUNCTION__," - " + ss.str()); + } + + if (numBytes > header.getHeaderLength()) + verifyDataFormat(pData, numBytes); + + *pMsgId = msgId; + } + catch (Exception& e) + { + if (!selfThrown) + e.buildStackTrace(__PRETTY_FUNCTION__); + + throw e; + } +} + +//----------------------------------------------------------------------------- + +void AutomationMsgParser::verifyDataFormat(unsigned char* pData, unsigned int numBytes) +{ + MessageHeader header; + bool selfThrown = false; + unsigned char* pTempDataStart = pData + header.getHeaderLength(); + unsigned char* pTempDataEnd = pData + numBytes - 1; + + // data format is + // [data header - 4 bytes][data - variable size] + // [data header][data][data header][data][data header][data][data header][data] + const unsigned int DATA_HEADER_LENGTH = 4; + + try { + std::stringstream ssError; + + ssError << "Data structure is incorrect. Data: " << Util::Strings::ByteArrayToHexString(pData+header.getHeaderLength(), numBytes - header.getHeaderLength()); + + // want to make sure data size is at least 5 bytes + if (pTempDataStart+DATA_HEADER_LENGTH > pTempDataEnd) + { + selfThrown = true; + throw Exception(__PRETTY_FUNCTION__," - " + ssError.str()); + } + + while (pTempDataStart < pTempDataEnd) + { + unsigned int dataSize = *(reinterpret_cast(pTempDataStart)); + + if (dataSize == 0) + { + selfThrown = true; + throw Exception(__PRETTY_FUNCTION__," - " + ssError.str()); + + } + + pTempDataStart += DATA_HEADER_LENGTH + dataSize; + + if (pTempDataStart-1 > pTempDataEnd) + { + selfThrown = true; + throw Exception(__PRETTY_FUNCTION__," - " + ssError.str()); + } + else if (pTempDataStart-1 == pTempDataEnd) + break; + } + } + catch (Exception& e) + { + if (!selfThrown) + e.buildStackTrace(__PRETTY_FUNCTION__); + + throw e; + } +} + diff --git a/CommonLib/src/Common/AutomationMessages/AutomationMsgParser.hpp b/CommonLib/src/Common/AutomationMessages/AutomationMsgParser.hpp new file mode 100644 index 0000000..a7e5ae3 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/AutomationMsgParser.hpp @@ -0,0 +1,78 @@ +#pragma once + +#include "MessageIDs.hpp" +#include + +class AutomationMsgParser +{ +public: + //>--------------------------------------------------------------------------- + // Function: instance + // + // Purpose: singleton + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + static AutomationMsgParser& Instance(); + + //>--------------------------------------------------------------------------- + // Function: ~Proc + // + // Purpose: Destroyer + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + ~AutomationMsgParser(); + + //>--------------------------------------------------------------------------- + // Function: parseMsg + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + void parseMsg(unsigned char* pData, unsigned int numBytes,unsigned int* pMsgId); + + private: + //>--------------------------------------------------------------------------- + // Function: AutomationMsgParser + // + // Purpose: Ctor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + AutomationMsgParser(); + + //>--------------------------------------------------------------------------- + // Function: gatherCmdMessageIds + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + void gatherCmdMessageIds(); + + //>--------------------------------------------------------------------------- + // Function: verifyDataFormat + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + void verifyDataFormat(unsigned char* pData, unsigned int numBytes); + + std::vector msgIdsVec; +}; + diff --git a/CommonLib/src/Common/AutomationMessages/GenericRspMessage.cpp b/CommonLib/src/Common/AutomationMessages/GenericRspMessage.cpp new file mode 100644 index 0000000..9e99556 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/GenericRspMessage.cpp @@ -0,0 +1,103 @@ +#include +#include +#include "GenericRspMessage.hpp" +#include "Exception.hpp" + +//------------------------------------------------------------------------ + +GenericRspMessage::GenericRspMessage(const bool& wasCommandSuccessful): + Message(MessageIDs::GENERIC_RSP, "GENERIC_RSP", sizeof(MessageStruct)), + m_messageStruct() +{ + m_messageStruct.wasCommandSuccessful = static_cast(wasCommandSuccessful); +} + +//------------------------------------------------------------------------ + +GenericRspMessage::GenericRspMessage(const GenericRspMessage& copy) : + Message(copy), + m_messageStruct(copy.m_messageStruct) +{ +} + +//------------------------------------------------------------------------ + +GenericRspMessage::~GenericRspMessage() +{ +} + +//------------------------------------------------------------------------ + +Message* GenericRspMessage::cloneSelf() +{ + GenericRspMessage* pMsg = new GenericRspMessage(*this); + return pMsg; +} + +//------------------------------------------------------------------------ + +void GenericRspMessage::executeMessage() +{ + try + { + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +void GenericRspMessage::formatData(unsigned char* pData) +{ + // Here's how the data is formatted + // each data item is preceded by a 4-byte header which tells us the size of the data item + // 1 data item will have [header][data] + // 2 data items will have [header][data][header][data] + unsigned int dataLen = 0; + const unsigned char* pTempDataStart = pData + getHeaderLength(); + + buildByteArray(&pTempDataStart, reinterpret_cast(&m_messageStruct.wasCommandSuccessful), sizeof(m_messageStruct.wasCommandSuccessful), dataLen); + + // we want update total size of the entire message + m_header.setMessageLength(static_cast(dataLen)); + m_header.format(pData); +} + +//------------------------------------------------------------------------ + +void GenericRspMessage::parseData(const unsigned char* pData) +{ + const unsigned char* pTempDataStart = pData; + const unsigned char* pTempDataEnd = pData + m_header.getMessageLength() - m_header.getHeaderLength() - 1; + std::stringstream ss; + + int sizeOfData = 0; + try { + sizeOfData = getNextDataItem(&pTempDataStart, pTempDataEnd, sizeOfData); + // make sure byte number match between what we're expected and what we receive + compareByteNumber(sizeof(m_messageStruct.wasCommandSuccessful), sizeOfData); + memcpy(&m_messageStruct.wasCommandSuccessful, pTempDataStart, sizeOfData); + + } + catch (Exception & e) { + e.buildStackTrace(__PRETTY_FUNCTION__); + + throw e; + } +} + +//------------------------------------------------------------------------ + +std::string GenericRspMessage::toString() const +{ + std::stringstream ss; + + ss << Message::toString() + << "wasCommandSuccessful: " << m_messageStruct.wasCommandSuccessful << "\n" + << "\n"; + + return ss.str(); +} diff --git a/CommonLib/src/Common/AutomationMessages/GenericRspMessage.hpp b/CommonLib/src/Common/AutomationMessages/GenericRspMessage.hpp new file mode 100644 index 0000000..d5051d7 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/GenericRspMessage.hpp @@ -0,0 +1,122 @@ +#pragma once + +#include "Message.hpp" +#include "MessageIDs.hpp" +#include "MessageHeader.hpp" + +class GenericRspMessage : public Message +{ +public: + //>--------------------------------------------------------------------------- + // Function: GenericRspMessage + // + // Purpose: constructor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + GenericRspMessage(const bool& wasCommandSuccessful); + + //>--------------------------------------------------------------------------- + // Function: GenericRspMessage + // + // Purpose: copy constructor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + GenericRspMessage(const GenericRspMessage ©); + + //>--------------------------------------------------------------------------- + // Function: ~GenericRspMessage + // + // Purpose: destructor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual ~GenericRspMessage(); + + //>--------------------------------------------------------------------------- + // Function: GetSuccessfulFlag + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + bool getSuccessfulFlag(){return static_cast(m_messageStruct.wasCommandSuccessful);} + + //>--------------------------------------------------------------------------- + // Function: ExecuteMessage + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual void executeMessage(); + + //>--------------------------------------------------------------------------- + // Function: ToString + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual std::string toString() const; + +protected: + //>--------------------------------------------------------------------------- + // Function: CloneSelf + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual Message* cloneSelf(); + + //>--------------------------------------------------------------------------- + // Function: FormatData + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual void formatData(unsigned char* pData); + + //>--------------------------------------------------------------------------- + // Function: ParseData + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual void parseData(const unsigned char* pData); + +private: + // do not allow + GenericRspMessage &operator=(const GenericRspMessage &rhs); + +#pragma pack(1) + struct MessageStruct + { + unsigned int wasCommandSuccessful; + }; +#pragma pack() + + MessageStruct m_messageStruct; +}; diff --git a/CommonLib/src/Common/AutomationMessages/Message.cpp b/CommonLib/src/Common/AutomationMessages/Message.cpp new file mode 100644 index 0000000..8bc903a --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/Message.cpp @@ -0,0 +1,176 @@ +#include +#include + +#include "Message.hpp" +#include "Exception.hpp" +#include "StringUtil.hpp" +//------------------------------------------------------------------------ + +Message::Message(const MessageIDs::MsgIds& id, + const std::string& description, + const unsigned short& messageLen) : + m_header(id, messageLen), + m_description(description) +{ +} + +//------------------------------------------------------------------------ + +Message::Message(const Message& copy) : + m_header(copy.m_header), + m_description(copy.m_description) +{ +} + +//------------------------------------------------------------------------ + +Message::~Message() +{ +} + +//------------------------------------------------------------------------ + +Message* Message::clone() +{ + return cloneSelf(); +} + +//------------------------------------------------------------------------ + +void Message::format(unsigned char* pBuffer) +{ + try + { + m_header.format(pBuffer); + formatData(pBuffer); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +std::string Message::getDescription() const +{ + return m_description; +} + +//------------------------------------------------------------------------ + +void Message::parse(const unsigned char* pData) +{ + try + { + m_header.parse(pData); + parseData(pData + getHeaderLength()); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +void Message::setMessageLength(const unsigned short& length) +{ + m_header.setMessageLength(length); +} + +//------------------------------------------------------------------------ + +std::string Message::toString() const +{ + std::stringstream ss; + ss << "Description: " << getDescription() << "\n" << m_header.toString(); + + return ss.str(); +} + +//------------------------------------------------------------------------ + +int Message::getNextDataItem(const unsigned char** pStartBuf, const unsigned char* pEndBuf, int& sizeOfPreviousData) +{ + bool selfThrown = false; + int sizeOfDataHeader = 4; + int sizeOfData = 0; + std::stringstream ssError; + + *pStartBuf += sizeOfPreviousData; + ssError << "Data structure is incorrect. Data: " << Util::Strings::ByteArrayToHexString(const_cast(*pStartBuf), pEndBuf - *pStartBuf + 1); + try { + // make sure 4 bytes of header information is present + if (*pStartBuf + sizeOfDataHeader > pEndBuf) + { + selfThrown = true; + throw Exception(__PRETTY_FUNCTION__," - " + ssError.str()); + } + + sizeOfData = *(*pStartBuf); + + // we want to make sure the nth header and nth data information match + // header tells us how many bytes in the nth data item, and the bytes + // of data is present in the buffer + if (*pStartBuf + sizeOfDataHeader + sizeOfData -1 <= pEndBuf) + { + // points to the address of the nth data item + *pStartBuf += sizeOfDataHeader; + } + else + { + selfThrown = true; + throw Exception(__PRETTY_FUNCTION__," - " + ssError.str()); + } + } catch (Exception& e) { + if (!selfThrown) + e.buildStackTrace(__PRETTY_FUNCTION__); + + throw e; + } + + return sizeOfData; +} + +//------------------------------------------------------------------------ + +void Message::buildByteArray(const unsigned char** pStartBuf, const char* data, const int& sizeOfDataBytes, unsigned int& totalBytesInArray) +{ + // copy the header information for this data item + memcpy(const_cast(*pStartBuf), &sizeOfDataBytes, sizeof(sizeOfDataBytes)); + *pStartBuf += sizeof(sizeOfDataBytes); + totalBytesInArray += sizeof(sizeOfDataBytes); + + // copy the data for this data item + memcpy(const_cast(*pStartBuf), data, sizeOfDataBytes); + *pStartBuf += sizeOfDataBytes; + totalBytesInArray += sizeOfDataBytes; +} + +//------------------------------------------------------------------------ + +void Message::compareByteNumber(int expectedNumBytes, int actualNumbyte) +{ + bool selfThrown = false; + std::stringstream ss; + + try + { + if (expectedNumBytes != actualNumbyte) + { + selfThrown = true; + + ss << "Expected number of bytes received: " << expectedNumBytes << ". Actual number of bytes received: " << actualNumbyte; + throw Exception(__PRETTY_FUNCTION__," - " + ss.str()); + } + } + catch (Exception & e) { + if (!selfThrown) + e.buildStackTrace(__PRETTY_FUNCTION__); + + throw e; + } +} diff --git a/CommonLib/src/Common/AutomationMessages/Message.hpp b/CommonLib/src/Common/AutomationMessages/Message.hpp new file mode 100644 index 0000000..ef9bba7 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/Message.hpp @@ -0,0 +1,241 @@ +#pragma once + +#include +#include "MessageIDs.hpp" +#include "MessageHeader.hpp" + +class Message +{ +public: + //>--------------------------------------------------------------------- + // Function: ~Message() + // + // Purpose: destructor + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual ~Message(); + + //>--------------------------------------------------------------------- + // Function: Clone() + // + // Purpose: Get a copy of this object + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: a copy of this object + //<--------------------------------------------------------------------- + virtual Message* clone(); + + //>--------------------------------------------------------------------- + // Function: ExecuteMessage() + // + // Purpose: Executes this message + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual void executeMessage() = 0; + + //>--------------------------------------------------------------------- + // Function: Format() + // + // Purpose: Formats this message for sending + //---------------------------------------------------------------------- + // Arguments: pBuffer - the buffer to put the formatting data in + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual void format(unsigned char* pBuffer); + + //>--------------------------------------------------------------------- + // Function: GetDescription() + // + // Purpose: Getter for this objects description + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: The description + //<--------------------------------------------------------------------- + virtual std::string getDescription() const; + + //>--------------------------------------------------------------------- + // Function: GetMessageID() + // + // Purpose: Getter for this objects message id + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: The id + //<--------------------------------------------------------------------- + virtual MessageIDs::MsgIds getMessageID() { return m_header.getMessageId(); } + + //>--------------------------------------------------------------------- + // Function: GetEntireMessageLength() + // + // Purpose: Getter for this objects message number of bytes, including the header + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: The entire message number of bytes + //<--------------------------------------------------------------------- + virtual unsigned int getEntireMessageLength() const { return m_header.getMessageLength();} + + //>--------------------------------------------------------------------- + // Function: GetHeaderLength() + // + // Purpose: Getter for this objects message number of header bytes + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: The header number of bytes + //<--------------------------------------------------------------------- + virtual unsigned short getHeaderLength() const { return m_header.getHeaderLength();} + + //>--------------------------------------------------------------------- + // Function: Parse() + // + // Purpose: Takes an array of bytes and populates this object + //---------------------------------------------------------------------- + // Arguments: The array of bytes + //---------------------------------------------------------------------- + // Return Value: None + //<--------------------------------------------------------------------- + virtual void parse(const unsigned char* pData); + + //>--------------------------------------------------------------------- + // Function: ToString() + // + // Purpose: Converts this object into a string + //---------------------------------------------------------------------- + // Arguments: None + //---------------------------------------------------------------------- + // Return Value: The string form of this object + //<--------------------------------------------------------------------- + virtual std::string toString() const; + +protected: + //>--------------------------------------------------------------------- + // Function: Constructor + // + // Purpose: The constructor for the childern to call + //---------------------------------------------------------------------- + // Arguments: id - the message id + // description - the message description + // messageLen - the number of bytes in the message payload (not including the header) + //---------------------------------------------------------------------- + // Return Value: The object + //<--------------------------------------------------------------------- + Message(const MessageIDs::MsgIds& id, + const std::string& description, + const unsigned short& messageLen = 0); + + //>--------------------------------------------------------------------- + // Function: Copy Constructor + // + // Purpose: Create a copy of this object + //---------------------------------------------------------------------- + // Arguments: copy - the object to copy + //---------------------------------------------------------------------- + // Return Value: The object + //<--------------------------------------------------------------------- + Message(const Message ©); + + //>--------------------------------------------------------------------- + // Function: CloneSelf + // + // Purpose: Pure virtual function for children to implement. + // Create a clone of this object + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: The object + //<--------------------------------------------------------------------- + virtual Message* cloneSelf() = 0; + + //>--------------------------------------------------------------------- + // Function: FormatData + // + // Purpose: Pure virtual function for children to implement. + // Format the data + //---------------------------------------------------------------------- + // Arguments: pData - the buffer to format to + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual void formatData(unsigned char* pData) = 0; + + //>--------------------------------------------------------------------- + // Function: ParseData + // + // Purpose: Pure virtual function for children to implement. + // Parse the data + //---------------------------------------------------------------------- + // Arguments: pData - the buffer to parse from + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual void parseData(const unsigned char* pData) = 0; + + //>--------------------------------------------------------------------- + // Function: SetMessageLength + // + // Purpose: Sets the message length of the payload of the message (not the header) + //---------------------------------------------------------------------- + // Arguments: length - the number of bytes in the payload + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual void setMessageLength(const unsigned short& length); + + //>--------------------------------------------------------------------- + // Function: getNextDataItem + // + // Purpose: + // get the next data item + // data format: + // [data header][data][data header][data]... + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + int getNextDataItem(const unsigned char** pStartBuf, const unsigned char* pEndBuf, int& sizeOfPreviousData); + + //>--------------------------------------------------------------------- + // Function: buildByteArray + // + // Purpose: + // this will add to the byte array a data item + // data format: + // [data header][data] + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void buildByteArray(const unsigned char** pStartBuf, const char* data, const int& sizeOfDataBytes, unsigned int& totalBytesInArray); + + //>--------------------------------------------------------------------- + // Function: compareByteNumber + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void compareByteNumber(int expectedNumBytes, int actualNumbyte); + + MessageHeader m_header; + +private: + // do not allow + Message(); + Message &operator=(const Message &rhs); + + std::string m_description; +}; diff --git a/CommonLib/src/Common/AutomationMessages/MessageHeader.cpp b/CommonLib/src/Common/AutomationMessages/MessageHeader.cpp new file mode 100644 index 0000000..8df7bae --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/MessageHeader.cpp @@ -0,0 +1,86 @@ +#include +#include +#include "MessageHeader.hpp" + +//------------------------------------------------------------------------ + +MessageHeader::MessageHeader(const MessageIDs::MsgIds& id, const unsigned short& messageLen) : + m_headerStruct() +{ + m_headerStruct.messageId = id; + m_headerStruct.messageLength = messageLen + getHeaderLength(); +} + +//------------------------------------------------------------------------ + +MessageHeader::MessageHeader() : + m_headerStruct() +{ + m_headerStruct.messageId = 0; + m_headerStruct.messageLength = 0; +} + +//------------------------------------------------------------------------ + +MessageHeader::MessageHeader(const MessageHeader& copy) : + m_headerStruct(copy.m_headerStruct) +{ +} + +//------------------------------------------------------------------------ + +MessageHeader::~MessageHeader() +{ +} + +//------------------------------------------------------------------------ + +void MessageHeader::format(unsigned char* pData) +{ + memcpy(pData, &m_headerStruct, getHeaderLength()); +} + +//------------------------------------------------------------------------ + +MessageIDs::MsgIds MessageHeader::getMessageId() +{ + return (MessageIDs::MsgIds)m_headerStruct.messageId; +} + +//------------------------------------------------------------------------ + +unsigned short MessageHeader::getHeaderLength() const +{ + return sizeof(m_headerStruct); +} + +//------------------------------------------------------------------------ + +unsigned int MessageHeader::getMessageLength() const +{ + return m_headerStruct.messageLength; +} + +//------------------------------------------------------------------------ + +void MessageHeader::parse(const unsigned char* pData) +{ + ::memcpy(&m_headerStruct, pData, getHeaderLength()); +} + +//------------------------------------------------------------------------ + +void MessageHeader::setMessageLength(const unsigned short& length) +{ + m_headerStruct.messageLength = length + getHeaderLength(); +} + +//------------------------------------------------------------------------ + +std::string MessageHeader::toString() const +{ + std::stringstream ss; + ss << "msg id: " << m_headerStruct.messageId << "\n" << "msg len: " << m_headerStruct.messageLength << "\n"; + + return ss.str(); +} diff --git a/CommonLib/src/Common/AutomationMessages/MessageHeader.hpp b/CommonLib/src/Common/AutomationMessages/MessageHeader.hpp new file mode 100644 index 0000000..2059807 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/MessageHeader.hpp @@ -0,0 +1,145 @@ +#pragma once + +#include "MessageIDs.hpp" + +class MessageHeader +{ +public: + //>--------------------------------------------------------------------- + // Function: MessageHeader + // + // Purpose: constructor + //---------------------------------------------------------------------- + // Arguments: id - the message id + // messageLen - the number of bytes of the entire message including the header + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + MessageHeader(const MessageIDs::MsgIds& id, const unsigned short& messageLen); + + //>--------------------------------------------------------------------- + // Function: MessageHeader + // + // Purpose: constructor + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + MessageHeader(); + + //>--------------------------------------------------------------------- + // Function: Copy Constructor + // + // Purpose: Create a copy of this object + //---------------------------------------------------------------------- + // Arguments: copy - the object to copy + //---------------------------------------------------------------------- + // Return Value: The object + //<--------------------------------------------------------------------- + MessageHeader(const MessageHeader ©); + + //>--------------------------------------------------------------------- + // Function: ~MessageHeader() + // + // Purpose: destructor + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual ~MessageHeader(); + + //>--------------------------------------------------------------------- + // Function: Format() + // + // Purpose: Formats this message for sending + //---------------------------------------------------------------------- + // Arguments: pBuffer - the buffer to put the formatting data in + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void format(unsigned char* pData); + + //>--------------------------------------------------------------------- + // Function: GetHeaderLength() + // + // Purpose: Get the number of bytes in the header + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: number of bytes in the header + //<--------------------------------------------------------------------- + unsigned short getHeaderLength() const; + + //>--------------------------------------------------------------------- + // Function: GetMessageLength() + // + // Purpose: Get the number of bytes in the entire message, including header + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: number of bytes in the message + //<--------------------------------------------------------------------- + unsigned int getMessageLength() const; + + //>--------------------------------------------------------------------- + // Function: GetMessageId() + // + // Purpose: Get the message id + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: the message id + //<--------------------------------------------------------------------- + MessageIDs::MsgIds getMessageId(); + + //>--------------------------------------------------------------------- + // Function: Parse() + // + // Purpose: Takes an array of bytes and populates this object + //---------------------------------------------------------------------- + // Arguments: The array of bytes + //---------------------------------------------------------------------- + // Return Value: None + //<--------------------------------------------------------------------- + void parse(const unsigned char* pData); + + //>--------------------------------------------------------------------- + // Function: SetMessageLength + // + // Purpose: Sets the message length of the payload of the message (not the header) + //---------------------------------------------------------------------- + // Arguments: length - the number of bytes in the payload + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void setMessageLength(const unsigned short& length); + + //>--------------------------------------------------------------------- + // Function: ToString() + // + // Purpose: Converts this object into a string + //---------------------------------------------------------------------- + // Arguments: None + //---------------------------------------------------------------------- + // Return Value: The string form of this object + //<--------------------------------------------------------------------- + std::string toString() const; + +protected: + +private: + // do not allow + MessageHeader &operator=(const MessageHeader &rhs); + +#pragma pack(1) + struct HeaderStruct + { + unsigned int messageId; + unsigned int messageLength; + }; +#pragma pack() + + HeaderStruct m_headerStruct; +}; diff --git a/CommonLib/src/Common/AutomationMessages/MessageIDs.hpp b/CommonLib/src/Common/AutomationMessages/MessageIDs.hpp new file mode 100644 index 0000000..4f6de3b --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/MessageIDs.hpp @@ -0,0 +1,16 @@ +#pragma once + + +namespace MessageIDs +{ + enum MsgIds + { + TRANSFER_A_FILE_CMD = 0xCA001001, + TRANSFER_A_FOLDER_CMD = 0xCA001002, + TRANSFER_GUTS_VIDEOS_CMD = 0xCA001003, + MOVE_GUTS_VIDEOS_TO_SUB_FOLDER_CMD = 0xCA001004, + WAIT_FOR_COMPLETION_CMD = 0xCA001005, + + GENERIC_RSP = 0xCA002001 + }; +} diff --git a/CommonLib/src/Common/AutomationMessages/MoveGutsVideosToSubFolderCmdMessage.cpp b/CommonLib/src/Common/AutomationMessages/MoveGutsVideosToSubFolderCmdMessage.cpp new file mode 100644 index 0000000..da735b5 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/MoveGutsVideosToSubFolderCmdMessage.cpp @@ -0,0 +1,117 @@ +#include +#include +#include "MoveGutsVideosToSubFolderCmdMessage.hpp" +#include "Exception.hpp" +#include "StringUtil.hpp" +#include "LinuxProc.hpp" +#include "IniFile.hpp" +#include "GenericRspMessage.hpp" +#include "Condition.hpp" + +//------------------------------------------------------------------------ + +MoveGutsVideosToSubFolderCmdMessage::MoveGutsVideosToSubFolderCmdMessage(std::string subFolder): + Message(MessageIDs::MOVE_GUTS_VIDEOS_TO_SUB_FOLDER_CMD, "MOVE_GUTS_VIDEOS_TO_SUB_FOLDER_CMD"), + m_subFolder(subFolder) +{ +} + +//------------------------------------------------------------------------ + +MoveGutsVideosToSubFolderCmdMessage::MoveGutsVideosToSubFolderCmdMessage(const MoveGutsVideosToSubFolderCmdMessage& copy) : + Message(copy), + m_subFolder(copy.m_subFolder) +{ +} + +//------------------------------------------------------------------------ + +MoveGutsVideosToSubFolderCmdMessage::~MoveGutsVideosToSubFolderCmdMessage() +{ +} + +//------------------------------------------------------------------------ + +Message* MoveGutsVideosToSubFolderCmdMessage::cloneSelf() +{ + MoveGutsVideosToSubFolderCmdMessage* pMsg = new MoveGutsVideosToSubFolderCmdMessage(*this); + return pMsg; +} + +//------------------------------------------------------------------------ + +void MoveGutsVideosToSubFolderCmdMessage::executeMessage() +{ + try + { + Condition& commandExecutingEvent = LinuxProc::Instance().getEvent(EventNames::COMMAND_EXECUTTION_IN_PROGRESS); + Condition& completeEvent = LinuxProc::Instance().getEvent(EventNames::COMMAND_EXECUTION_COMPLETE); + + completeEvent.reset(); + if (commandExecutingEvent.timedWait(0,0)) // a command is current executing + { + completeEvent.wait(); // wait until current command finish executing + } + + // signal this command is currently executing to prevent any other command from executing + commandExecutingEvent.signal(); + + /// code to execute commands here + + commandExecutingEvent.reset(); + completeEvent.signal(); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +void MoveGutsVideosToSubFolderCmdMessage::formatData(unsigned char* pData) +{ + // Here's how the data is formatted + // each data item is preceded by a 4-byte header which tells us the size of the data item + // 1 data item will have [header][data] + // 2 data items will have [header][data][header][data] + unsigned int dataLen = 0; + const unsigned char* pTempDataStart = pData + getHeaderLength(); + + buildByteArray(&pTempDataStart, m_subFolder.c_str(), m_subFolder.length(), dataLen); + + // we want update total size of the entire message + m_header.setMessageLength(static_cast(dataLen)); + m_header.format(pData); +} + +//------------------------------------------------------------------------ + +void MoveGutsVideosToSubFolderCmdMessage::parseData(const unsigned char* pData) +{ + const unsigned char* pTempDataStart = pData; + const unsigned char* pTempDataEnd = pData + m_header.getMessageLength() - m_header.getHeaderLength() - 1; + + int sizeOfData = 0; + try { + sizeOfData = getNextDataItem(&pTempDataStart, pTempDataEnd, sizeOfData); + m_subFolder = Util::Strings::ByteArrayToString(const_cast(pTempDataStart), sizeOfData); + + } catch (Exception& e) { + e.buildStackTrace(__PRETTY_FUNCTION__); + + throw e; + } +} + +//------------------------------------------------------------------------ + +std::string MoveGutsVideosToSubFolderCmdMessage::toString() const +{ + std::stringstream ss; + + ss << Message::toString() << ". Subfolder name: " << m_subFolder; + + return ss.str(); +} diff --git a/CommonLib/src/Common/AutomationMessages/MoveGutsVideosToSubFolderCmdMessage.hpp b/CommonLib/src/Common/AutomationMessages/MoveGutsVideosToSubFolderCmdMessage.hpp new file mode 100644 index 0000000..5798434 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/MoveGutsVideosToSubFolderCmdMessage.hpp @@ -0,0 +1,104 @@ +#pragma once + +#include "Message.hpp" +#include "MessageIDs.hpp" +#include "MessageHeader.hpp" + +class MoveGutsVideosToSubFolderCmdMessage : public Message +{ +public: + //>--------------------------------------------------------------------------- + // Function: MoveGutsVideosToSubFolderCmdMessage + // + // Purpose: constructor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + MoveGutsVideosToSubFolderCmdMessage(std::string subFolder = ""); + + //>--------------------------------------------------------------------------- + // Function: MoveGutsVideosToSubFolderCmdMessage + // + // Purpose: copy constructor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + MoveGutsVideosToSubFolderCmdMessage(const MoveGutsVideosToSubFolderCmdMessage ©); + + //>--------------------------------------------------------------------------- + // Function: ~MoveGutsVideosToSubFolderCmdMessage + // + // Purpose: destructor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual ~MoveGutsVideosToSubFolderCmdMessage(); + + //>--------------------------------------------------------------------------- + // Function: ExecuteMessage + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual void executeMessage(); + + //>--------------------------------------------------------------------------- + // Function: ToString + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual std::string toString() const; + +protected: + //>--------------------------------------------------------------------------- + // Function: CloneSelf + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual Message* cloneSelf(); + + //>--------------------------------------------------------------------------- + // Function: FormatData + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual void formatData(unsigned char* pData); + + //>--------------------------------------------------------------------------- + // Function: ParseData + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual void parseData(const unsigned char* pData); + +private: + // do not allow + MoveGutsVideosToSubFolderCmdMessage &operator=(const MoveGutsVideosToSubFolderCmdMessage &rhs); + + std::string m_subFolder; +}; diff --git a/CommonLib/src/Common/AutomationMessages/TransferAFileCmdMessage.cpp b/CommonLib/src/Common/AutomationMessages/TransferAFileCmdMessage.cpp new file mode 100644 index 0000000..92d90d8 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/TransferAFileCmdMessage.cpp @@ -0,0 +1,123 @@ +#include +#include +#include "TransferAFileCmdMessage.hpp" +#include "Proc.hpp" +#include "Exception.hpp" +#include "StringUtil.hpp" +#include "GenericRspMessage.hpp" +#include "UdpSocket.hpp" + +//------------------------------------------------------------------------ + +TransferAFileCmdMessage::TransferAFileCmdMessage(std::string fromFile, std::string toFile, bool deleteSource): + Message(MessageIDs::TRANSFER_A_FILE_CMD, "TRANSFER_A_FILE_CMD"), + m_fromFile(fromFile), + m_toFile(toFile), + m_deleteSource(static_cast(deleteSource)) +{ +} + +//------------------------------------------------------------------------ + +TransferAFileCmdMessage::TransferAFileCmdMessage(const TransferAFileCmdMessage& copy) : + Message(copy), + m_fromFile(copy.m_fromFile), + m_toFile(copy.m_toFile), + m_deleteSource(copy.m_deleteSource) +{ +} + +//------------------------------------------------------------------------ + +TransferAFileCmdMessage::~TransferAFileCmdMessage() +{ +} + +//------------------------------------------------------------------------ + +Message* TransferAFileCmdMessage::cloneSelf() +{ + TransferAFileCmdMessage* pMsg = new TransferAFileCmdMessage(*this); + return pMsg; +} + +//------------------------------------------------------------------------ + +void TransferAFileCmdMessage::executeMessage() +{ + try + { + GenericRspMessage rsp(true); + + //Proc::instance().sendAMessage(rsp); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +void TransferAFileCmdMessage::formatData(unsigned char* pData) +{ + // Here's how the data is formatted + // each data item is preceded by a 4-byte header which tells us the size of the data item + // 1 data item will have [header][data] + // 2 data items will have [header][data][header][data] + unsigned int dataLen = 0; + const unsigned char* pTempDataStart = pData + getHeaderLength(); + + buildByteArray(&pTempDataStart, m_fromFile.c_str(), m_fromFile.length(), dataLen); + buildByteArray(&pTempDataStart, m_toFile.c_str(), m_toFile.length(), dataLen); + buildByteArray(&pTempDataStart, reinterpret_cast(&m_deleteSource), sizeof(m_deleteSource), dataLen); + + // we want update total size of the entire message + m_header.setMessageLength(static_cast(dataLen)); + m_header.format(pData); +} + +//------------------------------------------------------------------------ + +void TransferAFileCmdMessage::parseData(const unsigned char* pData) +{ + const unsigned char* pTempDataStart = pData; + const unsigned char* pTempDataEnd = pData + m_header.getMessageLength() - m_header.getHeaderLength() - 1; + + int sizeOfData = 0; + try { + sizeOfData = getNextDataItem(&pTempDataStart, pTempDataEnd, sizeOfData); + m_fromFile = Util::Strings::ByteArrayToString(const_cast(pTempDataStart), sizeOfData); + + sizeOfData = getNextDataItem(&pTempDataStart, pTempDataEnd, sizeOfData); + getNextDataItem(&pTempDataStart, pTempDataEnd, sizeOfData); + + sizeOfData = getNextDataItem(&pTempDataStart, pTempDataEnd, sizeOfData); + m_toFile = Util::Strings::ByteArrayToString(const_cast(pTempDataStart), sizeOfData); + + sizeOfData = getNextDataItem(&pTempDataStart, pTempDataEnd, sizeOfData); + getNextDataItem(&pTempDataStart, pTempDataEnd, sizeOfData); + + sizeOfData = getNextDataItem(&pTempDataStart, pTempDataEnd, sizeOfData); + // make sure byte number match between what we're expected and what we receive + compareByteNumber(sizeof(m_deleteSource), sizeOfData); + memcpy(&m_deleteSource, pTempDataStart, sizeOfData); + + } catch (Exception& e) { + e.buildStackTrace(__PRETTY_FUNCTION__); + + throw e; + } +} + +//------------------------------------------------------------------------ + +std::string TransferAFileCmdMessage::toString() const +{ + std::stringstream ss; + + ss << Message::toString() << ". From file: " << m_fromFile << ". To file: " << m_toFile << ". Delete source: " << m_deleteSource; + + return ss.str(); +} diff --git a/CommonLib/src/Common/AutomationMessages/TransferAFileCmdMessage.hpp b/CommonLib/src/Common/AutomationMessages/TransferAFileCmdMessage.hpp new file mode 100644 index 0000000..10c6d80 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/TransferAFileCmdMessage.hpp @@ -0,0 +1,108 @@ +#pragma once + +#include "Message.hpp" +#include "MessageIDs.hpp" +#include "MessageHeader.hpp" + +class TransferAFileCmdMessage : public Message +{ +public: + //>--------------------------------------------------------------------------- + // Function: TransferAFileCmdMessage + // + // Purpose: constructor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + TransferAFileCmdMessage(std::string fromFile = "", std::string toFile = "", bool deleteSource = false); + + //>--------------------------------------------------------------------------- + // Function: TransferAFileCmdMessage + // + // Purpose: copy constructor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + TransferAFileCmdMessage(const TransferAFileCmdMessage ©); + + //>--------------------------------------------------------------------------- + // Function: ~TransferAFileCmdMessage + // + // Purpose: destructor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual ~TransferAFileCmdMessage(); + + //>--------------------------------------------------------------------------- + // Function: ExecuteMessage + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual void executeMessage(); + + //>--------------------------------------------------------------------------- + // Function: ToString + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual std::string toString() const; + +protected: + //>--------------------------------------------------------------------------- + // Function: CloneSelf + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual Message* cloneSelf(); + + //>--------------------------------------------------------------------------- + // Function: FormatData + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual void formatData(unsigned char* pData); + + //>--------------------------------------------------------------------------- + // Function: ParseData + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual void parseData(const unsigned char* pData); + +private: + // do not allow + TransferAFileCmdMessage &operator=(const TransferAFileCmdMessage &rhs); + + std::string m_fromFile; + + std::string m_toFile; + + unsigned int m_deleteSource; +}; diff --git a/CommonLib/src/Common/AutomationMessages/TransferGutsVideosCmdMessage.cpp b/CommonLib/src/Common/AutomationMessages/TransferGutsVideosCmdMessage.cpp new file mode 100644 index 0000000..eb91592 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/TransferGutsVideosCmdMessage.cpp @@ -0,0 +1,153 @@ +#include +#include +#include "TransferGutsVideosCmdMessage.hpp" +#include "LinuxProc.hpp" +#include "Exception.hpp" +#include "Condition.hpp" +#include "StringUtil.hpp" +#include "GenericRspMessage.hpp" +#include "IniFile.hpp" + +//------------------------------------------------------------------------ + +TransferGutsVideosCmdMessage::TransferGutsVideosCmdMessage(std::string currentTestFolder, unsigned int transferEverything, unsigned int deleteSource): + Message(MessageIDs::TRANSFER_GUTS_VIDEOS_CMD, "TRANSFER_GUTS_VIDEOS_CMD"), + m_currentTestFolder(currentTestFolder), + m_transferEverything(transferEverything), + m_deleteSource(deleteSource) +{ +} + +//------------------------------------------------------------------------ + +TransferGutsVideosCmdMessage::TransferGutsVideosCmdMessage(const TransferGutsVideosCmdMessage& copy) : + Message(copy), + m_currentTestFolder(copy.m_currentTestFolder), + m_transferEverything(copy.m_transferEverything), + m_deleteSource(copy.m_deleteSource) +{ +} + +//------------------------------------------------------------------------ + +TransferGutsVideosCmdMessage::~TransferGutsVideosCmdMessage() +{ +} + +//------------------------------------------------------------------------ + +Message* TransferGutsVideosCmdMessage::cloneSelf() +{ + TransferGutsVideosCmdMessage* pMsg = new TransferGutsVideosCmdMessage(*this); + return pMsg; +} + +//------------------------------------------------------------------------ + +void TransferGutsVideosCmdMessage::executeMessage() +{ + try + { + Condition& commandExecutingEvent = LinuxProc::Instance().getEvent(EventNames::COMMAND_EXECUTTION_IN_PROGRESS); + Condition& completeEvent = LinuxProc::Instance().getEvent(EventNames::COMMAND_EXECUTION_COMPLETE); + + completeEvent.reset(); + if (commandExecutingEvent.timedWait(0,0)) // a command is current executing + { + completeEvent.wait(); // wait until current command finish executing + } + + // signal this command is currently executing to prevent any other command from executing + commandExecutingEvent.signal(); + + GenericRspMessage rsp(true); + + //LinuxProc::instance().sendAMessage(rsp); + + gatherInfo(); + + Condition& event = LinuxProc::Instance().getEvent(EventNames::START_FILE_TRANSFER); + event.signal(); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +void TransferGutsVideosCmdMessage::gatherInfo() +{ + try + { + + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +void TransferGutsVideosCmdMessage::formatData(unsigned char* pData) +{ + // Here's how the data is formatted + // each data item is preceded by a 4-byte header which tells us the size of the data item + // 1 data item will have [header][data] + // 2 data items will have [header][data][header][data] + unsigned int dataLen = 0; + const unsigned char* pTempDataStart = pData + getHeaderLength(); + + buildByteArray(&pTempDataStart, m_currentTestFolder.c_str(), m_currentTestFolder.length(), dataLen); + buildByteArray(&pTempDataStart, reinterpret_cast(&m_transferEverything), sizeof(m_transferEverything), dataLen); + buildByteArray(&pTempDataStart, reinterpret_cast(&m_deleteSource), sizeof(m_deleteSource), dataLen); + + // we want update total size of the entire message + m_header.setMessageLength(static_cast(dataLen)); + m_header.format(pData); +} + +//------------------------------------------------------------------------ + +void TransferGutsVideosCmdMessage::parseData(const unsigned char* pData) +{ + const unsigned char* pTempDataStart = pData; + const unsigned char* pTempDataEnd = pData + m_header.getMessageLength() - m_header.getHeaderLength() - 1; + + int sizeOfData = 0; + try { + // get the address of the 1st data item + sizeOfData = getNextDataItem(&pTempDataStart, pTempDataEnd, sizeOfData); + m_currentTestFolder = Util::Strings::ByteArrayToString(const_cast(pTempDataStart), sizeOfData); + + sizeOfData = getNextDataItem(&pTempDataStart, pTempDataEnd, sizeOfData); + // make sure byte number match between what we're expected and what we receive + compareByteNumber(sizeof(m_transferEverything), sizeOfData); + memcpy(&m_transferEverything, pTempDataStart, sizeOfData); + + sizeOfData = getNextDataItem(&pTempDataStart, pTempDataEnd, sizeOfData); + // make sure byte number match between what we're expected and what we receive + compareByteNumber(sizeof(m_deleteSource), sizeOfData); + memcpy(&m_deleteSource, pTempDataStart, sizeOfData); + + } catch (Exception& e) { + e.buildStackTrace(__PRETTY_FUNCTION__); + + throw e; + } +} + +//------------------------------------------------------------------------ + +std::string TransferGutsVideosCmdMessage::toString() const +{ + std::stringstream ss; + + ss << Message::toString() << ". current test folder: " << m_currentTestFolder << ". transfer everything: " << m_transferEverything << ". Delete source: " << m_deleteSource; + + return ss.str(); +} diff --git a/CommonLib/src/Common/AutomationMessages/TransferGutsVideosCmdMessage.hpp b/CommonLib/src/Common/AutomationMessages/TransferGutsVideosCmdMessage.hpp new file mode 100644 index 0000000..6c013fa --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/TransferGutsVideosCmdMessage.hpp @@ -0,0 +1,126 @@ +#pragma once + +#include "Message.hpp" +#include "MessageIDs.hpp" +#include "MessageHeader.hpp" + +class TransferGutsVideosCmdMessage : public Message +{ +public: + //>--------------------------------------------------------------------- + // Function: TransferGutsVideosCmdMessage + // + // Purpose: constructor + //---------------------------------------------------------------------- + // Arguments: + // + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + TransferGutsVideosCmdMessage(std::string currentTestFolder, unsigned int transferEverything = 0, unsigned int deleteSource = 0); + + //>--------------------------------------------------------------------- + // Function: TransferGutsVideosCmdMessage + // + // Purpose: copy constructor + //---------------------------------------------------------------------- + // Arguments: + // + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + TransferGutsVideosCmdMessage(const TransferGutsVideosCmdMessage ©); + + //>--------------------------------------------------------------------- + // Function: ~TransferGutsVideosCmdMessage + // + // Purpose: destructor + //---------------------------------------------------------------------- + // Arguments: + // + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual ~TransferGutsVideosCmdMessage(); + + //>--------------------------------------------------------------------- + // Function: ExecuteMessage + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + // + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual void executeMessage(); + + //>--------------------------------------------------------------------- + // Function: ToString + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + // + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual std::string toString() const; + +protected: + //>--------------------------------------------------------------------- + // Function: CloneSelf + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + // + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual Message* cloneSelf(); + + //>--------------------------------------------------------------------- + // Function: FormatData + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + // + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual void formatData(unsigned char* pData); + + //>--------------------------------------------------------------------- + // Function: ParseData + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + // + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual void parseData(const unsigned char* pData); + + //>--------------------------------------------------------------------- + // Function: gatherInfo + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + // + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void gatherInfo(); + +private: + // do not allow + TransferGutsVideosCmdMessage &operator=(const TransferGutsVideosCmdMessage &rhs); + + std::string m_currentTestFolder; + unsigned int m_transferEverything; + unsigned int m_deleteSource; +}; diff --git a/CommonLib/src/Common/AutomationMessages/WaitForLastTaskCompletionCmdMessage.cpp b/CommonLib/src/Common/AutomationMessages/WaitForLastTaskCompletionCmdMessage.cpp new file mode 100644 index 0000000..728d175 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/WaitForLastTaskCompletionCmdMessage.cpp @@ -0,0 +1,82 @@ +#include +#include +#include "WaitForLastTaskCompletionCmdMessage.hpp" +#include "Exception.hpp" +#include "Condition.hpp" +#include "LinuxProc.hpp" +#include "GenericRspMessage.hpp" + +bool WaitForLastTaskCompletionCmdMessage::s_commandCompletionSuccess = true; + +//------------------------------------------------------------------------ + +WaitForLastTaskCompletionCmdMessage::WaitForLastTaskCompletionCmdMessage(): + Message(MessageIDs::WAIT_FOR_COMPLETION_CMD, "WAIT_FOR_COMPLETION_CMD") +{ +} + +//------------------------------------------------------------------------ + +WaitForLastTaskCompletionCmdMessage::WaitForLastTaskCompletionCmdMessage(const WaitForLastTaskCompletionCmdMessage& copy) : + Message(copy) +{ +} + +//------------------------------------------------------------------------ + +WaitForLastTaskCompletionCmdMessage::~WaitForLastTaskCompletionCmdMessage() +{ +} + +//------------------------------------------------------------------------ + +Message* WaitForLastTaskCompletionCmdMessage::cloneSelf() +{ + WaitForLastTaskCompletionCmdMessage* pMsg = new WaitForLastTaskCompletionCmdMessage(*this); + return pMsg; +} + +//------------------------------------------------------------------------ + +void WaitForLastTaskCompletionCmdMessage::executeMessage() +{ + try + { + Condition& event = LinuxProc::Instance().getEvent(EventNames::COMMAND_EXECUTION_COMPLETE); + event.wait(false); + + GenericRspMessage rsp(s_commandCompletionSuccess); + + //Proc::instance().sendAMessage(rsp); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +void WaitForLastTaskCompletionCmdMessage::formatData(unsigned char*) +{ + // no data to send +} + +//------------------------------------------------------------------------ + +void WaitForLastTaskCompletionCmdMessage::parseData(const unsigned char*) +{ + // no data to process +} + +//------------------------------------------------------------------------ + +std::string WaitForLastTaskCompletionCmdMessage::toString() const +{ + std::stringstream ss; + + ss << Message::toString() << ". No member data"; + + return ss.str(); +} diff --git a/CommonLib/src/Common/AutomationMessages/WaitForLastTaskCompletionCmdMessage.hpp b/CommonLib/src/Common/AutomationMessages/WaitForLastTaskCompletionCmdMessage.hpp new file mode 100644 index 0000000..b57f557 --- /dev/null +++ b/CommonLib/src/Common/AutomationMessages/WaitForLastTaskCompletionCmdMessage.hpp @@ -0,0 +1,105 @@ +#pragma once + +#include "Message.hpp" +#include "MessageIDs.hpp" +#include "MessageHeader.hpp" + +class WaitForLastTaskCompletionCmdMessage : public Message +{ +public: + //>--------------------------------------------------------------------------- + // Function: WaitForLastTaskCompletionCmdMessage + // + // Purpose: constructor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + WaitForLastTaskCompletionCmdMessage(); + + //>--------------------------------------------------------------------------- + // Function: WaitForLastTaskCompletionCmdMessage + // + // Purpose: copy constructor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + WaitForLastTaskCompletionCmdMessage(const WaitForLastTaskCompletionCmdMessage ©); + + //>--------------------------------------------------------------------------- + // Function: ~WaitForLastTaskCompletionCmdMessage + // + // Purpose: destructor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual ~WaitForLastTaskCompletionCmdMessage(); + + //>--------------------------------------------------------------------------- + // Function: ExecuteMessage + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual void executeMessage(); + + //>--------------------------------------------------------------------------- + // Function: ToString + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual std::string toString() const; + + // indicate command executed successfully or not + static bool s_commandCompletionSuccess; + +protected: + //>--------------------------------------------------------------------------- + // Function: CloneSelf + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual Message* cloneSelf(); + + //>--------------------------------------------------------------------------- + // Function: FormatData + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual void formatData(unsigned char* pData); + + //>--------------------------------------------------------------------------- + // Function: ParseData + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual void parseData(const unsigned char* pData); + +private: + // do not allow + WaitForLastTaskCompletionCmdMessage &operator=(const WaitForLastTaskCompletionCmdMessage &rhs); +}; diff --git a/CommonLib/src/Common/Comm/CommInterface.hpp b/CommonLib/src/Common/Comm/CommInterface.hpp new file mode 100644 index 0000000..5940f8a --- /dev/null +++ b/CommonLib/src/Common/Comm/CommInterface.hpp @@ -0,0 +1,70 @@ +#pragma once + +#include + +class CommInterface +{ +public: + //>--------------------------------------------------------------------- + // Function: CommInterface + // + // Purpose: COnstructor + //---------------------------------------------------------------------- + // Arguments: name - the name of this comm interface + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + CommInterface(const std::string& name) {m_name = name;}; + + //>--------------------------------------------------------------------- + // Function: ~CommInterface() + // + // Purpose: destructor + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual ~CommInterface(){}; + + //>--------------------------------------------------------------------- + // Function: GetName + // + // Purpose: Get the name of this comm interface + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: The name of the interface + //<--------------------------------------------------------------------- + std::string& getName() {return m_name;}; + + //>--------------------------------------------------------------------- + // Function: Read + // + // Purpose: Read data from this comm interface + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: The number of bytes read + //<--------------------------------------------------------------------- + virtual int read(char* pDataBuffer, const unsigned int& bufferSize, const unsigned int& timeoutSec) = 0; + + //>--------------------------------------------------------------------- + // Function: Write + // + // Purpose: Write data to this comm interface + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: The number of bytes written + //<--------------------------------------------------------------------- + virtual int write(const char* pDataToWrite, const unsigned int& numBytesToWrite) = 0; + +private: + // do not allow + CommInterface(); + CommInterface(const CommInterface ©); + CommInterface &operator=(const CommInterface &rhs); + + std::string m_name; +}; diff --git a/CommonLib/src/Common/Comm/UdpSocket.cpp b/CommonLib/src/Common/Comm/UdpSocket.cpp new file mode 100644 index 0000000..f941d16 --- /dev/null +++ b/CommonLib/src/Common/Comm/UdpSocket.cpp @@ -0,0 +1,131 @@ +#include +#include +#include +#include +#include +#include + +#include "UdpSocket.hpp" +#include "TimeoutError.hpp" +#include "NetworkUtil.hpp" + +UdpSocket::UdpSocket(const std::string& name, const int& localPort, const int& remotePort, const std::string& remoteAddy): + CommInterface(name), + m_localPort(localPort), + m_remotePort(remotePort), + m_sock(-1), + m_localSockInfo(), + m_remoteSockInfo() +{ + try + { + m_remoteAddy = Util::Network::ConvertHostnameToIp(remoteAddy); + bindSocket(); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +void UdpSocket::bindSocket() +{ + try + { + m_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + + if (m_sock < 0) + { + std::stringstream ss; + ss << "socket create failed: " << m_sock; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + memset((char*)&m_localSockInfo, 0, sizeof(m_localSockInfo)); + m_localSockInfo.sin_family = AF_INET; + + m_localSockInfo.sin_addr.s_addr = htonl(INADDR_ANY); + m_localSockInfo.sin_port = htons(m_localPort); + + int ret = bind(m_sock, (struct sockaddr*)&m_localSockInfo, sizeof(m_localSockInfo)); + + if(ret < 0) + { + std::stringstream ss; + ss << "bind failed: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + if (m_remotePort > 1 && m_remoteAddy.length() > 1) + { + memset((char*)&m_remoteSockInfo, 0, sizeof(m_remoteSockInfo)); + m_remoteSockInfo.sin_family = AF_INET; + + m_remoteSockInfo.sin_addr.s_addr = inet_addr(m_remoteAddy.c_str()); + m_remoteSockInfo.sin_port = htons(m_remotePort); + } + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +int UdpSocket::read(char* pDataBuffer, const unsigned int& bufferSize, const unsigned int& timeoutSec) +{ + try + { + // set the timeout + struct timeval to; + to.tv_sec = timeoutSec; + to.tv_usec = 0; + + if (timeoutSec != CommonLibConstants::INFINITE) + { + int ret = setsockopt(m_sock, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof(to)); + + if (ret < 0) + { + std::stringstream ss; + ss << "unable to set timeout: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + } + + socklen_t clntLen = sizeof(m_remoteSockInfo); + + int bytesRcv = recvfrom(m_sock, pDataBuffer, bufferSize, 0, (struct sockaddr *)&m_remoteSockInfo, &clntLen); + + if (errno == 11) + { + throw TimeoutError(__PRETTY_FUNCTION__, "timed out", TimeoutError::TIME_OUT_SOCKET); + } + + return bytesRcv; + } + catch (TimeoutError& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +int UdpSocket::write(const char* pDataToWrite, const unsigned int& numBytesToWrite) +{ + unsigned int bytesSent = sendto(m_sock, pDataToWrite, numBytesToWrite, 0, (struct sockaddr *)&m_remoteSockInfo, sizeof(m_remoteSockInfo)); + + return bytesSent; +} diff --git a/CommonLib/src/Common/Comm/UdpSocket.hpp b/CommonLib/src/Common/Comm/UdpSocket.hpp new file mode 100644 index 0000000..47af2c9 --- /dev/null +++ b/CommonLib/src/Common/Comm/UdpSocket.hpp @@ -0,0 +1,93 @@ +#pragma once + +#include +#include +#include +#include + +#include "CommInterface.hpp" +#include "Constants.hpp" + +class UdpSocket: public CommInterface +{ +public: + //>--------------------------------------------------------------------- + // Function: UdpSocket() + // + // Purpose: Constructor + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: the object + //<--------------------------------------------------------------------- + UdpSocket(const std::string& name, const int& localPort, const int& remotePort = -1, const std::string& remoteAddy = ""); + + //>--------------------------------------------------------------------- + // Function: ~UdpSocket + // + // Purpose: Destroyer + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual ~UdpSocket() {} + + //>--------------------------------------------------------------------- + // Function: BindSocket + // + // Purpose: Bind the socket + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void bindSocket(); + + //>--------------------------------------------------------------------- + // Function: Read + // + // Purpose: Read from the socket + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: number of bytes read + //<--------------------------------------------------------------------- + virtual int read(char* pDataBuffer, const unsigned int& bufferSize, const unsigned int& timeoutSec = CommonLibConstants::INFINITE); + + //>--------------------------------------------------------------------- + // Function: Write + // + // Purpose: Write to the socket + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: number of bytes written + //<--------------------------------------------------------------------- + virtual int write(const char* pDataToWrite, const unsigned int& numBytesToWrite); + + //>--------------------------------------------------------------------- + // Function: Close + // + // Purpose: close the file descriptor + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + void close(){shutdown(m_sock, SHUT_RDWR);} + +private: + // dont allow + UdpSocket(const UdpSocket& rhs); + UdpSocket& operator=(const UdpSocket& rhs); + + int m_localPort; + int m_remotePort; + std::string m_remoteAddy; + int m_sock; + + struct sockaddr_in m_localSockInfo; + struct sockaddr_in m_remoteSockInfo; +}; + diff --git a/CommonLib/src/Common/Exceptions/Exception.cpp b/CommonLib/src/Common/Exceptions/Exception.cpp new file mode 100644 index 0000000..46d8266 --- /dev/null +++ b/CommonLib/src/Common/Exceptions/Exception.cpp @@ -0,0 +1,110 @@ +#include "Exception.hpp" +#include "PosixRegexUtil.hpp" +#include "StringUtil.hpp" + +#include + +//------------------------------------------------------------------------ + +Exception::Exception(std::string functionName, const std::string& errorMsg, const std::string& exceptionClass) : + exception() +{ + std::string className = ""; + if (exceptionClass.length() == 0) + className = std::string(typeid(this).name()); + else + className = exceptionClass; + + // get the name of the class without the extra add-ons + std::vector vecMatches = Util::PosixRegex::GetMatchesFromRegex(className, "[a-z][0-9]+([a-z].+)"); + + if (vecMatches.size() > 1) + m_message = vecMatches[1]; + else + m_message = "Exception"; + + m_message += ": "; + + m_lastFunction = functionName; + + vecMatches = Util::PosixRegex::GetMatchesFromRegex(functionName, "([^ \\(]+\\()"); + + if (vecMatches.size() > 1) + functionName = vecMatches[1] + ")"; + + m_message += functionName + " - " + errorMsg; + m_fullStackTraceMessage = m_message; + m_message = errorMsg; +} + +//------------------------------------------------------------------------ + +Exception::Exception(const Exception &rhs) +{ + copy(rhs); +} + +//------------------------------------------------------------------------ + +Exception &Exception::operator=(const Exception &rhs) +{ + return copy(rhs); +} + +//------------------------------------------------------------------------ + +std::string Exception::getMessage(Message_Format msgFormat) +{ + std::string msg = m_message; + + if (msgFormat == ERROR_MESSAGE_WITH_STACKTRACE) + msg = m_fullStackTraceMessage; + + return msg; +} + +//------------------------------------------------------------------------ + +void Exception::buildStackTrace(std::string functionName, const std::string& errorMsg) +{ + if (!Util::Strings::StringsAreEqual(functionName, m_lastFunction)) + { + m_lastFunction = functionName; + + std::vectorvecMatches = Util::PosixRegex::GetMatchesFromRegex(functionName, "([^ \\(]+\\()"); + + if (vecMatches.size() > 1) + functionName = vecMatches[1] + ")"; + + m_fullStackTraceMessage.append(" -> "); + m_fullStackTraceMessage.append(functionName); + + if (errorMsg.length() > 0) + { + m_fullStackTraceMessage.append(" - " + errorMsg); + m_message = errorMsg; + } + } +} + +//------------------------------------------------------------------------ + +Exception &Exception::copy(const Exception &rhs) +{ + if (this == &rhs) + { + return *this; + } + + m_message = rhs.m_message; + m_fullStackTraceMessage = rhs.m_fullStackTraceMessage; + m_lastFunction = rhs.m_lastFunction; + + return *this; +} + +//------------------------------------------------------------------------ + +Exception::~Exception() throw() +{ +} diff --git a/CommonLib/src/Common/Exceptions/Exception.hpp b/CommonLib/src/Common/Exceptions/Exception.hpp new file mode 100644 index 0000000..b4efc96 --- /dev/null +++ b/CommonLib/src/Common/Exceptions/Exception.hpp @@ -0,0 +1,106 @@ +#pragma once + +#include +#include + +class Exception : public std::exception +{ +public: + enum Message_Format + { + ERROR_MESSAGE_WITH_STACKTRACE, // entire stack trace + ERROR_MESSAGE_ONLY // the function that throw the exception + }; + + //>--------------------------------------------------------------------- + // Function: Exception() + // + // Purpose: constructor + //---------------------------------------------------------------------- + // Arguments: + // functionName - should use custom macro __FUNCTION_NAME__ + // to get the name of offending function + // errorMsg - description of what caused the exception + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + Exception(const std::string functionName, const std::string& errorMsg, const std::string& exceptionClass = ""); + + //>--------------------------------------------------------------------- + // Function: Exception() + // + // Purpose: copy constructor + // this gets called when "throw ex" executes rather than throw + // throw; throws the same exception object + // throw ex; throws a new exception + //---------------------------------------------------------------------- + // Arguments: const Exception & - reference to Exception obj + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + Exception(const Exception &rhs); + + //>--------------------------------------------------------------------- + // Function: ~Exception() + // + // Purpose: destructor + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual ~Exception() throw(); + + //>--------------------------------------------------------------------- + // Function: getMessage() + // + // Purpose: to get the message data member + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: std::string - the message string + //<--------------------------------------------------------------------- + std::string getMessage(Message_Format msgFormat= ERROR_MESSAGE_WITH_STACKTRACE); + + //>--------------------------------------------------------------------- + // Function: buildStackTrace() + // + // Purpose: Build the stack trace of function calls for debugging purposes + //---------------------------------------------------------------------- + // Arguments: + // functionName - should use custom macro __PRETTY_FUNCTION__ + // to get the name of offending function + // + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void buildStackTrace(std::string functionName, const std::string& errorMsg = ""); + +protected: + std::string m_message; + std::string m_fullStackTraceMessage; + std::string m_lastFunction; + +private: + //>--------------------------------------------------------------------- + // Function: operator&() + // + // Purpose: assignment operator + //---------------------------------------------------------------------- + // Arguments: const Exception & - reference to Exception obj + //---------------------------------------------------------------------- + // Return Value: reference to Exception obj + //<--------------------------------------------------------------------- + Exception &operator=(const Exception &rhs); + + //>--------------------------------------------------------------------- + // Function: copy() + // + // Purpose: to do the work for assignment operator and copy ctor + //---------------------------------------------------------------------- + // Arguments: const Exception &rhs - const reference to Exception obj + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + Exception ©(const Exception &rhs); +}; diff --git a/CommonLib/src/Common/Exceptions/TimeoutError.cpp b/CommonLib/src/Common/Exceptions/TimeoutError.cpp new file mode 100644 index 0000000..0ee4b2e --- /dev/null +++ b/CommonLib/src/Common/Exceptions/TimeoutError.cpp @@ -0,0 +1,17 @@ +#include "TimeoutError.hpp" + +#include + +//------------------------------------------------------------------------ + +TimeoutError::TimeoutError(std::string functionName, const std::string& errorMsg, TIME_OUT_TYPE timeOutType) : + Exception(functionName, errorMsg, std::string(typeid(this).name())), + m_timeOutType(timeOutType) +{ +} + +//------------------------------------------------------------------------ + +TimeoutError::~TimeoutError() throw() +{ +} diff --git a/CommonLib/src/Common/Exceptions/TimeoutError.hpp b/CommonLib/src/Common/Exceptions/TimeoutError.hpp new file mode 100644 index 0000000..a164bcc --- /dev/null +++ b/CommonLib/src/Common/Exceptions/TimeoutError.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include "Exception.hpp" + +class TimeoutError : public Exception +{ +public: + enum TIME_OUT_TYPE + { + TIME_OUT_GENERIC, + TIME_OUT_SOCKET + }; + + //>--------------------------------------------------------------------- + // Function: TimeoutError() + // + // Purpose: default and non-default constructor + //---------------------------------------------------------------------- + // Arguments: std::string msg - a message to be printed + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + TimeoutError(std::string functionName, const std::string& errorMsg, TIME_OUT_TYPE timeOutType = TIME_OUT_GENERIC); + + //>--------------------------------------------------------------------- + // Function: ~TimeoutError() + // + // Purpose: destructor + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual ~TimeoutError() throw(); + + TIME_OUT_TYPE m_timeOutType; +}; diff --git a/CommonLib/src/Common/Lib/Condition.cpp b/CommonLib/src/Common/Lib/Condition.cpp new file mode 100644 index 0000000..b220f95 --- /dev/null +++ b/CommonLib/src/Common/Lib/Condition.cpp @@ -0,0 +1,333 @@ +#include +#include +#include +#include "Condition.hpp" +#include "Exception.hpp" +#include "TimeoutError.hpp" + +Condition::Condition(const std::string& name) : + OSObject(name), + m_state(NOT_SIGNALED) +{ + try + { + pthread_condattr_t attr; + int ret = pthread_condattr_init(&attr); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_condattr_init returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + ret = pthread_cond_init(&m_condition, &attr); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_cond_init returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + pthread_mutexattr_t mutexAttr; + ret = pthread_mutexattr_init(&mutexAttr); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_mutexattr_init returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + ret = pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_mutexattr_settype returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + ret = pthread_mutex_init(&m_mutex, &mutexAttr); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_mutex_lock returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } +} + +//------------------------------------------------------------------------ + +Condition::~Condition() +{ + int ret = pthread_cond_destroy(&m_condition); + + if (ret != 0) + { + // it is being destroyed, nothing to do + } +} + +//------------------------------------------------------------------------ + +void Condition::broadcast() +{ + try + { + lockMutex(); + + int ret = pthread_cond_broadcast(&m_condition); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_cond_broadcast returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + m_state = SIGNALED; + + unlockMutex(); + } + catch (Exception& e) + { + m_state = NOT_SIGNALED; + + unlockMutex(); + + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + + +void Condition::lockMutex() +{ + int ret = pthread_mutex_lock(&m_mutex); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_mutex_lock returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } +} + +//------------------------------------------------------------------------ + +void Condition::reset() +{ + try + { + lockMutex(); + m_state = NOT_SIGNALED; + unlockMutex(); + } + catch (Exception& e) + { + unlockMutex(); + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +void Condition::signal() +{ + try + { + lockMutex(); + + m_state = SIGNALED; + + int ret = pthread_cond_signal(&m_condition); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_cond_signal returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + unlockMutex(); + } + catch (Exception& e) + { + m_state = NOT_SIGNALED; + + unlockMutex(); + + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +bool Condition::timedWait(const unsigned long seconds, const unsigned long nanoseconds, bool shallWeReset) +{ + try + { + lockMutex(); + + // looping because pthread_cond_wait can return even if not signaled + while (m_state != SIGNALED) + { + timespec waitTime; + int status = 0; + + if( ( 0 != seconds ) || ( 0 != nanoseconds ) ) + { + status = clock_gettime(CLOCK_REALTIME , &waitTime); + + if( 0 != status ) + { + std::stringstream ss; + ss << "clock_gettime returned: " << status; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + else + { + waitTime.tv_nsec += nanoseconds; + + // check for more than one second's worth of nanoseconds + if( 999999999L < waitTime.tv_nsec ) + { + waitTime.tv_nsec -= 1000000000L; + waitTime.tv_sec += 1; + } + + waitTime.tv_sec += seconds; + } + } + else + { + waitTime.tv_sec = 0; + waitTime.tv_nsec = 0; + } + + status = pthread_cond_timedwait(&m_condition, &m_mutex, &waitTime); + + //@@@ + /*if (status == TIMEDOUT) + { + std::stringstream ss; + ss << "Condition::TimedWait() - pthread_cond_timedwait returned: " << status; + throw TimeoutError(ss.str()); + }*/ + if(status != 0) + { + std::stringstream ss; + ss << "pthread_cond_timedwait returned: " << status; + throw TimeoutError(__PRETTY_FUNCTION__,ss.str()); + } + }// end while + + if (shallWeReset == true) + { + reset(); + } + + unlockMutex(); + + return true; + } + catch (TimeoutError& e) + { + if (shallWeReset == true) + { + reset(); + } + + unlockMutex(); + + return false; + } + catch (Exception& e) + { + if (shallWeReset == true) + { + reset(); + } + + unlockMutex(); + + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +void Condition::unlockMutex() +{ + try + { + int ret = pthread_mutex_unlock(&m_mutex); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_mutex_unlock returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +void Condition::wait(bool shallWeReset) +{ + try + { + lockMutex(); + + // looping because pthread_cond_wait can return even if not signaled + while (m_state != SIGNALED) + { + int ret = pthread_cond_wait(&m_condition, &m_mutex); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_cond_wait returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + } + + if (shallWeReset == true) + { + reset(); + } + + unlockMutex(); + } + catch (Exception& e) + { + if (shallWeReset == true) + { + reset(); + } + + unlockMutex(); + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} diff --git a/CommonLib/src/Common/Lib/Condition.hpp b/CommonLib/src/Common/Lib/Condition.hpp new file mode 100644 index 0000000..1defe3e --- /dev/null +++ b/CommonLib/src/Common/Lib/Condition.hpp @@ -0,0 +1,106 @@ +#pragma once + +#include +#include "OSObject.hpp" + +class Condition : public OSObject +{ +public: + enum State + { + NOT_SIGNALED, + SIGNALED + }; + + //>--------------------------------------------------------------------- + // Function: Condition + // + // Purpose: The constructor + //---------------------------------------------------------------------- + // Arguments: name - the name of the condition + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + Condition(const std::string& name); + + //>--------------------------------------------------------------------- + // Function: ~Condition + // + // Purpose: The destroyer + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + virtual ~Condition(); + + //>--------------------------------------------------------------------- + // Function: Broadcast + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + void broadcast(); + + //>--------------------------------------------------------------------- + // Function: Reset + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + void reset(); + + //>--------------------------------------------------------------------- + // Function: Signal + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + void signal(); + + //>--------------------------------------------------------------------- + // Function: TimedWait + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + bool timedWait(const unsigned long seconds, const unsigned long nanoseconds, bool shallWeReset = true); + + //>--------------------------------------------------------------------- + // Function: Wait + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + void wait(bool shallWeReset = true); + +private: + // dont allow + Condition(const Condition& rhs); + Condition& operator=(const Condition& rhs); + + void lockMutex(); + + void unlockMutex(); + + pthread_cond_t m_condition; + + pthread_mutex_t m_mutex; + + State m_state; +}; diff --git a/CommonLib/src/Common/Lib/Constants.hpp b/CommonLib/src/Common/Lib/Constants.hpp new file mode 100644 index 0000000..8933f9d --- /dev/null +++ b/CommonLib/src/Common/Lib/Constants.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace CommonLibConstants +{ + const unsigned int MAIL_BUFFER_SIZE = 512; + const unsigned int INFINITE = 0xFFFFFFFF; +} diff --git a/CommonLib/src/Common/Lib/ErrorLog.cpp b/CommonLib/src/Common/Lib/ErrorLog.cpp new file mode 100644 index 0000000..0276a14 --- /dev/null +++ b/CommonLib/src/Common/Lib/ErrorLog.cpp @@ -0,0 +1,87 @@ +#include +#include +#include + +#include "ErrorLog.hpp" +#include "Exception.hpp" +#include "LockMutex.hpp" +#include "Timestamp.hpp" + +//----------------------------------------------------------------------------- + +ErrorLog &ErrorLog::Instance(const std::string& filename) +{ + try + { + static ErrorLog fileAndConsoleWriter(filename); + return fileAndConsoleWriter; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +ErrorLog::ErrorLog(const std::string& filename): + m_mutex("ErrorLog - Mutex") +{ + try + { + m_outlog.open(filename.c_str(), std::ios_base::app); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +ErrorLog::~ErrorLog() +{ + m_outlog.close(); +} + +//----------------------------------------------------------------------------- + +void ErrorLog::log(const std::string& msg, const bool putToConsole, ErrorLog::LogLevel level) +{ + try + { + LockMutex lock(&m_mutex); + + // build the string to log + std::stringstream msgToLogSs; + + if (level == INFO) + { + msgToLogSs << "INFO, " << msg + "\n"; + } + else + { + msgToLogSs << "ERROR, " << msg + "\n"; + } + + // log out data to console + if (putToConsole == true) + { + std::cout << msgToLogSs.str(); + } + + m_outlog << Timestamp::GetCurrentDateTimeString(Timestamp::DateTimeFormat::YYYYMMDD) << "_" << Timestamp::GetCurrentDateTimeString(Timestamp::DateTimeFormat::HHMMSSMM, "_") + "_" + msgToLogSs.str(); + + m_outlog.flush(); + } + catch (...) + { + // if we cant log, just continue on + } +} + + + + diff --git a/CommonLib/src/Common/Lib/ErrorLog.hpp b/CommonLib/src/Common/Lib/ErrorLog.hpp new file mode 100644 index 0000000..093ee6f --- /dev/null +++ b/CommonLib/src/Common/Lib/ErrorLog.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include +#include + +#include "Mutex.hpp" + +class ErrorLog +{ +public: + enum LogLevel + { + INFO, + ERROR + }; + + static ErrorLog &Instance(const std::string& filename = ""); + + ~ErrorLog(); + + void log(const std::string& msg, const bool putToConsole = true, LogLevel logLevel = ERROR); + +private: + // do not allow + ErrorLog(const ErrorLog& rhs); + ErrorLog& operator=(const ErrorLog& rhs); + + + ErrorLog(const std::string& filename); + + std::string m_filename; + std::ofstream m_outlog; + + Mutex m_mutex; +}; + + + diff --git a/CommonLib/src/Common/Lib/IniFile.cpp b/CommonLib/src/Common/Lib/IniFile.cpp new file mode 100644 index 0000000..c994761 --- /dev/null +++ b/CommonLib/src/Common/Lib/IniFile.cpp @@ -0,0 +1,439 @@ +#include +#include + +#include "IniFile.hpp" +#include "Exception.hpp" +#include "StringUtil.hpp" + +// INI-file delimiters +static const char COMMENT_CHAR = '#'; +static const char KEY_VALUE_DELIMITER = '='; +static const char SECTION_HDR_START_CHAR = '['; +static const char SECTION_HDR_END_CHAR = ']'; + +//------------------------------------------------------------------------ + +IniFile::IniFile(const std::string& fileName) +{ + try + { + readFile(fileName); + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"caught unknown error"); + } +} + +//------------------------------------------------------------------------ + +IniFile::~IniFile() +{ +} + +//------------------------------------------------------------------------ + +void IniFile::addKeyValuePair(const std::string& section, + const std::string& key, + const std::string& value) +{ + configMap[section].insert(KeyValuePair(key, value)); +} + +//------------------------------------------------------------------------ + +bool IniFile::getBool(const std::string& section , + const std::string& key) const +{ + try + { + std::stringstream ss; + + ss.str(Util::Strings::ToLower(getString(section , key))); + ss.setf(std::ios_base::boolalpha); + bool tmp; + ss >> tmp; + + return tmp; + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"caught unknown error"); + } +} + +//------------------------------------------------------------------------ + +double IniFile::getDouble(const std::string& section, + const std::string& key) const +{ + try + { + std::stringstream ss; + + ss.str(getString(section , key)); + double tmp; + ss >> tmp; + + return tmp; + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"caught unknown error"); + } +} + +//------------------------------------------------------------------------ + +void IniFile::getKeys(const std::string& section, + std::vector& keys) const +{ + try + { + keys.clear(); // empty list + + // make sure section exists + SectionIter sectionIt = configMap.find(section); + + if (sectionIt == configMap.end()) + { + std::ostringstream oss; + + oss << "section '" << section.c_str() << "' does not exist\n"; + + throw Exception(__PRETTY_FUNCTION__,oss.str()); + } + + // fill up vector with keys + for (KeyValueIter keyValueIt = sectionIt->second.begin(); + keyValueIt != sectionIt->second.end(); + ++keyValueIt) + { + keys.push_back(keyValueIt->first); + } + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"caught unknown error"); + } +} + +//------------------------------------------------------------------------ + +void IniFile::getKeyValue(const std::string& line, + std::string& key, + std::string& value) const +{ + try + { + size_t equalPos; + + // everything to left of delimiter is key + equalPos = line.find(KEY_VALUE_DELIMITER); + key = line.substr(0 , equalPos); + + // everything to right of delimiter is value (except possible comment) + value = line.substr(equalPos + 1); + + size_t commentPos; + commentPos = value.find(COMMENT_CHAR); + + if (commentPos != std::string::npos) + { + value = value.substr(0 , commentPos); + } + + // trim leading/trailing spaces on key and value + key = Util::Strings::TrimSpaces(key); + value = Util::Strings::TrimSpaces(value); + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"caught unknown error"); + } +} + +//------------------------------------------------------------------------ + +IniFile::LineType IniFile::getLineType(const std::string& line) const +{ + try + { + // trim leading/trailing spaces + std::string tempLine = Util::Strings::TrimSpaces(line); + + // blank line? + if (tempLine.length() == 0) + { + return BLANK_LINE; + } + + // commment? + if (tempLine[0] == COMMENT_CHAR) + { + return COMMENT; + } + + // section header? + if (tempLine[0] == SECTION_HDR_START_CHAR) + { + // check for end of section header + if (tempLine.find(SECTION_HDR_END_CHAR) != std::string::npos) + { + return SECTION_HEADER; + } + else // starts out as a section header, but no end char + { + return BAD_LINE; + } + } + + // Assume everything else is a key/value pair. + // Previously checked for "=" and returned BAD_LINE if it didn't exist. + // However, this did not allow for keys with no values. + return KEY_VALUE_PAIR; + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"caught unknown error"); + } +} + +//------------------------------------------------------------------------ + +int IniFile::getInt(const std::string& section, const std::string& key) const +{ + try + { + std::stringstream ss; + + ss.str(getString(section , key)); + int tmp = 0; + ss >> tmp; + + return tmp; + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"caught unknown error"); + } +} + +//------------------------------------------------------------------------ + +unsigned int IniFile::getUint(const std::string& section, + const std::string& key, + bool isHexString) const +{ + try + { + std::stringstream ss; + + unsigned int tmp = 0; + + if (isHexString == false) + { + std::string iniVal = getString(section , key); + ss << iniVal; + ss >> tmp; + } + else + { + std::string iniVal = getString(section , key); + ss << std::hex << iniVal; + ss >> tmp; + } + + return tmp; + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"caught unknown error"); + } +} + +//------------------------------------------------------------------------ + +std::string IniFile::getString(const std::string& section, + const std::string& key) const +{ + try + { + // make sure section exists + SectionIter sectionIt = configMap.find(section); + + if (sectionIt == configMap.end()) + { + std::stringstream ss; + ss << "section '" << section << "' does not exist"; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + // make sure key exists + KeyValueIter keyValueIt = sectionIt->second.find(key); + + if (keyValueIt == sectionIt->second.end()) + { + std::ostringstream oss; + + oss << "key '" << key << "' does not exist"; + + throw Exception(__PRETTY_FUNCTION__,oss.str()); + } + + return keyValueIt->second; + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"caught unknown error"); + } +} + +//------------------------------------------------------------------------ + +bool IniFile::isSection(const std::string& section) const +{ + return configMap.find(section) != configMap.end(); +} + +//------------------------------------------------------------------------ + +void IniFile::readFile(const std::string& fileName) +{ + try + { + // open file + std::ifstream cfgStream(fileName.c_str()); + + if (cfgStream.fail()) + { + std::string s = "could not open file: " + fileName; + throw Exception(__PRETTY_FUNCTION__,s); + } + + // read line-by-line + // - skip comments, blank lines + // - save last section name + // - add key/value pairs as ecnountered + std::string section; + bool bHaveSection = false; + + while (!cfgStream.eof()) + { + std::string line = ""; + + std::getline(cfgStream, line); + + if(line != "") + { + char lastChar = line[line.length() - 1]; + + if(lastChar == '\r') + { + line = line.substr(0, line.length() - 1); + } + } + + LineType lineType = getLineType(line); + + switch (lineType) + { + case BLANK_LINE: + case COMMENT: + // do nothing + break; + + case SECTION_HEADER: + { + // save section + size_t first = line.find_first_of('['); + size_t last = line.find_first_of(']'); + section = line.substr(first + 1 , last - first - 1); + + bHaveSection = true; + } + break; + + case KEY_VALUE_PAIR: + if (bHaveSection) + { + // add to map + std::string key; + std::string value; + getKeyValue(line , key , value); + + addKeyValuePair(section, key, value); + } + else + { + throw Exception(__PRETTY_FUNCTION__,"key/value pair before section"); + } + + break; + + case BAD_LINE: + std::string errMsg; + + errMsg = "bad line: '" + line + "'"; + + throw Exception(__PRETTY_FUNCTION__,errMsg.c_str()); + } + } + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"caught unknown error"); + } +} + +//------------------------------------------------------------------------ diff --git a/CommonLib/src/Common/Lib/IniFile.hpp b/CommonLib/src/Common/Lib/IniFile.hpp new file mode 100644 index 0000000..010ff0d --- /dev/null +++ b/CommonLib/src/Common/Lib/IniFile.hpp @@ -0,0 +1,224 @@ +#pragma once + +#include +#include +#include + +class IniFile +{ +public: + //>--------------------------------------------------------------------------- + // Function: IniFile + // + // Purpose: Constructor + //---------------------------------------------------------------------------- + // Arguments:fileName - name of INI-format file + //---------------------------------------------------------------------------- + // Return Value: none + //---------------------------------------------------------------------------- + IniFile(const std::string& fileName); + + //>--------------------------------------------------------------------------- + // Function: ~IniFile + // + // Purpose: destructor + //---------------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------------- + // Return Value: none + //---------------------------------------------------------------------------- + virtual ~IniFile(); + + //>--------------------------------------------------------------------------- + // Function: getBool + // + // Purpose: return value of a given section/key interpreted as a boolean + //---------------------------------------------------------------------------- + // Arguments: + // section - section containing desired key/value pair + // key - key in given section + //---------------------------------------------------------------------------- + // Return Value: + // value string of given section/key interpreted as a boolean + //---------------------------------------------------------------------------- + bool getBool(const std::string& section, const std::string& key) const; + + //>--------------------------------------------------------------------------- + // Function: getDouble + // + // Purpose: return value of a given section/key interpreted as a double + //---------------------------------------------------------------------------- + // Arguments: + // section - section containing desired key/value pair + // key - key in given section + //---------------------------------------------------------------------------- + // Return Value: + // value string of given section/key interpreted as a double + //---------------------------------------------------------------------------- + double getDouble(const std::string& section, const std::string& key) const; + + //>--------------------------------------------------------------------------- + // Function: getKeys + // + // Purpose: return list of keys in a given section + //---------------------------------------------------------------------------- + // Arguments: + // section - section from which to return list of keys + // keys - list of keys in given section + //---------------------------------------------------------------------------- + // Return Value: none + //---------------------------------------------------------------------------- + void getKeys(const std::string& section, + std::vector& keys) const; + + //>--------------------------------------------------------------------------- + // Function: GetInt + // + // Purpose: return value of a given section/key interpreted as a int + //---------------------------------------------------------------------------- + // Arguments: + // section - section containing desired key/value pair + // key - key in given section + //---------------------------------------------------------------------------- + // Return Value: the value as an int + //---------------------------------------------------------------------------- + int getInt(const std::string& section, const std::string& key) const; + + //>--------------------------------------------------------------------------- + // Function: getLong + // + // Purpose: return value of a given section/key interpreted as a long + //---------------------------------------------------------------------------- + // Arguments: + // section - section containing desired key/value pair + // key - key in given section + //---------------------------------------------------------------------------- + // Return Value: + // value string of given section/key interpreted as a long + //---------------------------------------------------------------------------- + unsigned int getUint(const std::string& section, const std::string& key, bool isHexString) const; + + //>--------------------------------------------------------------------------- + // Function: getString + // + // Purpose: return value of a given section/key interpreted as a string + //---------------------------------------------------------------------------- + // Arguments: + // section - section containing desired key/value pair + // key - key in given section + //---------------------------------------------------------------------------- + // Return Value: + // value string of given section/key interpreted as a string + //---------------------------------------------------------------------------- + std::string getString(const std::string& section, + const std::string& key) const; + + //>--------------------------------------------------------------------------- + // Function: isSection + // + // Purpose: return whether given string is a section + //---------------------------------------------------------------------------- + // Arguments: + // str - string for which to return whether it is a section + //---------------------------------------------------------------------------- + // Return Value: + // whether specified string is a section(true) or not(false) + //---------------------------------------------------------------------------- + bool isSection(const std::string& str) const; + +protected: + //>--------------------------------------------------------------------------- + // Function: addKeyValuePair + // + // Purpose: + // adds a key/value pair to a section + //---------------------------------------------------------------------------- + // Arguments: + // section - section to which to add key/value pair + // key - key of key/value pair to add + // value - value of key/value pair to add + //---------------------------------------------------------------------------- + // Return Value: none + //---------------------------------------------------------------------------- + void addKeyValuePair(const std::string& section, + const std::string& key, + const std::string& value); + +private: + // do not allow + IniFile(); + IniFile(const IniFile ©); + IniFile &operator=(const IniFile &rhs); + + // types of line allowed in INI-format file + enum LineType + { + COMMENT, + KEY_VALUE_PAIR, + SECTION_HEADER, + BLANK_LINE, + BAD_LINE + }; + + // internally-used data structures + typedef std::map KeyValueMap; + typedef std::pair KeyValuePair; + typedef std::map SectionMap; + typedef KeyValueMap::const_iterator KeyValueIter; + typedef SectionMap::const_iterator SectionIter; + + SectionMap configMap; // map containing sections and key/value pairs + + //>--------------------------------------------------------------------------- + // Function: getKeyValue + // + // Purpose: + // returns key/value pair(strings) from a string. + // + // Key/value pairs are delimited by an equal sign, "=". If no equal sign + // is found, then value is an empty string. Spaces are trimmed from both + // ends of the key and value strings. + //---------------------------------------------------------------------------- + // Arguments: + // line - string containing a key/value pair + // key - returned key string + // value - return value string. may be empty if no equal sign found in + // line. + //---------------------------------------------------------------------------- + // Return Value: none + //---------------------------------------------------------------------------- + void getKeyValue(const std::string& line, + std::string& key, + std::string& value) const; + + //>--------------------------------------------------------------------------- + // Function: getLineType + // + // Purpose: + // returns type of line in passed string + //---------------------------------------------------------------------------- + // Arguments: + // line - string containing line read from file + //---------------------------------------------------------------------------- + // Return Value: + // type of line (see LineType enum) of passed string + //---------------------------------------------------------------------------- + LineType getLineType(const std::string& line) const; + + //>--------------------------------------------------------------------------- + // Function: readFile + // + // Purpose: + // reads file and repeatedly calls ConfigData::addKeyValuePair to store + // sections and key/value pairs. Throws FileErr exception if could not + // open file. + // + // Throws IniFileErr exception if problem with data in file. + //---------------------------------------------------------------------------- + // Arguments: + // fileName - name of INI-format file to read/parse + //---------------------------------------------------------------------------- + // Return Value: none + //---------------------------------------------------------------------------- + void readFile(const std::string& fileName); +}; diff --git a/CommonLib/src/Common/Lib/LockMutex.cpp b/CommonLib/src/Common/Lib/LockMutex.cpp new file mode 100644 index 0000000..4eb2225 --- /dev/null +++ b/CommonLib/src/Common/Lib/LockMutex.cpp @@ -0,0 +1,39 @@ +#include "LockMutex.hpp" +#include "Exception.hpp" +#include "Mutex.hpp" + +LockMutex::LockMutex(Mutex* pMutex) : + m_pMutex(pMutex) +{ + try + { + m_pMutex->lock(); + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"LockMutex::LockMutex() - caught unknown"); + } +} + +//------------------------------------------------------------------------ + +LockMutex::~LockMutex() +{ + try + { + m_pMutex->unlock(); + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + } + catch (...) + { + } + m_pMutex = 0; +} diff --git a/CommonLib/src/Common/Lib/LockMutex.hpp b/CommonLib/src/Common/Lib/LockMutex.hpp new file mode 100644 index 0000000..dadfbca --- /dev/null +++ b/CommonLib/src/Common/Lib/LockMutex.hpp @@ -0,0 +1,37 @@ +#pragma once + +class Mutex; + +class LockMutex +{ +public: + //>--------------------------------------------------------------------- + // Function: LockMutex() + // + // Purpose: constructor + //---------------------------------------------------------------------- + // Arguments:pMutex, pointer to a mutex + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + explicit LockMutex(Mutex* pMutex); + + //>--------------------------------------------------------------------- + // Function: ~LockMutex() + // + // Purpose: destroyer + //---------------------------------------------------------------------- + // Arguments: none + //-------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + ~LockMutex(); + +private: + // do not allow + LockMutex(); + LockMutex(const LockMutex ©); + LockMutex &operator=(const LockMutex &rhs); + + Mutex* m_pMutex; // do not delete +}; diff --git a/CommonLib/src/Common/Lib/Mutex.cpp b/CommonLib/src/Common/Lib/Mutex.cpp new file mode 100644 index 0000000..71abe14 --- /dev/null +++ b/CommonLib/src/Common/Lib/Mutex.cpp @@ -0,0 +1,110 @@ +#include +#include "Mutex.hpp" +#include "Exception.hpp" + +Mutex::Mutex(const std::string& name) : + OSObject(name) +{ + try + { + // set up mutex to be of the recursive type + + pthread_mutexattr_t mutexAttr; + int ret = pthread_mutexattr_init(&mutexAttr); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_mutexattr_init returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + ret = pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_mutexattr_settype returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + ret = pthread_mutex_init(&m_mutex, &mutexAttr); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_mutex_lock returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + } + catch (Exception &e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } +} + +//------------------------------------------------------------------------ + +Mutex::~Mutex() +{ + try + { + unlock(); + } + catch(...) + { + //nothing to do here + } + + int ret = pthread_mutex_destroy(&m_mutex); + + if (ret != 0) + { + // it is being destroyed, nothing to do + } +} + +//------------------------------------------------------------------------ + +void Mutex::lock() +{ + try + { + int ret = pthread_mutex_lock(&m_mutex); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_mutex_lock returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + } + catch (Exception &e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } +} + +//------------------------------------------------------------------------ + +void Mutex::unlock() +{ + try + { + int ret = pthread_mutex_unlock(&m_mutex); + + if (ret != 0) + { + std::stringstream ss; + ss << "pthread_mutex_unlock returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + } + catch (Exception &e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } +} diff --git a/CommonLib/src/Common/Lib/Mutex.hpp b/CommonLib/src/Common/Lib/Mutex.hpp new file mode 100644 index 0000000..5de82f6 --- /dev/null +++ b/CommonLib/src/Common/Lib/Mutex.hpp @@ -0,0 +1,71 @@ +#pragma once + +#include +#include "OSObject.hpp" + +class Mutex : OSObject +{ +public: + //>--------------------------------------------------------------------------- + // Function: Mutex + // + // Purpose: Constructor + //---------------------------------------------------------------------------- + // Arguments: name - the name of this mutex + //---------------------------------------------------------------------------- + // Return Value: none + //---------------------------------------------------------------------------- + Mutex(const std::string& name); + + //>--------------------------------------------------------------------------- + // Function: ~Mutex + // + // Purpose: Destroyer + //---------------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------------- + // Return Value: none + //---------------------------------------------------------------------------- + virtual ~Mutex(); + + //>--------------------------------------------------------------------------- + // Function: GetMutex + // + // Purpose: Get the mutex + //---------------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------------- + // Return Value: none + //---------------------------------------------------------------------------- + //pthread_mutex_t GetMutex() { return m_mutex;}; + + //>--------------------------------------------------------------------------- + // Function: Lock + // + // Purpose: lock the mutex + //---------------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------------- + // Return Value: none + //---------------------------------------------------------------------------- + void lock(); + + //>--------------------------------------------------------------------------- + // Function: Unlock + // + // Purpose: unlock the mutex + //---------------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------------- + // Return Value: none + //---------------------------------------------------------------------------- + void unlock(); + +private: + // not allowed + Mutex(const Mutex& rhs); + Mutex& operator=(const Mutex& rhs); + + pthread_mutex_t m_mutex; +}; + diff --git a/CommonLib/src/Common/Lib/OSObject.cpp b/CommonLib/src/Common/Lib/OSObject.cpp new file mode 100644 index 0000000..87bbce2 --- /dev/null +++ b/CommonLib/src/Common/Lib/OSObject.cpp @@ -0,0 +1,20 @@ +#include +#include "OSObject.hpp" + +OSObject::OSObject(const std::string &name) : + m_name(name), + m_handle(0) +{ +} + +//------------------------------------------------------------------------ + +OSObject::~OSObject() +{ + if (m_handle) + { + //@@@ + //::CloseHandle(handle_); + } + m_handle = 0; +} diff --git a/CommonLib/src/Common/Lib/OSObject.hpp b/CommonLib/src/Common/Lib/OSObject.hpp new file mode 100644 index 0000000..da84c40 --- /dev/null +++ b/CommonLib/src/Common/Lib/OSObject.hpp @@ -0,0 +1,73 @@ +#pragma once + +#include + +class OSObject +{ +public: + typedef void* HANDLE; + + //>--------------------------------------------------------------------- + // Function: OSObject() + // + // Purpose: constructor + //---------------------------------------------------------------------- + // Arguments: name - the name of this object + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + explicit OSObject(const std::string &name); + + //>--------------------------------------------------------------------- + // Function: ~OSObject() + // + // Purpose: destructor + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual ~OSObject(); + + //>--------------------------------------------------------------------------- + // Function: GetName + // + // Purpose: Retrieve the name + //---------------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------------- + // Return Value: the name + //---------------------------------------------------------------------------- + std::string getName() const { return m_name; } + + //>--------------------------------------------------------------------------- + // Function: GetHandle + // + // Purpose: Retrieve the handle + //---------------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------------- + // Return Value: the handle + //---------------------------------------------------------------------------- + HANDLE getHandle() const { return m_handle; } + + //>--------------------------------------------------------------------------- + // Function: SetHandle + // + // Purpose: sets the handle + //---------------------------------------------------------------------------- + // Arguments: handle - the handle + //---------------------------------------------------------------------------- + // Return Value: none + //---------------------------------------------------------------------------- + void setHandle(HANDLE handle) { m_handle = handle; } + +private: + // do not allow + OSObject(const OSObject ©); + OSObject &operator=(const OSObject &rhs); + + std::string m_name; + HANDLE m_handle; +}; + diff --git a/CommonLib/src/Common/Lib/Semaphore.cpp b/CommonLib/src/Common/Lib/Semaphore.cpp new file mode 100644 index 0000000..cf676c9 --- /dev/null +++ b/CommonLib/src/Common/Lib/Semaphore.cpp @@ -0,0 +1,103 @@ +#include +#include +#include +#include "Semaphore.hpp" +#include "Exception.hpp" +#include "TimeoutError.hpp" + +Semaphore::Semaphore(const std::string& name) : + OSObject(name) +{ + try + { + int ret = sem_init(&m_semaphore, 0, 0); + + if (ret != 0) + { + std::stringstream ss; + ss << "Semaphore::Semaphore() - sem_init returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + } + catch (Exception &e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } +} + +//------------------------------------------------------------------------ + +Semaphore::~Semaphore() +{ + try + { + sem_close(&m_semaphore); + } + catch(...) + { + //nothing to do here + } +} + +//------------------------------------------------------------------------ + +void Semaphore::wait(time_t seconds, long nseconds) +{ + try + { + if (seconds == -1 || nseconds == -1) + { + int ret = sem_wait(&m_semaphore); + + if (ret != 0) + { + std::stringstream ss; + ss << "sem_wait returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + } + else + { + timespec timeout; + timeout.tv_sec = seconds; + timeout.tv_nsec = nseconds; + + int ret = sem_timedwait(&m_semaphore, &timeout); + + if (ret != 0) + { + std::stringstream ss; + ss << "sem_timedwait returned: " << ret; + throw TimeoutError(__PRETTY_FUNCTION__,ss.str()); + } + } + } + catch (Exception &e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } +} + +//------------------------------------------------------------------------ + +void Semaphore::set() +{ + try + { + int ret = sem_post(&m_semaphore); + + if (ret != 0) + { + std::stringstream ss; + ss << "sem_post returned: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + } + catch (Exception &e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } +} diff --git a/CommonLib/src/Common/Lib/Semaphore.hpp b/CommonLib/src/Common/Lib/Semaphore.hpp new file mode 100644 index 0000000..a2c8650 --- /dev/null +++ b/CommonLib/src/Common/Lib/Semaphore.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include +#include "OSObject.hpp" + +class Semaphore : public OSObject +{ +public: + //>--------------------------------------------------------------------- + // Function: Semaphore + // + // Purpose: constructor + //---------------------------------------------------------------------- + // Arguments: name - the name of this object + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + Semaphore(const std::string& name); + + //>--------------------------------------------------------------------- + // Function: Semaphore + // + // Purpose: destroyer + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual ~Semaphore(); + + //>--------------------------------------------------------------------- + // Function: Set + // + // Purpose: set a semaphore + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void set(); + + //>--------------------------------------------------------------------- + // Function: Wait + // + // Purpose: Wait on a semaphore + //---------------------------------------------------------------------- + // Arguments: seconds - the seconds to wait + // nseconds - the nano seconds to wait + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void wait(time_t seconds = -1, long nseconds = -1); + +private: + // not allowed + Semaphore(const Semaphore& rhs); + Semaphore& operator=(const Semaphore& rhs); + + sem_t m_semaphore; +}; + diff --git a/CommonLib/src/Common/Lib/Thread.cpp b/CommonLib/src/Common/Lib/Thread.cpp new file mode 100644 index 0000000..bafe020 --- /dev/null +++ b/CommonLib/src/Common/Lib/Thread.cpp @@ -0,0 +1,123 @@ +#include +#include +#include +#include + +#include + +#include "Thread.hpp" +#include "Exception.hpp" + +//------------------------------------------------------------------------ + +Thread::Thread(const std::string &name, unsigned int stackSize) : + OSObject(name), + m_stackSize(stackSize), + m_id(0), + m_resumeCondition(name + "_RESUME_EVENT") +{ +} + +//------------------------------------------------------------------------ + +Thread::~Thread() +{ +} + +//------------------------------------------------------------------------ + +void* Thread::StartRoutine(void* pArg) +{ + // use this when we bomb + std::ostringstream oss; + + // this code below makes use of RTTI through dynamic_cast<>. For + // more information, see "The C++ Programming Language" 3th ed, by + // B. Stroustrup, section 15.4. + Thread *pBase = static_cast(pArg); + Thread *pObj = dynamic_cast(pBase); + + // hang out here until caller tells us to start + pBase->m_resumeCondition.wait(); + + if (pObj != 0) + { + try + { + (*pObj)(); // run the thread + } + catch (Exception& e) + { + oss << e.getMessage(); + // handle situation where thread is deleted before we get here + if (pObj) + { + oss << ", thread name = " << pObj->getName() << ", ID = " + << pObj->getID(); + } + oss << std::endl; + } + catch (std::exception& e) + { + oss << "std::exception: " + << e.what() + << " , thread name = " + << pObj->getName(); + } + catch (...) + { + oss << "pObj->operator()(), caught (...)," + << " thread name = " + << pObj->getName(); + } + } + + return 0; +} + +//------------------------------------------------------------------------ + +void Thread::create() +{ + try + { + pthread_attr_t attr; + pthread_attr_init(&attr); + + pthread_t handle = 0; + + int res = pthread_create(&handle, &attr, &StartRoutine, this); + + if (res != 0) + { + std::stringstream ss; + ss << "pthread_create returned: " << res; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + if (handle == 0) + { + std::stringstream ss; + ss << "pthread_create returned null handle"; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + setHandle((void*)handle); + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"Thread::Create() - unknown err"); + } +} + +//------------------------------------------------------------------------ + +void Thread::resume() +{ + m_resumeCondition.signal(); +} diff --git a/CommonLib/src/Common/Lib/Thread.hpp b/CommonLib/src/Common/Lib/Thread.hpp new file mode 100644 index 0000000..e200b7e --- /dev/null +++ b/CommonLib/src/Common/Lib/Thread.hpp @@ -0,0 +1,146 @@ +#pragma once + +#include +#include + +#include "OSObject.hpp" +#include "Condition.hpp" + +class Thread : public OSObject +{ +public: + enum { DEFAULT_STACK_SIZE = 4096 }; + + //>--------------------------------------------------------------------- + // Function: Thread() + // + // Purpose: constructor + //---------------------------------------------------------------------- + // Arguments:name - the name of this thread + // stackSize - + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + explicit Thread(const std::string &name, unsigned int stackSize = DEFAULT_STACK_SIZE); + + //>--------------------------------------------------------------------- + // Function: ~Thread() + // + // Purpose: destructor + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual ~Thread(); + + //>--------------------------------------------------------------------- + // Function: operator()() + // + // Purpose: where all the action is in the derived classes + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual void operator()() = 0; + + //>--------------------------------------------------------------------- + // Function: create() + // + // Purpose: to make call the system thread creation routine + //---------------------------------------------------------------------- + // Arguments: LPTHREAD_START_ROUTINE func, pointer to start function + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void create(); + + //>--------------------------------------------------------------------- + // Function: getID() + // + // Purpose: to get the ID of the thread + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: unsigned int, the ID + //<--------------------------------------------------------------------- + unsigned int getID() const { return m_id; } + + //>--------------------------------------------------------------------- + // Function: resume() + // + // Purpose: to use the same call to resume MFC and non-MFC threads + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void resume(); + + //>--------------------------------------------------------------------- + // Function: startRoutine() + // + // Purpose: to call the run() method of this class. It uses RTTI to + // determine what the derived type is and calls correct method. + //---------------------------------------------------------------------- + // Arguments: LPVOID pArg, 'this' pointer from create() method + //---------------------------------------------------------------------- + // Return Value: DWORD WINAPI, return zero for now + //<--------------------------------------------------------------------- + static void* StartRoutine(void* pArg); + + //>--------------------------------------------------------------------- + // Function: StartThread() + // + // Purpose: Commands the thread to run + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual void startThread() = 0; + + //>--------------------------------------------------------------------- + // Function: SuspendThread() + // + // Purpose: Commands the thread to pause its execution + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual void suspendThread() = 0; + + //>--------------------------------------------------------------------- + // Function: Quit() + // + // Purpose: Command the thread to exit + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + virtual void quit() = 0; + + //>--------------------------------------------------------------------- + // Function: WaitForThreadToExit() + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void waitForThreadToExit() { pthread_join((pthread_t)getHandle(), 0); }; + +private: + // do not allow + Thread(); + Thread(const Thread ©); + Thread &operator=(const Thread &rhs); + + unsigned int m_stackSize; + unsigned int m_id; + Condition m_resumeCondition; +}; diff --git a/CommonLib/src/Common/Lib/Timestamp.cpp b/CommonLib/src/Common/Lib/Timestamp.cpp new file mode 100644 index 0000000..3db94a5 --- /dev/null +++ b/CommonLib/src/Common/Lib/Timestamp.cpp @@ -0,0 +1,153 @@ +#include +#include +#include + +#include "sys/time.h" + +#include "Timestamp.hpp" +#include "Exception.hpp" + +//------------------------------------------------------------------------ + +Timestamp::Timestamp() : + m_currentTime(0), + m_timeString(), + m_startTime(0) +{ + timeBuff_[0] = '\0'; +} + +//------------------------------------------------------------------------ + +Timestamp::~Timestamp() +{ +} + +//------------------------------------------------------------------------ + +void Timestamp::startTiming() +{ + m_startTime = GetCurrentTimeMs(); +} + +//------------------------------------------------------------------------ + +unsigned int Timestamp::getElapsedTimeSecs() +{ + unsigned int currentTime = GetCurrentTimeMs(); + return (currentTime - m_startTime) / 1000; +} + +//------------------------------------------------------------------------ + +unsigned int Timestamp::getElapsedTimeMs() +{ + unsigned int currentTime = GetCurrentTimeMs(); + unsigned int delta = currentTime - m_startTime; + return delta; +} + +//------------------------------------------------------------------------ + +std::string Timestamp::getElapsedTimeString() +{ + double d = getElapsedTimeSecs(); + + std::stringstream ss; + ss << d; + + return ss.str(); +} + +//----------------------------------------------------------------------------- + +std::string Timestamp::GetCurrentDateTimeString(Timestamp::DateTimeFormat format, std::string separator) +{ + std::stringstream ss; + + struct timeval curTime; + gettimeofday(&curTime, 0); + int millisecs = curTime.tv_usec / 1000; + + struct tm* myTm = localtime(&curTime.tv_sec); + + try + { + switch (format) + { + case Timestamp::DateTimeFormat::YYYYMM: + ss << std::setfill('0') << "20" << std::setw(2)<< myTm->tm_year%100 + << separator << std::setfill('0') << std::setw(2) << myTm->tm_mon+1; + break; + case Timestamp::DateTimeFormat::YYYYMMDD: + ss << std::setfill('0') << "20" << std::setw(2)<< myTm->tm_year%100 + << separator << std::setfill('0') << std::setw(2) << myTm->tm_mon+1 + << separator << std::setfill('0') << std::setw(2) << myTm->tm_mday; + break; + case Timestamp::DateTimeFormat::MMDDYYYY: + ss << std::setfill('0') << std::setfill('0') << std::setw(2) << myTm->tm_mon+1 + << separator << std::setfill('0') << std::setw(2) << myTm->tm_mday + << separator << "20" << std::setw(2)<< myTm->tm_year%100; + break; + case Timestamp::DateTimeFormat::HHMMSS: + case Timestamp::DateTimeFormat::HHMMSSMM: + ss << std::setfill('0') << std::setw(2) << myTm->tm_hour << separator + << std::setfill('0') << std::setw(2) << myTm->tm_min << separator + << std::setfill('0') << std::setw(2) << myTm->tm_sec; + } + + if (format == Timestamp::DateTimeFormat::HHMMSSMM) + ss << "." << millisecs; + + return ss.str(); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +unsigned int Timestamp::GetCurrentTimeNs() +{ + const unsigned long NS_PER_SEC = 1000000000; + struct timespec curTime; + clock_gettime(CLOCK_REALTIME, &curTime); + + unsigned long curTimeNs = (curTime.tv_sec * NS_PER_SEC) + curTime.tv_nsec; + + return curTimeNs; +} + +//----------------------------------------------------------------------------- + +unsigned int Timestamp::GetCurrentTimeUs() +{ + const unsigned int NS_PER_SEC = 1000000000; + struct timespec curTime; + clock_gettime(CLOCK_REALTIME, &curTime); + + unsigned int curTimeNs = (curTime.tv_sec * NS_PER_SEC) + curTime.tv_nsec; + + return curTimeNs/1000; +} + +//----------------------------------------------------------------------------- + +unsigned int Timestamp::GetCurrentTimeMs() +{ + const unsigned long NS_PER_SEC = 1000000000; + struct timespec curTime; + clock_gettime(CLOCK_REALTIME, &curTime); + + unsigned long curTimeNs = (curTime.tv_sec * NS_PER_SEC) + curTime.tv_nsec; + + return curTimeNs/1000000; +} + +//----------------------------------------------------------------------------- + + + diff --git a/CommonLib/src/Common/Lib/Timestamp.hpp b/CommonLib/src/Common/Lib/Timestamp.hpp new file mode 100644 index 0000000..a35b7db --- /dev/null +++ b/CommonLib/src/Common/Lib/Timestamp.hpp @@ -0,0 +1,169 @@ +#pragma once + +#include +#include + +class Timestamp +{ +public: + enum class DateTimeFormat + { + YYYYMM, + YYYYMMDD, + MMDDYYYY, + HHMMSS, + HHMMSSMM + }; + + enum class TimeResolution + { + SECS, + MILLISECS + }; + + //>--------------------------------------------------------------------- + // Function: Timestamp() + // + // Purpose: constructor + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + Timestamp(); + + //>--------------------------------------------------------------------- + // Function: ~Timestamp() + // + // Purpose: destructor + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + ~Timestamp(); + + //>--------------------------------------------------------------------- + // Function: getLength() + // + // Purpose: to return the length of the time string + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: int, the length + //<--------------------------------------------------------------------- + int getLength() const { return CTIME_LENGTH_; } + + //>--------------------------------------------------------------------- + // Function: startTiming() + // + // Purpose: to start the timing to get some elapsed time + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void startTiming(); + + //>--------------------------------------------------------------------- + // Function: getElapsedTime() + // + // Purpose: to get the amount of elapsed time since the call to + // startTiming(). + // Note: clock returns the number of clock ticks of elapsed + // processor time. The returned value is the product of the amount + // of time that has elapsed since the start of a process and the + // value of the CLOCKS_PER_SEC constant. If the amount of elapsed + // time is unavailable, the function returns -1, cast as a + // clock_t. + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: double, seconds of elapsed time + //<--------------------------------------------------------------------- + unsigned int getElapsedTimeSecs(); + + //>--------------------------------------------------------------------- + // Function: GetElapsedTimeMs() + // + // Purpose: to get the amount of elapsed time since the call to + // startTiming(). + // Note: clock returns the number of clock ticks of elapsed + // processor time. The returned value is the product of the amount + // of time that has elapsed since the start of a process and the + // value of the CLOCKS_PER_SEC constant. If the amount of elapsed + // time is unavailable, the function returns -1, cast as a + // clock_t. + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: double, seconds of elapsed time + //<--------------------------------------------------------------------- + unsigned int getElapsedTimeMs(); + + //>--------------------------------------------------------------------- + // Function: getElapsedTimeString() + // + // Purpose: to do the same as getElapsedTime() but return std::string + //---------------------------------------------------------------------- + // Arguments: none + //---------------------------------------------------------------------- + // Return Value: std::string, seconds of elapsed time + //<--------------------------------------------------------------------- + std::string getElapsedTimeString(); + + //>--------------------------------------------------------------------- + // Function: GetTime + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + static std::string GetCurrentDateTimeString(Timestamp::DateTimeFormat format, std::string separator = ""); + + //>--------------------------------------------------------------------- + // Function: GetCurrentTimeNs + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + static unsigned int GetCurrentTimeNs(); + + //>--------------------------------------------------------------------- + // Function: GetCurrentTimeUs + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + static unsigned int GetCurrentTimeUs(); + + //>--------------------------------------------------------------------- + // Function: GetCurrentTimeMs + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + static unsigned int GetCurrentTimeMs(); + +private: + // do not allow + Timestamp(const Timestamp &rhs); + Timestamp &operator=(const Timestamp &rhs); + + enum { CTIME_LENGTH_ = 26 }; + char timeBuff_[CTIME_LENGTH_]; + time_t m_currentTime; + std::string m_timeString; + unsigned int m_startTime; +}; diff --git a/CommonLib/src/Common/Lib/Util/DateTimeUtil.cpp b/CommonLib/src/Common/Lib/Util/DateTimeUtil.cpp new file mode 100644 index 0000000..dadf6be --- /dev/null +++ b/CommonLib/src/Common/Lib/Util/DateTimeUtil.cpp @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "DateTimeUtil.hpp" +#include "Exception.hpp" +#include "Timestamp.hpp" + +//----------------------------------------------------------------------------- + +void Util::DateTime::Sleep(unsigned int msToSleep) +{ + const int MICO_TO_MS_CONVERSION = 1000; + + usleep(msToSleep * MICO_TO_MS_CONVERSION); +} diff --git a/CommonLib/src/Common/Lib/Util/DateTimeUtil.hpp b/CommonLib/src/Common/Lib/Util/DateTimeUtil.hpp new file mode 100644 index 0000000..211f3e3 --- /dev/null +++ b/CommonLib/src/Common/Lib/Util/DateTimeUtil.hpp @@ -0,0 +1,25 @@ +#ifndef DATE_TIME_UTIL_H +#define DATE_TIME_UTIL_H + +#include +#include + +namespace Util +{ + namespace DateTime + { + + //>--------------------------------------------------------------------- + // Function: Sleep + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + void Sleep(unsigned int msToSleep); + } +} + +#endif diff --git a/CommonLib/src/Common/Lib/Util/FileSystemUtil.cpp b/CommonLib/src/Common/Lib/Util/FileSystemUtil.cpp new file mode 100644 index 0000000..89842da --- /dev/null +++ b/CommonLib/src/Common/Lib/Util/FileSystemUtil.cpp @@ -0,0 +1,291 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "FileSystemUtil.hpp" +#include "Exception.hpp" +#include "Timestamp.hpp" + +//----------------------------------------------------------------------------- + +void Util::FileSystem::ChangeFilePermissions(const std::string& file, const unsigned int& permissions) +{ + try + { + int ret = chmod(file.c_str(), permissions); + + if (ret != 0) + { + std::stringstream ss; + ss << "Chmod returned " << ret << " for file " << file; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +void Util::FileSystem::CopyDirectory(const std::string& fromName, const std::string& toName) +{ + try + { + // recursive copy file/directory and retain permissions + std::stringstream cmdSs; + cmdSs << "cp -r -p " << fromName << " " << toName; + int ret = system(cmdSs.str().c_str()); + + if (ret != 0) + { + std::stringstream ss; + ss << "Could not copy: " << fromName << " to " << toName; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +void Util::FileSystem::CopyFile(const std::string& fromName, const std::string& toName) +{ + try + { + // copy the file and retain permissions in the new file + std::stringstream cmdCopySs; + cmdCopySs << "cp -p " << fromName << " " << toName; + int ret = system(cmdCopySs.str().c_str()); + + if (ret != 0) + { + std::stringstream ss; + ss << "Could not copy: " << fromName << " to " << toName; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + // remove the original + std::stringstream cmdRemoveSs; + cmdRemoveSs << "rm " << fromName; + ret = system(cmdRemoveSs.str().c_str()); + + if (ret != 0) + { + std::stringstream ss; + ss << "Could not remove: " << fromName; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +void Util::FileSystem::CreateDirectory(const std::string& directory) +{ + // if we saved a file, open up the permissions + const std::string FILE_PERMISSION_STR = "0777"; + + try + { + struct stat statBuf; + + if (stat(directory.c_str(), &statBuf) != -1) + { + if (S_ISDIR(statBuf.st_mode)) + { + // directory is already there + return; + } + } + + int ret = mkdir(directory.c_str(), S_IWOTH); + + if (ret != 0) + { + std::stringstream ss; + ss << "mkdir failed: " << ret; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + // change permissions + long permission = strtol(FILE_PERMISSION_STR.c_str(), 0, 8); + ChangeFilePermissions(directory, permission); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +std::string Util::FileSystem::GetExePathAndFilename() +{ + try + { + std::string strPath = ""; + char path[PATH_MAX] = { 0 }; + int nchar = readlink("/proc/self/exe", path, sizeof(path)); + + if (nchar > 0) + strPath = std::string(path); + + return strPath; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +int Util::FileSystem::IsFile(const char* path) +{ + try + { + struct stat pathStat; + stat(path, &pathStat); + return S_ISREG(pathStat.st_mode); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +int Util::FileSystem::IsDirectory(const char* path) +{ + try + { + struct stat pathStat; + stat(path, &pathStat); + return S_ISDIR(pathStat.st_mode); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +std::string Util::FileSystem::ExtractDirectory(const char* path) +{ + try + { + std::string dir = ""; + + if (IsFile(path)) + { + dir = std::string(path); + dir = dir.substr(0, dir.find_last_of('/') + 1); + } + + return dir; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +std::string Util::FileSystem::ExtractFilename(const char* path) +{ + try + { + std::string filename = ""; + + if (IsFile(path)) + { + filename = std::string(path); + filename = filename.substr(filename.find_last_of('/') + 1); + } + + return filename; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +std::string Util::FileSystem::AddSlashToPath(const std::string &path) +{ + char ch = path.back(); + char nativeSeparator = '/'; + std::string tempPath = path; + + std::string ss; + //ss.back() + if (ch != nativeSeparator) + tempPath = tempPath + nativeSeparator; + + return tempPath; +} + +//----------------------------------------------------------------------------- + +std::string Util::FileSystem::RemoveSlashInFrontOfPath(const std::string &path) +{ + char ch = path.back(); + char nativeSeparator = '/'; + std::string tempPath = path; + + if (ch == nativeSeparator) + tempPath = tempPath.substr(1,path.length()-1); + + return tempPath; +} + +//----------------------------------------------------------------------------- + +std::string Util::FileSystem::BuildPath(const std::string &left, const std::string &right) +{ + std::string path; + + path = AddSlashToPath(left); + + if (right.length() > 0) + path += RemoveSlashInFrontOfPath(right); + + return path; +} diff --git a/CommonLib/src/Common/Lib/Util/FileSystemUtil.hpp b/CommonLib/src/Common/Lib/Util/FileSystemUtil.hpp new file mode 100644 index 0000000..5e7137e --- /dev/null +++ b/CommonLib/src/Common/Lib/Util/FileSystemUtil.hpp @@ -0,0 +1,147 @@ +#ifndef FILE_SYSTEM_UTIL_H +#define FILE_SYSTEM_UTIL_H + +#include +#include + +namespace Util +{ + namespace FileSystem + { + //>--------------------------------------------------------------------- + // Function: ChangeFilePermissions + // + // Purpose: change the permissions on an existing file + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void ChangeFilePermissions(const std::string& file, const unsigned int& permissions); + + //>--------------------------------------------------------------------- + // Function: CopyDirectory + // + // Purpose: recursivly copy a directory + //---------------------------------------------------------------------- + // Arguments: fromName - + // toName - + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void CopyDirectory(const std::string& fromName, const std::string& toName); + + //>--------------------------------------------------------------------- + // Function: CopyFile1 + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: fromName - + // toName - + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void CopyFile(const std::string& fromName, const std::string& toName); + + //>--------------------------------------------------------------------- + // Function: CreateDirectory + // + // Purpose: creates a directory + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + void CreateDirectory(const std::string& directory); + + //>--------------------------------------------------------------------- + // Function: getExePathAndFilename + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string GetExePathAndFilename(); + + //>--------------------------------------------------------------------- + // Function: isFile + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + int IsFile(const char* path); + + //>--------------------------------------------------------------------- + // Function: isDirectory + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + int IsDirectory(const char* path); + + //>--------------------------------------------------------------------- + // Function: extractDirectory + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string ExtractDirectory(const char* path); + + //>--------------------------------------------------------------------- + // Function: extractFilename + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string ExtractFilename(const char* path); + + //>--------------------------------------------------------------------- + // Function: AddBackSlashToPath + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string AddSlashToPath(const std::string &path); + + //>--------------------------------------------------------------------- + // Function: RemoveSlashInFrontOfPath + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string RemoveSlashInFrontOfPath(const std::string &path); + + //>--------------------------------------------------------------------- + // Function: BuildPath + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string BuildPath(const std::string &left, const std::string &right = ""); + } +} + +#endif diff --git a/CommonLib/src/Common/Lib/Util/MiscUtil.cpp b/CommonLib/src/Common/Lib/Util/MiscUtil.cpp new file mode 100644 index 0000000..14a8afa --- /dev/null +++ b/CommonLib/src/Common/Lib/Util/MiscUtil.cpp @@ -0,0 +1,139 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "MiscUtil.hpp" +#include "StringUtil.hpp" +#include "Exception.hpp" +#include "Timestamp.hpp" + +//----------------------------------------------------------------------------- + +std::string Util::Misc::GetUuidString() +{ + static int uid = 0; + uid++; + + std::stringstream ss; + ss << uid; + + return ss.str(); +} + +//----------------------------------------------------------------------------- + +std::string Util::Misc::ParseErrorStringForDisplay(const std::string& errMsg) +{ + // want everything to the left of -> + std::size_t pos = errMsg.find("->"); + + std::string userMsg = errMsg.substr (0, pos); + + return userMsg; +} + +//----------------------------------------------------------------------------- + +std::string Util::Misc::ReadFromStandardInput() +{ + try + { + std::string txt = ""; + + char* line = 0; + size_t len = 0; + ssize_t read; + + read = getline(&line, &len, stdin); + std::stringstream ss; + + if (read > 0) + { + line[read - 1] = '\0'; + ss << line; + txt = ss.str(); + + free(line); + } + + return txt; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +std::string Util::Misc::GetComputerName() +{ + try + { + char hostname[HOST_NAME_MAX] = {"\0"}; + gethostname(hostname, HOST_NAME_MAX); + + return std::string(hostname); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +std::map Util::Misc::GetUsersOfRunningProcess(const std::string& processName) +{ + std::map users; + + try + { + const int BUF_SIZE = 512; + char buf[BUF_SIZE] = {"\0"}; + std::string command = "pidof " + processName; + FILE *cmdPipe = popen(command.c_str(), "r"); + // run the command to get the process id of the process name + fgets(buf, BUF_SIZE, cmdPipe); + pclose(cmdPipe); + std::string val(buf); + val = val.substr(0, val.length()-1); + std::vector uidVec = Util::Strings::StringSplit(val, " ", false); + + for (std::vector::iterator it = uidVec.begin(); it != uidVec.end(); it++) + { + command = "ps -o uname= -p " + *it; + cmdPipe = popen(command.c_str(), "r"); + // get the user id of the process id + fgets(buf,BUF_SIZE,cmdPipe); + pclose(cmdPipe); + val = std::string(buf); + val = val.substr(0, val.length()-1); + users[*it]=val; + } + + return users; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} diff --git a/CommonLib/src/Common/Lib/Util/MiscUtil.hpp b/CommonLib/src/Common/Lib/Util/MiscUtil.hpp new file mode 100644 index 0000000..0258eb8 --- /dev/null +++ b/CommonLib/src/Common/Lib/Util/MiscUtil.hpp @@ -0,0 +1,72 @@ +#ifndef MISC_UTIL_H +#define MISC_UTIL_H + +#include +#include +#include + +namespace Util +{ + namespace Misc + { + //>--------------------------------------------------------------------- + // Function: GetUuidString + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string GetUuidString(); + + //>--------------------------------------------------------------------- + // Function: ParseErrorStringForDisplay + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string ParseErrorStringForDisplay(const std::string& errMsg); + + + //>--------------------------------------------------------------------- + // Function: readFromStandardInput + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string ReadFromStandardInput(); + + //>--------------------------------------------------------------------- + // Function: GetComputerName + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string GetComputerName(); + + //>--------------------------------------------------------------------- + // Function: GetUsersOfRunningProcess + // + // Purpose: + // Get all the process ids and the user ids of a running process + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + // the map pair [process id] = [user id] + //<--------------------------------------------------------------------- + std::map GetUsersOfRunningProcess(const std::string& processName); + } +} + +#endif diff --git a/CommonLib/src/Common/Lib/Util/NetworkUtil.cpp b/CommonLib/src/Common/Lib/Util/NetworkUtil.cpp new file mode 100644 index 0000000..90c3390 --- /dev/null +++ b/CommonLib/src/Common/Lib/Util/NetworkUtil.cpp @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "NetworkUtil.hpp" +#include "StringUtil.hpp" +#include "Exception.hpp" +#include "Timestamp.hpp" + +//------------------------------------------------------------------------ + +bool Util::Network::IsIpAddress(const std::string& ipAddress) +{ + try + { + std::string octet; + for (int i = 0; i < 4; i++) + { + octet = Strings::GetSubstringDelimited(ipAddress, ".", i); + if (Strings::IsNumeric(octet)) + { + std::stringstream ss; + ss << octet; + int num; + ss >> num; + if (num > 254) + return false; + } + else + return false; + } + + return true; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +std::string Util::Network::ConvertHostnameToIp(std::string hostname) +{ + struct addrinfo hints, * servinfo = 0, * p; + struct sockaddr_in* h; + int rv; + + try + { + std::string ip = hostname; + // convert to dot address notation if needed + if (hostname.length() > 0 && !IsIpAddress(hostname)) + { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6 + hints.ai_socktype = SOCK_STREAM; + + if ((rv = getaddrinfo(hostname.c_str(), "http", &hints, &servinfo)) != 0) + { + throw Exception(__PRETTY_FUNCTION__, "getaddrinfo() failed"); + } + + // loop through all the results and connect to the first we can + for (p = servinfo; p != 0; p = p->ai_next) + { + h = (struct sockaddr_in*)p->ai_addr; + ip = std::string(inet_ntoa(h->sin_addr)); + } + + if (servinfo != 0) + freeaddrinfo(servinfo); // all done with this structure + } + + return ip; + } + catch (Exception& e) + { + if (servinfo != 0) + freeaddrinfo(servinfo); + + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} diff --git a/CommonLib/src/Common/Lib/Util/NetworkUtil.hpp b/CommonLib/src/Common/Lib/Util/NetworkUtil.hpp new file mode 100644 index 0000000..07c2a98 --- /dev/null +++ b/CommonLib/src/Common/Lib/Util/NetworkUtil.hpp @@ -0,0 +1,35 @@ +#ifndef NETWORK_UTIL_H +#define NETWORK_UTIL_H + +#include +#include + +namespace Util +{ + namespace Network + { + //>--------------------------------------------------------------------- + // Function: IsIpAddress + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + bool IsIpAddress(const std::string& ipAddress); + + //>--------------------------------------------------------------------- + // Function: convertHostnameToIp + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string ConvertHostnameToIp(std::string hostname); + } +} + +#endif diff --git a/CommonLib/src/Common/Lib/Util/PosixRegexUtil.cpp b/CommonLib/src/Common/Lib/Util/PosixRegexUtil.cpp new file mode 100644 index 0000000..b5e1434 --- /dev/null +++ b/CommonLib/src/Common/Lib/Util/PosixRegexUtil.cpp @@ -0,0 +1,107 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "PosixRegexUtil.hpp" +#include "Timestamp.hpp" + +//----------------------------------------------------------------------------- + +std::vector Util::PosixRegex::GetMatchesFromRegex(std::string text, std::string pattern, bool caseSensitive) +{ + std::vector vecMatches; + regex_t regex; + const int MAX_MATCHES = 10; + regmatch_t matches[MAX_MATCHES]; + + int flags = REG_EXTENDED; + + if (!caseSensitive) + flags |= REG_ICASE; + + if (regcomp(®ex, pattern.c_str(), flags)) + return vecMatches; + + unsigned int m = 0; + char* cursor = (char*)text.c_str(); + + for (m = 0; m < MAX_MATCHES - 1; m++) + { + if (regexec(®ex, cursor, MAX_MATCHES + 1, matches, 0)) + break; // no more matches + + unsigned int offset = 0; + for (int g = 0; g < MAX_MATCHES; g++) + { + if (matches[g].rm_so == -1) + break; // no more groups + + if (g == 0) + offset = matches[g].rm_eo; + + char cursorCopy[strlen(cursor) + 1]; + strcpy(cursorCopy, cursor); + cursorCopy[matches[g].rm_eo] = 0; + vecMatches.push_back(cursorCopy + matches[g].rm_so); + } + cursor += offset; + } + regfree(®ex); + return vecMatches; +} + +//----------------------------------------------------------------------------- + +bool Util::PosixRegex::IsMatch(std::string text, std::string pattern, bool caseSensitive) +{ + bool isMatch = false; + + std::vector vecMatches = GetMatchesFromRegex(text, pattern, caseSensitive); + + if (vecMatches.size() > 0) + isMatch = true; + + return isMatch; +} + +//----------------------------------------------------------------------------- + +std::string Util::PosixRegex::EscapeMetaChars(std::string text) +{ + std::string posixMetaChars = "\\()[].^$*?"; + + for (int i=0; i<(int)posixMetaChars.length(); i++) + { + std::string left = ""; + std::string right = ""; + std::size_t index = text.find(posixMetaChars[i]); + + if (index != std::string::npos) + { + if (index > 0) + { + left = text.substr(0,index); + } + + right = "\\" + text.substr(index,text.length()); + + text = left + right; + } + } + + return text; +} diff --git a/CommonLib/src/Common/Lib/Util/PosixRegexUtil.hpp b/CommonLib/src/Common/Lib/Util/PosixRegexUtil.hpp new file mode 100644 index 0000000..668e32b --- /dev/null +++ b/CommonLib/src/Common/Lib/Util/PosixRegexUtil.hpp @@ -0,0 +1,46 @@ +#ifndef POSIX_REGEX_UTIL_H +#define POSIX_REGEX_UTIL_H + +#include +#include + +namespace Util +{ + namespace PosixRegex + { + //>--------------------------------------------------------------------- + // Function: GetMatchesFromRegex + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::vector GetMatchesFromRegex(std::string text, std::string pattern, bool caseSensitive = false); + + //>--------------------------------------------------------------------- + // Function: IsMatch + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + bool IsMatch(std::string text, std::string pattern, bool caseSensitive = false); + + //>--------------------------------------------------------------------- + // Function: EscapeMetaChars + // + // Purpose: Escape posix regex metacharacters + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string EscapeMetaChars(std::string text); + } +} + +#endif // ConfigFileManager_H diff --git a/CommonLib/src/Common/Lib/Util/StringUtil.cpp b/CommonLib/src/Common/Lib/Util/StringUtil.cpp new file mode 100644 index 0000000..4b1fd44 --- /dev/null +++ b/CommonLib/src/Common/Lib/Util/StringUtil.cpp @@ -0,0 +1,304 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "StringUtil.hpp" +#include "Exception.hpp" +#include "Timestamp.hpp" + +//----------------------------------------------------------------------------- + +std::vector Util::Strings::StringSplit(const std::string& s, const std::string& delim, const bool keepEmpty) +{ + std::vector result; + if (delim.empty()) + { + result.push_back(s); + } + else + { + std::string::const_iterator substart = s.begin(), subend; + while (true) + { + subend = std::search(substart, s.end(), delim.begin(), delim.end()); + std::string temp(substart, subend); + if (keepEmpty || !temp.empty()) + { + result.push_back(temp); + } + if (subend == s.end()) + { + break; + } + substart = subend + delim.size(); + } + } + return result; +} + +//----------------------------------------------------------------------------- + +std::string Util::Strings::ToLower(const std::string& s) +{ + try + { + std::string lower(s); + for(size_t i = 0; i < s.length(); i++) + { + lower[i] = tolower(lower[i]); + } + + return lower; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +std::string Util::Strings::ToUpper(const std::string& s) +{ + try + { + std::string upper(s); + for(size_t i = 0; i < s.length(); i++) + { + upper[i] = toupper(upper[i]); + } + + return upper; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +std::string Util::Strings::TrimSpaces(const std::string& s) +{ + try + { + size_t firstNonSpace = s.find_first_not_of(' '); + size_t lastNonSpace = s.find_last_not_of(' '); + + // if no leading space, then start at beginning of string + if (firstNonSpace == std::string::npos) + { + firstNonSpace = 0; + } + + return s.substr(firstNonSpace, lastNonSpace - firstNonSpace + 1); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +double Util::Strings::ToDouble(const std::string& string) +{ + try + { + std::stringstream ss; + ss << string; + + double temp = 0.0; + + ss >> temp; + + return temp; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +std::string Util::Strings::ToString(const int& val) +{ + try + { + std::stringstream ss; + ss << val; + return ss.str(); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +std::string Util::Strings::ToString(const double& val) +{ + try + { + std::stringstream ss; + ss << val; + return ss.str(); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +std::string Util::Strings::GetSubstringDelimited(std::string s, std::string delimiter, int index) +{ + try + { + std::vector row; + + row = StringSplit(s, delimiter, false); + + if ((int)row.size() > index) + return row[index]; + else + return ""; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +bool Util::Strings::IsNumeric(const std::string& s) +{ + try + { + int sizeOfString = static_cast(s.length()); + int iteration = 0; + bool isNumeric = true; + + if (sizeOfString == 0) + isNumeric = false; + + while (iteration < sizeOfString) + { + if (!isdigit(s[iteration])) + { + isNumeric = false; + break; + } + + iteration++; + } + + return isNumeric; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +bool Util::Strings::StringsAreEqual(std::string str1, std::string str2, bool caseSensitive) +{ + bool stringsAreEqual = false; + + if (!caseSensitive) + { + std::transform(str1.begin(), str1.end(), str1.begin(), toupper); + std::transform(str2.begin(), str2.end(), str2.begin(), toupper); + } + + if (str1 == str2) + stringsAreEqual = true; + + return stringsAreEqual; + +} + +//----------------------------------------------------------------------------- + +std::string Util::Strings::ByteArrayToHexString(unsigned char* byteArray, unsigned int numBytes) +{ + try + { + std::stringstream ss; + + for (unsigned int i = 0; i < numBytes; i++) + { + if (i == 0) + ss << "0x"; + else + ss << " "; + + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byteArray[i]); + } + + return ss.str(); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//----------------------------------------------------------------------------- + +std::string Util::Strings::ByteArrayToString(unsigned char* byteArray, unsigned int numBytes) +{ + unsigned char* pTempBuf = 0; + try + { + pTempBuf = new unsigned char[numBytes + 1]; + + memcpy(pTempBuf, byteArray, numBytes); + pTempBuf[numBytes] = '\0'; + + std::string str(reinterpret_cast(pTempBuf)); + + if (pTempBuf != 0) + delete[] pTempBuf; + + return str; + } + catch (Exception& e) + { + if (pTempBuf != 0) + delete[] pTempBuf; + + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} diff --git a/CommonLib/src/Common/Lib/Util/StringUtil.hpp b/CommonLib/src/Common/Lib/Util/StringUtil.hpp new file mode 100644 index 0000000..9721b2b --- /dev/null +++ b/CommonLib/src/Common/Lib/Util/StringUtil.hpp @@ -0,0 +1,145 @@ +#ifndef STRING_UTIL_H +#define STRING_UTIL_H + +#include +#include + +namespace Util +{ + namespace Strings + { + //>--------------------------------------------------------------------- + // Function: Split + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::vector StringSplit(const std::string& s, const std::string& delim, const bool keepEmpty = false); + + //>--------------------------------------------------------------------- + // Function: ToDouble + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + double ToDouble(const std::string& string); + + //>--------------------------------------------------------------------- + // Function: ToLower + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string ToLower(const std::string& s); + + //>--------------------------------------------------------------------- + // Function: ToString + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string ToString(const int& val); + + //>--------------------------------------------------------------------- + // Function: ToString + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string ToString(const double& val); + + //>--------------------------------------------------------------------- + // Function: ToUpper + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string ToUpper(const std::string& s); + + //>--------------------------------------------------------------------- + // Function: TrimSpaces + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string TrimSpaces(const std::string& s); + + //>--------------------------------------------------------------------- + // Function: GetSubstringDelimited + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string GetSubstringDelimited(std::string s, std::string delimiter, int index); + + //>--------------------------------------------------------------------- + // Function: IsNumeric + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + bool IsNumeric(const std::string& s); + + //>--------------------------------------------------------------------- + // Function: StringsAreEqual + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + bool StringsAreEqual(std::string str1, std::string str2, bool caseSensitive = false); + + //>--------------------------------------------------------------------- + // Function: ByteArrayToHexString + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string ByteArrayToHexString(unsigned char* byteArray, unsigned int numBytes); + + //>--------------------------------------------------------------------- + // Function: ByteArrayToString + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: + //<--------------------------------------------------------------------- + std::string ByteArrayToString(unsigned char* byteArray, unsigned int numBytes); + } +} + +#endif diff --git a/CommonLib/src/Common/Mail/AckMail.cpp b/CommonLib/src/Common/Mail/AckMail.cpp new file mode 100644 index 0000000..87cab02 --- /dev/null +++ b/CommonLib/src/Common/Mail/AckMail.cpp @@ -0,0 +1,67 @@ +#include +#include "AckMail.hpp" + +//----------------------------------------------------------------------------- + +AckMail::AckMail(const AckMail& rhs) : + Mail(rhs), + m_msg(rhs.m_msg) +{ +} + +//------------------------------------------------------------------------------ + +AckMail::AckMail(const MailHeader::MailEndPoint& source, const MailHeader::MailEndPoint& destination, const unsigned int& sequenceNumber): + Mail(MailHeader::ACK, source, destination, "Ack Mail", sizeof(m_msg)), + m_msg() +{ + m_msg.sequenceNumber = sequenceNumber; +} + +//------------------------------------------------------------------------------ + +AckMail::~AckMail() +{ +} + +//------------------------------------------------------------------------------ + +Mail* AckMail::cloneSelf() +{ + AckMail* pMsg = new AckMail(*this); + + return pMsg; +} + +//------------------------------------------------------------------------------ + +void AckMail::formatData(unsigned char* pBuffer) +{ + memcpy(pBuffer, &m_msg, sizeof(m_msg)); +} + +//------------------------------------------------------------------------ + +unsigned int AckMail::getSequencNumber() const +{ + return m_msg.sequenceNumber; +} + +//------------------------------------------------------------------------ + +std::ostream& AckMail::insert(std::ostream& os) const +{ + Mail::insert(os); + + os << "Payload(h): \n"; + os << " sequenceNumber: " << m_msg.sequenceNumber << "\n\n"; + + return os; +} + +//------------------------------------------------------------------------------ + +void AckMail::parseData(const unsigned char* pBuffer) +{ + memcpy(&m_msg, pBuffer, sizeof(m_msg)); +} diff --git a/CommonLib/src/Common/Mail/AckMail.hpp b/CommonLib/src/Common/Mail/AckMail.hpp new file mode 100644 index 0000000..fb9d021 --- /dev/null +++ b/CommonLib/src/Common/Mail/AckMail.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include "Mail.hpp" + +//------------------------------------------------------------------------------ + +class AckMail : public Mail +{ +public: + AckMail(const AckMail ©); + + AckMail(const MailHeader::MailEndPoint& source, const MailHeader::MailEndPoint& destination, const unsigned int& sequenceNumber); + + ~AckMail(); + + unsigned int getSequencNumber() const; + +protected: + // virtual functions from base class + virtual void formatData(unsigned char* pBuffer); + virtual std::ostream& insert(std::ostream& os) const; + virtual void parseData(const unsigned char* pBuffer); + virtual Mail* cloneSelf(); + +private: + // do not allow + AckMail &operator=(const AckMail& rhs); + +#pragma pack(1) + struct Message + { + //int length; + unsigned int sequenceNumber; + //char sz_argument[MAX_MSG_ARGUMENT]; + }; +#pragma pack() + + Message m_msg; +}; diff --git a/CommonLib/src/Common/Mail/Mail.cpp b/CommonLib/src/Common/Mail/Mail.cpp new file mode 100644 index 0000000..52c22ca --- /dev/null +++ b/CommonLib/src/Common/Mail/Mail.cpp @@ -0,0 +1,123 @@ +#include +#include "Mail.hpp" + +//------------------------------------------------------------------------------ + +Mail::Mail(const MailHeader::MailId& mailId, const MailHeader::MailEndPoint& source, const MailHeader::MailEndPoint& destination, const std::string& description, int dataSize): + m_description(description), + m_header(mailId, source, destination, dataSize) +{ +} + +//----------------------------------------------------------------------------- + +Mail::Mail(const Mail& rhs) : + m_description(rhs.m_description), + m_header(rhs.m_header) +{ +} + +//------------------------------------------------------------------------------ + +Mail::~Mail() +{ +} + +//------------------------------------------------------------------------------ + +Mail* Mail::clone() +{ + // ask the child class to clone itself + return cloneSelf(); +} + +//------------------------------------------------------------------------------ + +void Mail::format(unsigned char* pBuffer) +{ + // ask header to format its data + m_header.format(pBuffer); + + // ask child class to format its data + formatData(pBuffer + m_header.getHeaderSize()); +} + +//------------------------------------------------------------------------------ + +MailHeader::MailEndPoint Mail::getSource() const +{ + return m_header.getSource(); +} + +//------------------------------------------------------------------------------ + +MailHeader::MailEndPoint Mail::getDestination() const +{ + return m_header.getDestination(); +} + +//------------------------------------------------------------------------------ + +MailHeader::MailId Mail::getMsgId() const +{ + return m_header.getMsgId(); +} + +//------------------------------------------------------------------------------ + +unsigned int Mail::getDataSize() const +{ + return m_header.getDataSize(); +} + +//------------------------------------------------------------------------------ + +unsigned int Mail::getHeaderSize() const +{ + return m_header.getHeaderSize(); +} + +//------------------------------------------------------------------------------ + +time_t Mail::getTimeStamp() const +{ + return m_header.getTimeStamp(); +} + +//------------------------------------------------------------------------------ + +std::string Mail::getDescription() const +{ + return m_description; +} + +//------------------------------------------------------------------------ + +std::ostream& Mail::insert(std::ostream& os) const +{ + os << "Description: " << getDescription() << "\n" << m_header; + + return os; +} + +//------------------------------------------------------------------------------ + +void Mail::parse(const unsigned char* pBuffer) +{ + m_header.parse(pBuffer); + parseData(pBuffer + m_header.getHeaderSize()); +} + +//------------------------------------------------------------------------ + +void Mail::setDataSize(const int& payloadSize) +{ + m_header.setDataSize(payloadSize); +} + +//------------------------------------------------------------------------ + +std::ostream& operator<<(std::ostream& os, Mail& msg) +{ + return msg.insert(os); +} diff --git a/CommonLib/src/Common/Mail/Mail.hpp b/CommonLib/src/Common/Mail/Mail.hpp new file mode 100644 index 0000000..864b617 --- /dev/null +++ b/CommonLib/src/Common/Mail/Mail.hpp @@ -0,0 +1,48 @@ +#pragma once +#include +#include +#include "MailHeader.hpp" + +//------------------------------------------------------------------------------ + +class Mail +{ +public: + virtual ~Mail(); + + Mail* clone(); + + void format(unsigned char* pBuffer); + std::string getDescription() const; + MailHeader::MailId getMsgId() const; + MailHeader::MailEndPoint getSource() const; + MailHeader::MailEndPoint getDestination() const; + unsigned int getDataSize() const; + unsigned int getHeaderSize() const; + time_t getTimeStamp() const; + void parse(const unsigned char* pBuffer); + void setDataSize(const int& payloadSize); + + friend std::ostream& operator<<(std::ostream& os, Mail& msg); + +protected: + Mail(const Mail ©); + + Mail(const MailHeader::MailId& mailId, const MailHeader::MailEndPoint& source, const MailHeader::MailEndPoint& destination, const std::string& description, int dataSize); + + virtual std::ostream& insert(std::ostream& os) const; + + virtual Mail* cloneSelf() = 0; + + virtual void formatData(unsigned char* pBuffer) = 0; + + virtual void parseData(const unsigned char* pBuffer) = 0; + +private: + // do not allow + Mail(); + Mail &operator=(const Mail &rhs); + + std::string m_description; + MailHeader m_header; +}; diff --git a/CommonLib/src/Common/Mail/MailHeader.cpp b/CommonLib/src/Common/Mail/MailHeader.cpp new file mode 100644 index 0000000..860f02e --- /dev/null +++ b/CommonLib/src/Common/Mail/MailHeader.cpp @@ -0,0 +1,111 @@ +#include +#include +#include "MailHeader.hpp" + +//----------------------------------------------------------------------------- + +MailHeader::MailHeader(const MailHeader& rhs) : + m_header(rhs.m_header) +{ +} + +//------------------------------------------------------------------------------ + +MailHeader::MailHeader(): + m_header() +{ +} + +//------------------------------------------------------------------------------ + +MailHeader::MailHeader(const MailHeader::MailId& mailId, const MailHeader::MailEndPoint& source, const MailHeader::MailEndPoint& destination, const unsigned int& payloadSize): + m_header() +{ + m_header.mailId = mailId; + m_header.source = source; + m_header.destination = destination; + m_header.dataSize = payloadSize + getHeaderSize(); + m_header.timeStamp = time(0); +} + +//------------------------------------------------------------------------------ + +MailHeader::~MailHeader() +{ +} + +//------------------------------------------------------------------------------ + +void MailHeader::format(unsigned char* pBuffer) +{ + memcpy(pBuffer, &m_header, sizeof(m_header)); +} + +//------------------------------------------------------------------------------ + +MailHeader::MailEndPoint MailHeader::getSource() const +{ + return m_header.source; +} + +//------------------------------------------------------------------------------ + +MailHeader::MailEndPoint MailHeader::getDestination() const +{ + return m_header.destination; +} + +//------------------------------------------------------------------------------ + +MailHeader::MailId MailHeader::getMsgId() const +{ + return m_header.mailId; +} + +//------------------------------------------------------------------------------ + +unsigned int MailHeader::getDataSize() const +{ + return m_header.dataSize; +} + +//------------------------------------------------------------------------------ + +time_t MailHeader::getTimeStamp() const +{ + return m_header.timeStamp; +} + +//------------------------------------------------------------------------------ + +unsigned int MailHeader::getHeaderSize() +{ + return sizeof(MailHeader::Header); +} + +//------------------------------------------------------------------------------ + +void MailHeader::parse(const unsigned char* pBuffer) +{ + ::memcpy(&m_header, pBuffer, sizeof(m_header)); +} + +//------------------------------------------------------------------------ + +void MailHeader::setDataSize(int payloadSize) +{ + m_header.dataSize = payloadSize + getHeaderSize(); +} + +//------------------------------------------------------------------------------ + +std::ostream& operator<<(std::ostream& os, const MailHeader& header) +{ + os << "Header(h): \n"; + os << " source: " << header.getSource() << "\n" ; + os << " destination: " << header.getDestination() << "\n"; + os << " mailID: " << header.getMsgId() << "\n"; + os << " timeStamp: " << header.getTimeStamp() << "\n"; + + return os; +} diff --git a/CommonLib/src/Common/Mail/MailHeader.hpp b/CommonLib/src/Common/Mail/MailHeader.hpp new file mode 100644 index 0000000..2844068 --- /dev/null +++ b/CommonLib/src/Common/Mail/MailHeader.hpp @@ -0,0 +1,74 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +class MailHeader +{ +public: + enum MailId + { + ACK, + CMD_ERROR_LOG + }; + + enum MailEndPoint + { + UTAP, + REPLAY, + CHAMBER_TEMPS, + STREAM_PROCESS, + ECU_READ, + USI_MANAGER, + SCIENCE, + HOUSEKEEPING, + HRPT, + GAC, + RECORDING_REPLAY, + UTAP_TD, + NA + }; + + MailHeader(const MailHeader ©); + + MailHeader(); + + MailHeader(const MailHeader::MailId& id, const MailHeader::MailEndPoint& source, const MailHeader::MailEndPoint& destination, const unsigned int& payloadSize); + + ~MailHeader(); + + void format(unsigned char* pBuffer); + + // getters + MailHeader::MailEndPoint getSource() const; + MailHeader::MailEndPoint getDestination() const; + MailHeader::MailId getMsgId() const; + unsigned int getDataSize() const; + time_t getTimeStamp() const; + + static unsigned int getHeaderSize(); + + void parse(const unsigned char* pBuffer); + + void setDataSize(int payloadSize); + + friend std::ostream& operator<<(std::ostream& os, const MailHeader& header); + +private: + +#pragma pack(1) + struct Header + { + MailHeader::MailEndPoint source; + MailHeader::MailEndPoint destination; + MailHeader::MailId mailId; + unsigned int dataSize; + time_t timeStamp; + }; +#pragma pack() + + + Header m_header; +}; + diff --git a/CommonLib/src/Common/Mail/MailQueue.cpp b/CommonLib/src/Common/Mail/MailQueue.cpp new file mode 100644 index 0000000..d59d3de --- /dev/null +++ b/CommonLib/src/Common/Mail/MailQueue.cpp @@ -0,0 +1,128 @@ +#include +#include "MailQueue.hpp" +#include "Exception.hpp" +#include "Mail.hpp" + +//----------------------------------------------------------------------------- + +MailQueue::MailQueue(const std::string& name): + OSObject(name), + m_mailQueue() +{ +} + +//----------------------------------------------------------------------------- + +MailQueue::~MailQueue() +{ + // empty out the queue and clean up memory + try + { + clearQueue(); + } + catch(...) + { + // do not throw + } +} + +//----------------------------------------------------------------------------- + +void MailQueue::addMail(Mail* pMail) +{ + try + { + // create a copy of the mail + Mail* pMyMailCopy = pMail->clone(); + + m_mailQueue.push_front(pMyMailCopy);// put the newest msg in the front + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"MailQueue::addMsgToQueue() - caught unknown err"); + } +} + +//----------------------------------------------------------------------------- + +void MailQueue::clearQueue() +{ + try + { + int numElements = getNumMailItemsQueue(); + + for (int i = 0; i < numElements; i++) + { + Mail* pMail = m_mailQueue.back(); + + delete pMail; + + pMail = 0; + } + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"MailQueue::clearQueue() - caught unknown err"); + } +} + +//----------------------------------------------------------------------------- + +unsigned int MailQueue::getNumMailItemsQueue() +{ + try + { + return m_mailQueue.size(); + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"MailQueue::GetNumMailItemsQueue() - caught unknown err"); + } +} + +//----------------------------------------------------------------------------- + +Mail* MailQueue::getOldestMail() +{ + try + { + if (getNumMailItemsQueue() > 0) + { + // caller must delete this object when they are done with it + Mail* pMail = m_mailQueue.back(); + m_mailQueue.pop_back(); + return pMail; + } + else + { + std::stringstream ss; + ss << "MailQueue::GetOldestMail() - there is no mail in the buffer"; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + } + catch(Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } + catch(...) + { + throw Exception(__PRETTY_FUNCTION__,"MailQueue::getMsg() - caught unknown err"); + } +} + diff --git a/CommonLib/src/Common/Mail/MailQueue.hpp b/CommonLib/src/Common/Mail/MailQueue.hpp new file mode 100644 index 0000000..566a9f7 --- /dev/null +++ b/CommonLib/src/Common/Mail/MailQueue.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include + +#include "OSObject.hpp" + +class Mail; + +//------------------------------------------------------------------------------ + +class MailQueue : OSObject +{ +public: + MailQueue(const std::string& name); + + ~MailQueue(); + + void addMail(Mail* pMail); + + void clearQueue(); + + Mail* getOldestMail(); + + //Mail* GetNewestMail(); + + unsigned int getNumMailItemsQueue(); + +private: + // private constructors... + MailQueue(const MailQueue& copy); + MailQueue &operator=(const MailQueue& rhs); + + // private members + std::deque m_mailQueue; +}; diff --git a/CommonLib/src/Common/Mail/Mailslot.cpp b/CommonLib/src/Common/Mail/Mailslot.cpp new file mode 100644 index 0000000..4746b51 --- /dev/null +++ b/CommonLib/src/Common/Mail/Mailslot.cpp @@ -0,0 +1,157 @@ +#include "Mailslot.hpp" +#include "Exception.hpp" +#include "LockMutex.hpp" +#include "TimeoutError.hpp" +#include "Constants.hpp" + +Mailslot::Mailslot(const std::string& name) : + OSObject(name), + m_mutex(name + "_Mutex"), + m_mail(name + "_MailQueue"), + m_semaphore(name + " _DataReadySem") +{ + try + { + } + catch(...) + { + //nothing to do here + } +} + +//------------------------------------------------------------------------ + +Mailslot::~Mailslot() +{ + try + { + } + catch(...) + { + //nothing to do here + } +} + +//------------------------------------------------------------------------ + +Mail* Mailslot::read(unsigned int timeoutInMs) +{ + Mail* pMailToReturn = NULL; + + try + { + //--------------------Perform the wait if commanded------------------ + + if (timeoutInMs == CommonLibConstants::INFINITE) + { + m_semaphore.wait(); + } + else if (timeoutInMs > 0) + { + try + { + const unsigned long sec = timeoutInMs/1000; + const unsigned long ms = timeoutInMs % 1000; + const unsigned long ns = ms * 1000000; + + m_semaphore.wait(sec, ns); + } + catch (TimeoutError& e) + { + // expected...log and continue + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } + } + + LockMutex lock(&m_mutex); + + //--------------------Get the Mail------------------ + + int numMail = m_mail.getNumMailItemsQueue(); + + if (numMail > 0)// need to do this check for the case where there was no wait commanded. + { + pMailToReturn = m_mail.getOldestMail(); + } + + return pMailToReturn; + } + catch (TimeoutError& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +void Mailslot::send(Mail* pMail) +{ + try + { + LockMutex lock(&m_mutex); + + m_mail.addMail(pMail); + + m_semaphore.set(); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +int Mailslot::getNumMsgs() +{ + try + { + LockMutex lock(&m_mutex); + + return m_mail.getNumMailItemsQueue(); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} + +//------------------------------------------------------------------------ + +bool Mailslot::isThereMail() +{ + try + { + LockMutex lock(&m_mutex); + + int numMsgs = m_mail.getNumMailItemsQueue(); + + if (numMsgs > 0) + { + return true; + } + else + { + return false; + } + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} diff --git a/CommonLib/src/Common/Mail/Mailslot.hpp b/CommonLib/src/Common/Mail/Mailslot.hpp new file mode 100644 index 0000000..d97803c --- /dev/null +++ b/CommonLib/src/Common/Mail/Mailslot.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include "OSObject.hpp" +#include "Constants.hpp" +#include "Condition.hpp" +#include "Semaphore.hpp" +#include "MailQueue.hpp" +#include "Mutex.hpp" + +class Mailslot : public OSObject +{ +public: + Mailslot(const std::string& name); + + ~Mailslot(); + + bool isThereMail(); + int getNumMsgs(); + Mail* read(unsigned int timeoutInMs = CommonLibConstants::INFINITE); + void send(Mail* pMail); + +private: + // not allowed + Mailslot(const Mailslot& rhs); + Mailslot& operator=(const Mailslot& rhs); + + Mutex m_mutex; + MailQueue m_mail; + //Condition m_dataReadyEvent; + Semaphore m_semaphore; +}; + diff --git a/CommonLib/src/Common/Names/EventNames.cpp b/CommonLib/src/Common/Names/EventNames.cpp new file mode 100644 index 0000000..2ecc0d8 --- /dev/null +++ b/CommonLib/src/Common/Names/EventNames.cpp @@ -0,0 +1,42 @@ +#include + +#include "EventNames.hpp" +#include "Exception.hpp" + +EventNames& EventNames::Instance() +{ + static EventNames names; + return names; +} + +//------------------------------------------------------------------------ + +EventNames::~EventNames() +{ +} + +//------------------------------------------------------------------------ + +EventNames::EventNames(): + m_nameMap() +{ + m_nameMap[GLOBAL_QUIT] = "GLOBAL_QUIT"; + m_nameMap[COMMAND_EXECUTTION_IN_PROGRESS] = "COMMAND_EXECUTTION_IN_PROGRESS"; + m_nameMap[COMMAND_EXECUTION_COMPLETE] = "COMMAND_EXECUTION_COMPLETE"; + m_nameMap[START_FILE_TRANSFER] = "START_FILE_TRANSFER"; +} + +//------------------------------------------------------------------------ + +std::string EventNames::operator[](EventNames::Names name) +{ + std::map::const_iterator it = m_nameMap.find(name); + if (it == m_nameMap.end()) + { + std::stringstream ss; + ss << "value " << name << "not found"; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + return it->second; +} diff --git a/CommonLib/src/Common/Names/EventNames.hpp b/CommonLib/src/Common/Names/EventNames.hpp new file mode 100644 index 0000000..db292e5 --- /dev/null +++ b/CommonLib/src/Common/Names/EventNames.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +class EventNames +{ +public: + static EventNames& Instance(); + virtual ~EventNames(); + + enum Names + { + GLOBAL_QUIT, + COMMAND_EXECUTTION_IN_PROGRESS, + COMMAND_EXECUTION_COMPLETE, + START_FILE_TRANSFER, + NUM_EVENTS + }; + + std::string operator[](EventNames::Names name); + +private: + // do not allow + EventNames(const EventNames &rhs); + EventNames &operator=(const EventNames &rhs); + EventNames(); + + std::map m_nameMap; +}; diff --git a/CommonLib/src/Common/Names/MailboxNames.cpp b/CommonLib/src/Common/Names/MailboxNames.cpp new file mode 100644 index 0000000..615f28b --- /dev/null +++ b/CommonLib/src/Common/Names/MailboxNames.cpp @@ -0,0 +1,38 @@ +#include +#include "MailboxNames.hpp" +#include "Exception.hpp" + +MailboxNames& MailboxNames::Instance() +{ + static MailboxNames names; + return names; +} + +//------------------------------------------------------------------------ + +MailboxNames::~MailboxNames() +{ +} + +//------------------------------------------------------------------------ + +MailboxNames::MailboxNames(): + m_nameMap() +{ + m_nameMap[SAMPLE] = "SAMPLE"; +} + +//------------------------------------------------------------------------ + +std::string MailboxNames::operator[](Names name) +{ + std::map::const_iterator it = m_nameMap.find(name); + if (it == m_nameMap.end()) + { + std::stringstream ss; + ss << "value " << name << "not found"; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + return it->second; +} diff --git a/CommonLib/src/Common/Names/MailboxNames.hpp b/CommonLib/src/Common/Names/MailboxNames.hpp new file mode 100644 index 0000000..ed6e6bf --- /dev/null +++ b/CommonLib/src/Common/Names/MailboxNames.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +class MailboxNames +{ +public: + static MailboxNames& Instance(); + virtual ~MailboxNames(); + + enum Names + { + SAMPLE, + NUM_MAILBOXES + }; + + std::string operator[](Names name); + +private: + // do not allow + MailboxNames(const MailboxNames &rhs); + MailboxNames &operator=(const MailboxNames &rhs); + MailboxNames(); + + std::map m_nameMap; +}; diff --git a/CommonLib/src/Common/Names/SemaphoreNames.cpp b/CommonLib/src/Common/Names/SemaphoreNames.cpp new file mode 100644 index 0000000..2e2a350 --- /dev/null +++ b/CommonLib/src/Common/Names/SemaphoreNames.cpp @@ -0,0 +1,38 @@ +#include +#include "SemaphoreNames.hpp" +#include "Exception.hpp" + +SemaphoreNames& SemaphoreNames::Instance() +{ + static SemaphoreNames names; + return names; +} + +//------------------------------------------------------------------------ + +SemaphoreNames::~SemaphoreNames() +{ +} + +//------------------------------------------------------------------------ + +SemaphoreNames::SemaphoreNames(): + m_nameMap() +{ + m_nameMap[SAMPLE_SEM] = "PROCESS_SCIENCE"; +} + +//------------------------------------------------------------------------ + +std::string SemaphoreNames::operator[](Names name) +{ + std::map::const_iterator it = m_nameMap.find(name); + if (it == m_nameMap.end()) + { + std::stringstream ss; + ss << "value " << name << "not found"; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + return it->second; +} diff --git a/CommonLib/src/Common/Names/SemaphoreNames.hpp b/CommonLib/src/Common/Names/SemaphoreNames.hpp new file mode 100644 index 0000000..1f665aa --- /dev/null +++ b/CommonLib/src/Common/Names/SemaphoreNames.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +class SemaphoreNames +{ + +public: + static SemaphoreNames& Instance(); + virtual ~SemaphoreNames(); + + enum Names + { + SAMPLE_SEM, + NUM_SEMS + }; + + std::string operator[](Names name); + +private: + // do not allow + SemaphoreNames(const SemaphoreNames &rhs); + SemaphoreNames &operator=(const SemaphoreNames &rhs); + SemaphoreNames(); + + std::map m_nameMap; +}; diff --git a/CommonLib/src/Common/Names/ThreadNames.cpp b/CommonLib/src/Common/Names/ThreadNames.cpp new file mode 100644 index 0000000..79031da --- /dev/null +++ b/CommonLib/src/Common/Names/ThreadNames.cpp @@ -0,0 +1,42 @@ +#include +#include "ThreadNames.hpp" +#include "Exception.hpp" + +ThreadNames& ThreadNames::Instance() +{ + static ThreadNames names; + + return names; +} + +//------------------------------------------------------------------------ + +ThreadNames::~ThreadNames() +{ +} + +//------------------------------------------------------------------------ + +ThreadNames::ThreadNames(): + m_nameMap() +{ + m_nameMap[VIDEO_READ_THREAD] = "VRS_VIDEO_READ_THREAD"; + m_nameMap[VIDEO_PROCESS_THREAD] = "VRS_VIDEO_PROCESS_THREAD"; + m_nameMap[COMMAND_SOCKET_READ_THREAD] = "VRS_COMMAND_SOCKET_READ_THREAD"; +} + +//------------------------------------------------------------------------ +std::string ThreadNames::operator[](Names name) +{ + std::map::const_iterator it = m_nameMap.find(name); + if (it == m_nameMap.end()) + { + std::stringstream ss; + ss << "value " << name << "not found"; + throw Exception(__PRETTY_FUNCTION__,ss.str()); + } + + std::string nameString = it->second; + + return nameString; +} diff --git a/CommonLib/src/Common/Names/ThreadNames.hpp b/CommonLib/src/Common/Names/ThreadNames.hpp new file mode 100644 index 0000000..f8ade22 --- /dev/null +++ b/CommonLib/src/Common/Names/ThreadNames.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +class ThreadNames +{ + +public: + static ThreadNames& Instance(); + virtual ~ThreadNames(); + + enum Names + { + VIDEO_READ_THREAD, + VIDEO_PROCESS_THREAD, + COMMAND_SOCKET_READ_THREAD + }; + + std::string operator[](Names name); + +private: + // do not allow + ThreadNames(const ThreadNames &rhs); + ThreadNames &operator=(const ThreadNames &rhs); + ThreadNames(); + + std::map m_nameMap; +}; diff --git a/CommonLib/src/Common/Proc/Proc.cpp b/CommonLib/src/Common/Proc/Proc.cpp new file mode 100644 index 0000000..655feb2 --- /dev/null +++ b/CommonLib/src/Common/Proc/Proc.cpp @@ -0,0 +1,113 @@ +#include +#include "Proc.hpp" +#include "IniFile.hpp" +#include "Exception.hpp" +#include "Timestamp.hpp" +#include "UdpSocket.hpp" +#include "Message.hpp" +#include "Condition.hpp" + +#include + +//----------------------------------------------------------------------------- + +Proc::Proc(): + m_eventMap() +{ + // Every project must create a singleton LinuxProc class that inherits Proc() + // All single classes must be instantiated in LinuxProc constructor + + // all singleton classes aka [class]::instance() need to be instantiated here as they create static variables + // they all should also be instantiated in one thread, preferable the main thread. Instantiating them in multiple + // threads will make it hard for us to synchronize their destructions, as static variables are destroyed in the order + // they were created per thread + + // all static variables are destroyed in the reverse order they were created per thread + // so any static variables that are dependent upon need to be instantiated first so they will be destroyed last + // LinuxProc and Proc are the last static variables to be instantiated and the first static variable to be destroyed + // as it needs to coordinate the destruction of all variables created on the heap + try { + initEvents(); + + } catch (Exception& e) { + + throw; + } +} + +//----------------------------------------------------------------------------- + +Proc::~Proc() +{ + // delete events + std::map::iterator eventIt; + for (eventIt = m_eventMap.begin(); eventIt != m_eventMap.end(); ++eventIt) + { + //std::string name = eventIt->second->GetName(); + delete eventIt->second; + eventIt->second = 0; + } +} + +//----------------------------------------------------------------------------- + +void Proc::initEvents() +{ + try + { + for (int i = 0; i < EventNames::NUM_EVENTS; i++) + { + EventNames::Names eventName = static_cast(i); + addEvent(eventName); + } + } + catch (Exception &e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } +} + +//---------------------------------------------------------------------------- + +void Proc::addEvent(const EventNames::Names& event) +{ + try + { + EventNames& eventNames = EventNames::Instance(); + std::string eventName = eventNames[event]; + m_eventMap[eventName] = new Condition(eventName); + } + catch (Exception &e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } +} + +//---------------------------------------------------------------------------- + +Condition& Proc::getEvent(const EventNames::Names& name) const +{ + try + { + std::map::const_iterator i = m_eventMap.find(EventNames::Instance()[name]); + + if (i == m_eventMap.end()) + { + std::stringstream oss; + oss << "couldn't find event: " + << EventNames::Instance()[name]; + throw Exception(__PRETTY_FUNCTION__,oss.str()); + } + else + { + return *(i->second); + } + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw e; + } +} diff --git a/CommonLib/src/Common/Proc/Proc.hpp b/CommonLib/src/Common/Proc/Proc.hpp new file mode 100644 index 0000000..47c83c1 --- /dev/null +++ b/CommonLib/src/Common/Proc/Proc.hpp @@ -0,0 +1,74 @@ +#ifndef PROC_H +#define PROC_H + +#include "EventNames.hpp" + +class Message; +class Condition; + +class Proc +{ + +public: + //>--------------------------------------------------------------------------- + // Function: ~Proc + // + // Purpose: Destroyer + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + virtual ~Proc(); + + //>--------------------------------------------------------------------- + // Function: GetEvent + // + // Purpose: Get a condition (ie: Event) + //---------------------------------------------------------------------- + // Arguments: name - the name of the condition + //---------------------------------------------------------------------- + // Return Value: a referance to the condition + //<--------------------------------------------------------------------- + Condition& getEvent(const EventNames::Names& name) const; + +protected: + //>--------------------------------------------------------------------------- + // Function: Proc + // + // Purpose: Ctor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + Proc(); + + //>--------------------------------------------------------------------- + // Function: AddEvent() + // + // Purpose: Add an event to this process + //---------------------------------------------------------------------- + // Arguments: + // event - the name of the event + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void addEvent(const EventNames::Names& event); + + //>--------------------------------------------------------------------- + // Function: InitEvents() + // + // Purpose: + //---------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------- + // Return Value: none + //<--------------------------------------------------------------------- + void initEvents(); + +private: + std::map m_eventMap; +}; + +#endif diff --git a/CommonLib/src/LinuxProc.cpp b/CommonLib/src/LinuxProc.cpp new file mode 100644 index 0000000..18f3483 --- /dev/null +++ b/CommonLib/src/LinuxProc.cpp @@ -0,0 +1,61 @@ +#include "LinuxProc.hpp" +#include "Exception.hpp" +#include "IniFile.hpp" +#include "Timestamp.hpp" +#include "ErrorLog.hpp" +#include "FileSystemUtil.hpp" + +#include + +//----------------------------------------------------------------------------- + +LinuxProc& LinuxProc::Instance() +{ + static LinuxProc proc; + return proc; +} + +//----------------------------------------------------------------------------- + +LinuxProc::LinuxProc(): + Proc() +{ + // all singleton classes aka [class]::instance() need to be instantiated here as they create static variables + // they all should also be instantiated in one thread, preferable the main thread. Instantiating them in multiple + // threads will make it hard for us to synchronize their destructions, as static variables are destroyed in the order + // they were created per thread + + // all static variables are destroyed in the reverse order they were created per thread + // so any static variables that are dependent upon need to be instantiated first so they will be destroyed last + // LinuxProc is the last static variables to be instantiated and the first static variable to be destroyed + // as it needs to coordinate the destruction of all variables created on the heap + try { + std::string exePath = Util::FileSystem::ExtractDirectory(Util::FileSystem::GetExePathAndFilename().c_str()); + + std::string configFilePath = Util::FileSystem::BuildPath(exePath,"config.ini"); + + m_iniFile = new IniFile(configFilePath); + + std::string logPath = Util::FileSystem::BuildPath(exePath,"Output"); + + Util::FileSystem::CreateDirectory(logPath); + + Timestamp time; + std::stringstream ss; + + ss << time.GetCurrentDateTimeString(Timestamp::DateTimeFormat::YYYYMMDD) << "_" << Timestamp::GetCurrentDateTimeString(Timestamp::DateTimeFormat::HHMMSS, "_") << "_log.txt"; + + ErrorLog::Instance(Util::FileSystem::BuildPath(logPath,ss.str())); + + } catch (Exception& e) { + e.buildStackTrace(__PRETTY_FUNCTION__); + throw; + } +} + +//----------------------------------------------------------------------------- + +LinuxProc::~LinuxProc() +{ + +} diff --git a/CommonLib/src/LinuxProc.hpp b/CommonLib/src/LinuxProc.hpp new file mode 100644 index 0000000..ff38fc4 --- /dev/null +++ b/CommonLib/src/LinuxProc.hpp @@ -0,0 +1,60 @@ +#ifndef LINUXPROC_H +#define LINUXPROC_H + +#include "Proc.hpp" + +class IniFile; + +class LinuxProc : public Proc +{ + +public: + //>--------------------------------------------------------------------------- + // Function: instance + // + // Purpose: singleton + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + static LinuxProc& Instance(); + + //>--------------------------------------------------------------------------- + // Function: getConfig + // + // Purpose: + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + IniFile& getConfig(){return *m_iniFile;}; + + //>--------------------------------------------------------------------------- + // Function: ~Proc + // + // Purpose: Destroyer + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + ~LinuxProc(); + +private: + //>--------------------------------------------------------------------------- + // Function: Proc + // + // Purpose: Ctor + //---------------------------------------------------------------------------- + // Arguments: + //---------------------------------------------------------------------------- + // Return Value: + //---------------------------------------------------------------------------- + LinuxProc(); + + IniFile* m_iniFile; +}; + +#endif diff --git a/CommonLib/src/main.cpp b/CommonLib/src/main.cpp new file mode 100644 index 0000000..5195ee1 --- /dev/null +++ b/CommonLib/src/main.cpp @@ -0,0 +1,35 @@ +//============================================================================ +// Name : HelloWorld.cpp +// Author : +// Version : +// Copyright : Your copyright notice +// Description : Hello World in C++, Ansi-style +//============================================================================ + +#include +#include +#include + +#include "Exception.hpp" +#include "MiscUtil.hpp" +#include "LinuxProc.hpp" + +using namespace std; + +int main() +{ + cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! + + try + { + LinuxProc::Instance(); + } + catch (Exception& e) + { + e.buildStackTrace(__PRETTY_FUNCTION__); + cout << e.getMessage() << endl; + } + + + return 0; +} diff --git a/git_scripts/ignore_a_tracked_file.sh b/git_scripts/ignore_a_tracked_file.sh new file mode 100644 index 0000000..06dc9d6 --- /dev/null +++ b/git_scripts/ignore_a_tracked_file.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +length=${#1}; + +if [[ $length -eq 0 ]] +then + echo "Please specify a tracked file to ignore"; + exit 1 +fi + +git update-index --skip-worktree $1 diff --git a/git_scripts/list_tracked_files_under_main_branch.sh b/git_scripts/list_tracked_files_under_main_branch.sh new file mode 100644 index 0000000..bceca92 --- /dev/null +++ b/git_scripts/list_tracked_files_under_main_branch.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +git ls-tree -r main --name-only diff --git a/git_scripts/unignore_a_tracked_file.sh b/git_scripts/unignore_a_tracked_file.sh new file mode 100644 index 0000000..4415a6c --- /dev/null +++ b/git_scripts/unignore_a_tracked_file.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +length=${#1}; + +if [[ $length -eq 0 ]] +then + echo "Please specify a tracked file to ignore"; + exit 1 +fi + +git update-index --no-skip-worktree $1