clang-format
This commit is contained in:
198
.clang-format
Normal file
198
.clang-format
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
# # https://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||||
|
# # https://clang-format-configurator.site
|
||||||
|
|
||||||
|
IndentWidth: 4
|
||||||
|
TabWidth: 4
|
||||||
|
UseTab: Never
|
||||||
|
ColumnLimit: 80
|
||||||
|
|
||||||
|
AlignAfterOpenBracket: AlwaysBreak # Align, DontAlign, AlwaysBreak, BlockIndent
|
||||||
|
AlignArrayOfStructures: Right # Left, Right
|
||||||
|
AlignConsecutiveAssignments:
|
||||||
|
Enabled: true
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: true
|
||||||
|
AlignCompound: true
|
||||||
|
PadOperators: true
|
||||||
|
AlignConsecutiveBitFields:
|
||||||
|
Enabled: true
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: true
|
||||||
|
AlignCompound: true
|
||||||
|
PadOperators: true
|
||||||
|
AlignConsecutiveDeclarations: None
|
||||||
|
AlignConsecutiveMacros:
|
||||||
|
Enabled: true
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: true
|
||||||
|
AlignCompound: true
|
||||||
|
PadOperators: true
|
||||||
|
AlignEscapedNewlines: Right # DontAlign, Left, Right
|
||||||
|
|
||||||
|
AllowShortCaseLabelsOnASingleLine: true
|
||||||
|
AlignConsecutiveShortCaseStatements: # AllowShortCaseLabelsOnASingleLine: true
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
BreakBeforeBinaryOperators: true
|
||||||
|
AlignOperands: AlignAfterOperator # Align, AlignAfterOperator
|
||||||
|
|
||||||
|
AlignTrailingComments:
|
||||||
|
Kind: Always # Leave, Always, Never
|
||||||
|
OverEmptyLines: 1
|
||||||
|
|
||||||
|
AllowShortBlocksOnASingleLine: Never # Never, Empty, Always
|
||||||
|
AllowShortEnumsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: None # None, InlineOnly, Empty, Inline, All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never # Never, WithoutElse, OnlyFirstIf, AllIfsAndElse
|
||||||
|
AllowShortLambdasOnASingleLine: None # None, Empty, Inline, All
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterReturnType: All # None, All, TopLevel, AllDefinitions, TopLevelDefinitions
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes # No, MultiLine, Yes
|
||||||
|
|
||||||
|
# AttributeMacros # TODO
|
||||||
|
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
|
||||||
|
BitFieldColonSpacing: Both # Both, None, Before, After
|
||||||
|
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: MultiLine # Never, MultiLine, Always
|
||||||
|
AfterEnum: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterStruct: true
|
||||||
|
AfterUnion: true
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: true
|
||||||
|
BeforeElse: true
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
|
||||||
|
# BracedInitializerIndentWidth: 4
|
||||||
|
BreakAfterAttributes: Always # Always, Leave, Never
|
||||||
|
# BreakBeforeBinaryOperators # TODO
|
||||||
|
# BreakBeforeConceptDeclarations # TODO
|
||||||
|
# BreakBeforeInlineASMColon # TODO
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
|
||||||
|
ConstructorInitializerIndentWidth: 2
|
||||||
|
BreakConstructorInitializers: BeforeComma # BeforeColon, BeforeComma, AfterColon
|
||||||
|
BreakInheritanceList: BeforeComma # BeforeColon, BeforeComma, AfterColon, AfterComma
|
||||||
|
|
||||||
|
BreakStringLiterals: true
|
||||||
|
# ColumnLimit # TODO
|
||||||
|
# CommentPragmas # TODO
|
||||||
|
CompactNamespaces: false
|
||||||
|
# ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: false
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
# DisableFormat: false
|
||||||
|
EmptyLineAfterAccessModifier: Never # Never, Leave, Always
|
||||||
|
EmptyLineBeforeAccessModifier: Always # Never, Leave, LogicalBlock, Always
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
# ForEachMacros:
|
||||||
|
# IfMacros:
|
||||||
|
IncludeBlocks: Preserve # Preserve, Merge, Regroup
|
||||||
|
# IncludeCategories: # TODO
|
||||||
|
# IncludeIsMainRegex
|
||||||
|
# IncludeIsMainSourceRegex
|
||||||
|
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
IndentAccessModifiers: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentExternBlock: NoIndent # AfterExternBlock, NoIndent, Indent
|
||||||
|
IndentGotoLabels: false
|
||||||
|
IndentPPDirectives: None # None, AfterHash, BeforeHash
|
||||||
|
IndentRequiresClause: true # C++
|
||||||
|
# IndentWrappedFunctionNames: false
|
||||||
|
InsertBraces: true
|
||||||
|
InsertNewlineAtEOF: true
|
||||||
|
# InsertTrailingCommas: #TODO
|
||||||
|
|
||||||
|
# works only for C++14 and C23
|
||||||
|
# IntegerLiteralSeparator:
|
||||||
|
# Binary: 4
|
||||||
|
# Decimal: 3
|
||||||
|
# Hex: 2
|
||||||
|
IntegerLiteralSeparator:
|
||||||
|
Binary: -1
|
||||||
|
Decimal: -1
|
||||||
|
Hex: -1
|
||||||
|
|
||||||
|
KeepEmptyLinesAtEOF: false
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
LambdaBodyIndentation: Signature # Signature, OuterScope
|
||||||
|
# LineEnding:
|
||||||
|
# MacroBlockBegin:
|
||||||
|
# MacroBlockEnd:
|
||||||
|
# Macros:
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None # None, Inner, All
|
||||||
|
# NamespaceMacros:
|
||||||
|
PPIndentWidth: -1
|
||||||
|
PackConstructorInitializers: Never # Never, BinPack, CurrentLine, NextLine, NextLineOnly
|
||||||
|
# PenaltyBreakAssignment:
|
||||||
|
# PenaltyBreakBeforeFirstCallParameter:
|
||||||
|
# PenaltyBreakComment
|
||||||
|
# PenaltyBreakFirstLessLess
|
||||||
|
# PenaltyBreakOpenParenthesis
|
||||||
|
# PenaltyBreakString
|
||||||
|
# PenaltyBreakTemplateDeclaration
|
||||||
|
# PenaltyExcessCharacter
|
||||||
|
# PenaltyIndentedWhitespace
|
||||||
|
# PenaltyReturnTypeOnItsOwnLine
|
||||||
|
PointerAlignment: Left
|
||||||
|
QualifierAlignment: Left
|
||||||
|
# QualifierOrder: TODO
|
||||||
|
# RawStringFormats:
|
||||||
|
ReferenceAlignment: Left
|
||||||
|
ReflowComments: true
|
||||||
|
RemoveBracesLLVM: false
|
||||||
|
RemoveParentheses: ReturnStatement
|
||||||
|
RemoveSemicolon: true
|
||||||
|
# RequiresClausePositionStyle: # TODO, C++
|
||||||
|
# RequiresExpressionIndentation: # TODO, C++
|
||||||
|
SeparateDefinitionBlocks: Always
|
||||||
|
# ShortNamespaceLines: 1
|
||||||
|
SortIncludes: CaseSensitive
|
||||||
|
SortUsingDeclarations: LexicographicNumeric
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpacesBeforeTrailingComments: 2
|
||||||
|
SpacesInAngles: Never
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpacesInLineCommentPrefix:
|
||||||
|
Minimum: 1
|
||||||
|
Maximum: -1
|
||||||
|
SpacesInParens: Never
|
||||||
|
# SpacesInParensOptions:
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
# StatementAttributeLikeMacros:
|
||||||
|
# StatementMacros:
|
||||||
|
# TypeNames:
|
||||||
|
# TypenameMacros:
|
||||||
|
# WhitespaceSensitiveMacros:
|
||||||
89
src/ipc.cpp
89
src/ipc.cpp
@@ -7,18 +7,19 @@
|
|||||||
|
|
||||||
#include "ipc.hpp"
|
#include "ipc.hpp"
|
||||||
|
|
||||||
namespace ipc
|
namespace ipc {
|
||||||
{
|
|
||||||
|
|
||||||
#define set_message(verbose, s, ...) { \
|
#define set_message(verbose, s, ...) \
|
||||||
m_message = fmt::format(s __VA_OPT__(,) __VA_ARGS__); \
|
{ \
|
||||||
if (verbose < 0) { \
|
m_message = fmt::format(s __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
throw std::runtime_error(m_message); \
|
if (verbose < 0) { \
|
||||||
} else if (verbose <= m_verbose) { \
|
throw std::runtime_error(m_message); \
|
||||||
fmt::print(m_message); \
|
} \
|
||||||
fmt::print("\n"); \
|
else if (verbose <= m_verbose) { \
|
||||||
} \
|
fmt::print(m_message); \
|
||||||
}
|
fmt::print("\n"); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
default_name();
|
default_name();
|
||||||
@@ -36,9 +37,13 @@ start_external(const std::string& executable, bool is_server)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
start_external(const std::string& executable, const std::string& ipc_name, bool is_server)
|
start_external(
|
||||||
|
const std::string& executable,
|
||||||
|
const std::string& ipc_name,
|
||||||
|
bool is_server)
|
||||||
{
|
{
|
||||||
auto command = fmt::format("{} {} {}", executable, ipc_name, is_server ? "1" : "0");
|
auto command
|
||||||
|
= fmt::format("{} {} {}", executable, ipc_name, is_server ? "1" : "0");
|
||||||
fmt::print("execute: {}\n", command);
|
fmt::print("execute: {}\n", command);
|
||||||
|
|
||||||
auto thread_func = [command] {
|
auto thread_func = [command] {
|
||||||
@@ -49,7 +54,7 @@ start_external(const std::string& executable, const std::string& ipc_name, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ipc::Ipc(bool is_server, int verbose)
|
Ipc::Ipc(bool is_server, int verbose)
|
||||||
: Ipc(default_name(), is_server, verbose)
|
: Ipc(default_name(), is_server, verbose)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,17 +72,29 @@ Ipc::write(const void* buffer, size_t count, size_t size)
|
|||||||
ssize_t bytes_sent = 0;
|
ssize_t bytes_sent = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
bytes_current = _write(&bytes_buffer[bytes_sent], bytes_required - bytes_sent);
|
bytes_current
|
||||||
|
= _write(&bytes_buffer[bytes_sent], bytes_required - bytes_sent);
|
||||||
bytes_sent += bytes_current;
|
bytes_sent += bytes_current;
|
||||||
// set_message(2, "write {} -> {}/{}\n", bytes_current, bytes_sent, bytes_required);
|
// set_message(2, "write {} -> {}/{}\n", bytes_current, bytes_sent,
|
||||||
|
// bytes_required);
|
||||||
} while ((bytes_current > 0) && (bytes_sent != bytes_required));
|
} while ((bytes_current > 0) && (bytes_sent != bytes_required));
|
||||||
|
|
||||||
if (bytes_sent != bytes_required) {
|
if (bytes_sent != bytes_required) {
|
||||||
set_message(-1, "c : (-) write ({} * {}) = {} bytes error: only {} bytes are sent",
|
set_message(
|
||||||
count, size, bytes_required, bytes_sent);
|
-1,
|
||||||
|
"c : (-) write ({} * {}) = {} bytes error: only {} bytes are sent",
|
||||||
|
count,
|
||||||
|
size,
|
||||||
|
bytes_required,
|
||||||
|
bytes_sent);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_message(1, "c : (+) write ({} * {}) = {} bytes", count, size, bytes_required);
|
set_message(
|
||||||
|
1,
|
||||||
|
"c : (+) write ({} * {}) = {} bytes",
|
||||||
|
count,
|
||||||
|
size,
|
||||||
|
bytes_required);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -89,22 +106,40 @@ Ipc::read(void* buffer, size_t count, size_t size)
|
|||||||
|
|
||||||
const ssize_t bytes_required = size * count;
|
const ssize_t bytes_required = size * count;
|
||||||
|
|
||||||
char* bytes_buffer = (char*)buffer;
|
char* bytes_buffer = (char*)buffer;
|
||||||
ssize_t bytes_current = 0;
|
ssize_t bytes_current = 0;
|
||||||
ssize_t bytes_received = 0;
|
ssize_t bytes_received = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
bytes_current = _read(&bytes_buffer[bytes_received], bytes_required - bytes_received);
|
bytes_current = _read(
|
||||||
|
&bytes_buffer[bytes_received],
|
||||||
|
bytes_required - bytes_received);
|
||||||
bytes_received += bytes_current;
|
bytes_received += bytes_current;
|
||||||
set_message(2, "read {} -> {}/{}\n", bytes_current, bytes_received, bytes_required);
|
set_message(
|
||||||
|
2,
|
||||||
|
"read {} -> {}/{}\n",
|
||||||
|
bytes_current,
|
||||||
|
bytes_received,
|
||||||
|
bytes_required);
|
||||||
} while ((bytes_current > 0) && (bytes_received != bytes_required));
|
} while ((bytes_current > 0) && (bytes_received != bytes_required));
|
||||||
|
|
||||||
if (bytes_received != bytes_required) {
|
if (bytes_received != bytes_required) {
|
||||||
set_message(-1, "c : (-) read ({} * {}) = {} bytes error: only {} bytes are recieved",
|
set_message(
|
||||||
count, size, bytes_required, bytes_received);
|
-1,
|
||||||
|
"c : (-) read ({} * {}) = {} bytes error: only {} bytes are "
|
||||||
|
"recieved",
|
||||||
|
count,
|
||||||
|
size,
|
||||||
|
bytes_required,
|
||||||
|
bytes_received);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_message(1, "c : (+) read ({} * {}) = {} bytes", size, count, bytes_required);
|
set_message(
|
||||||
|
1,
|
||||||
|
"c : (+) read ({} * {}) = {} bytes",
|
||||||
|
size,
|
||||||
|
count,
|
||||||
|
bytes_required);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -123,4 +158,4 @@ Ipc::read(char* str)
|
|||||||
read(str, 1, len);
|
read(str, 1, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace ipc
|
||||||
|
|||||||
26
src/ipc.hpp
26
src/ipc.hpp
@@ -6,11 +6,10 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ipc
|
namespace ipc {
|
||||||
{
|
|
||||||
|
|
||||||
void
|
void
|
||||||
init();
|
init();
|
||||||
@@ -22,11 +21,14 @@ void
|
|||||||
start_external(const std::string& executable, bool is_server);
|
start_external(const std::string& executable, bool is_server);
|
||||||
|
|
||||||
void
|
void
|
||||||
start_external(const std::string& executable, const std::string& ipc_name, bool is_server);
|
start_external(
|
||||||
|
const std::string& executable,
|
||||||
|
const std::string& ipc_name,
|
||||||
|
bool is_server);
|
||||||
|
|
||||||
class Ipc
|
class Ipc
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Ipc(bool is_server, int verbose = 0);
|
Ipc(bool is_server, int verbose = 0);
|
||||||
|
|
||||||
Ipc(const std::string& name, bool is_server, int verbose = 0);
|
Ipc(const std::string& name, bool is_server, int verbose = 0);
|
||||||
@@ -36,14 +38,14 @@ public:
|
|||||||
void
|
void
|
||||||
write(const char* str);
|
write(const char* str);
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void
|
void
|
||||||
write(const T& data)
|
write(const T& data)
|
||||||
{
|
{
|
||||||
write(&data, 1, sizeof(T));
|
write(&data, 1, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void
|
void
|
||||||
write(const T* data, size_t count)
|
write(const T* data, size_t count)
|
||||||
{
|
{
|
||||||
@@ -56,14 +58,14 @@ public:
|
|||||||
void
|
void
|
||||||
read(char* str);
|
read(char* str);
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void
|
void
|
||||||
read(T& data)
|
read(T& data)
|
||||||
{
|
{
|
||||||
read(&data, 1, sizeof(T));
|
read(&data, 1, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void
|
void
|
||||||
read(T* data, size_t count)
|
read(T* data, size_t count)
|
||||||
{
|
{
|
||||||
@@ -73,14 +75,14 @@ public:
|
|||||||
void
|
void
|
||||||
read(void* buffer, size_t count, size_t size);
|
read(void* buffer, size_t count, size_t size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ssize_t
|
ssize_t
|
||||||
_write(const void* buffer, size_t bytes);
|
_write(const void* buffer, size_t bytes);
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
_read(void* buffer, size_t bytes);
|
_read(void* buffer, size_t bytes);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int m_verbose;
|
int m_verbose;
|
||||||
std::string m_message;
|
std::string m_message;
|
||||||
|
|
||||||
@@ -92,4 +94,4 @@ protected:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace ipc
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ ipc_read_string(void* ipc, char* str)
|
|||||||
i->read(str);
|
i->read(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void
|
void
|
||||||
ipc_write(void* ipc, const T* data, size_t count)
|
ipc_write(void* ipc, const T* data, size_t count)
|
||||||
{
|
{
|
||||||
@@ -97,7 +97,7 @@ ipc_write(void* ipc, const T* data, size_t count)
|
|||||||
i->write(data, count);
|
i->write(data, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void
|
void
|
||||||
ipc_read(void* ipc, T* data, size_t count)
|
ipc_read(void* ipc, T* data, size_t count)
|
||||||
{
|
{
|
||||||
@@ -107,8 +107,16 @@ ipc_read(void* ipc, T* data, size_t count)
|
|||||||
i->read(data, count);
|
i->read(data, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _IPC_WRITE_FN(data_type) _IPC_WRITE_FN_NAME(data_type) { return ipc_write(ipc, data, count); }
|
#define _IPC_WRITE_FN(data_type) \
|
||||||
#define _IPC_READ_FN(data_type) _IPC_READ_FN_NAME (data_type) { return ipc_read (ipc, data, count); }
|
_IPC_WRITE_FN_NAME(data_type) \
|
||||||
|
{ \
|
||||||
|
return ipc_write(ipc, data, count); \
|
||||||
|
}
|
||||||
|
#define _IPC_READ_FN(data_type) \
|
||||||
|
_IPC_READ_FN_NAME(data_type) \
|
||||||
|
{ \
|
||||||
|
return ipc_read(ipc, data, count); \
|
||||||
|
}
|
||||||
|
|
||||||
_IPC_WRITE_FN(char);
|
_IPC_WRITE_FN(char);
|
||||||
_IPC_WRITE_FN(int);
|
_IPC_WRITE_FN(int);
|
||||||
|
|||||||
@@ -40,8 +40,10 @@ ipc_write_string(void* ipc, const char* str);
|
|||||||
void
|
void
|
||||||
ipc_read_string(void* ipc, char* str);
|
ipc_read_string(void* ipc, char* str);
|
||||||
|
|
||||||
#define _IPC_WRITE_FN_NAME(type) void ipc_write_ ## type (void* ipc, const type * data, size_t count)
|
#define _IPC_WRITE_FN_NAME(type) \
|
||||||
#define _IPC_READ_FN_NAME(type) void ipc_read_ ## type (void* ipc, type * data, size_t count)
|
void ipc_write_##type(void* ipc, const type* data, size_t count)
|
||||||
|
#define _IPC_READ_FN_NAME(type) \
|
||||||
|
void ipc_read_##type(void* ipc, type* data, size_t count)
|
||||||
|
|
||||||
_IPC_WRITE_FN_NAME(char);
|
_IPC_WRITE_FN_NAME(char);
|
||||||
_IPC_WRITE_FN_NAME(int);
|
_IPC_WRITE_FN_NAME(int);
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
|
|
||||||
#include "ipc.hpp"
|
#include "ipc.hpp"
|
||||||
|
|
||||||
namespace ipc
|
namespace ipc {
|
||||||
{
|
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
default_name()
|
default_name()
|
||||||
@@ -20,8 +19,7 @@ default_name()
|
|||||||
void
|
void
|
||||||
make_fifo(const std::string& name, unsigned int mode)
|
make_fifo(const std::string& name, unsigned int mode)
|
||||||
{
|
{
|
||||||
if (mkfifo(name.c_str(), mode) < 0)
|
if (mkfifo(name.c_str(), mode) < 0) {
|
||||||
{
|
|
||||||
auto message = fmt::format("mkfifo '{}' : {}", name, strerror(errno));
|
auto message = fmt::format("mkfifo '{}' : {}", name, strerror(errno));
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -35,7 +33,7 @@ init(const std::string& name, unsigned int mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ipc::Ipc(const std::string& name, bool is_server, int verbose)
|
Ipc::Ipc(const std::string& name, bool is_server, int verbose)
|
||||||
: m_verbose(verbose)
|
: m_verbose(verbose)
|
||||||
{
|
{
|
||||||
auto fifo_open = [](std::string name, int flags) -> int {
|
auto fifo_open = [](std::string name, int flags) -> int {
|
||||||
int fd = open(name.c_str(), flags);
|
int fd = open(name.c_str(), flags);
|
||||||
@@ -50,7 +48,8 @@ Ipc::Ipc(const std::string& name, bool is_server, int verbose)
|
|||||||
if (is_server) {
|
if (is_server) {
|
||||||
m_reader_fd = fifo_open(name + "_c", O_RDONLY);
|
m_reader_fd = fifo_open(name + "_c", O_RDONLY);
|
||||||
m_writer_fd = fifo_open(name + "_s", O_WRONLY);
|
m_writer_fd = fifo_open(name + "_s", O_WRONLY);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
m_writer_fd = fifo_open(name + "_c", O_WRONLY);
|
m_writer_fd = fifo_open(name + "_c", O_WRONLY);
|
||||||
m_reader_fd = fifo_open(name + "_s", O_RDONLY);
|
m_reader_fd = fifo_open(name + "_s", O_RDONLY);
|
||||||
}
|
}
|
||||||
@@ -72,4 +71,4 @@ Ipc::_read(void* buffer, size_t bytes)
|
|||||||
return ::read(m_reader_fd, buffer, bytes);
|
return ::read(m_reader_fd, buffer, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace ipc
|
||||||
|
|||||||
@@ -11,8 +11,7 @@
|
|||||||
|
|
||||||
#define UNUSED(x) (void)(x)
|
#define UNUSED(x) (void)(x)
|
||||||
|
|
||||||
namespace ipc
|
namespace ipc {
|
||||||
{
|
|
||||||
|
|
||||||
// https://stackoverflow.com/a/17387176
|
// https://stackoverflow.com/a/17387176
|
||||||
// Returns the last Win32 error, in string format.
|
// Returns the last Win32 error, in string format.
|
||||||
@@ -22,29 +21,29 @@ getLastErrorAsString()
|
|||||||
{
|
{
|
||||||
// Get the error message ID, if any.
|
// Get the error message ID, if any.
|
||||||
DWORD errorMessageID = ::GetLastError();
|
DWORD errorMessageID = ::GetLastError();
|
||||||
if(errorMessageID == 0) {
|
if (errorMessageID == 0) {
|
||||||
return std::string(); //No error message has been recorded
|
return std::string(); // No error message has been recorded
|
||||||
}
|
}
|
||||||
|
|
||||||
LPSTR messageBuffer = nullptr;
|
LPSTR messageBuffer = nullptr;
|
||||||
|
|
||||||
// Ask Win32 to give us the string version of that message ID.
|
// Ask Win32 to give us the string version of that message ID.
|
||||||
// The parameters we pass in, tell Win32 to create the buffer that holds the
|
// The parameters we pass in, tell Win32 to create the buffer that holds the
|
||||||
// message for us (because we don't yet know how long the message string will be).
|
// message for us (because we don't yet know how long the message string
|
||||||
|
// will be).
|
||||||
//
|
//
|
||||||
// https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessagea
|
// https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessagea
|
||||||
//
|
//
|
||||||
size_t size = FormatMessageA(
|
size_t size = FormatMessageA(
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
| FORMAT_MESSAGE_IGNORE_INSERTS, // dwFlags
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS, // dwFlags
|
|
||||||
|
|
||||||
NULL, // lpSource
|
NULL, // lpSource
|
||||||
errorMessageID, // dwMessageId
|
errorMessageID, // dwMessageId
|
||||||
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), // dwLanguageId
|
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), // dwLanguageId
|
||||||
(LPSTR)&messageBuffer, // lpBuffer
|
(LPSTR)&messageBuffer, // lpBuffer
|
||||||
0, // nSize
|
0, // nSize
|
||||||
NULL // *Arguments
|
NULL // *Arguments
|
||||||
);
|
);
|
||||||
|
|
||||||
// Copy the error message into a std::string.
|
// Copy the error message into a std::string.
|
||||||
@@ -75,7 +74,7 @@ init(const std::string& name, unsigned int mode)
|
|||||||
// https://habr.com/ru/post/166155/
|
// https://habr.com/ru/post/166155/
|
||||||
|
|
||||||
Ipc::Ipc(const std::string& name, bool is_server, int verbose)
|
Ipc::Ipc(const std::string& name, bool is_server, int verbose)
|
||||||
: m_verbose(verbose)
|
: m_verbose(verbose)
|
||||||
{
|
{
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
@@ -83,21 +82,22 @@ Ipc::Ipc(const std::string& name, bool is_server, int verbose)
|
|||||||
// fmt::print("full name = {}\n", full_name);
|
// fmt::print("full name = {}\n", full_name);
|
||||||
|
|
||||||
auto throw_failed = [](const std::string& name) {
|
auto throw_failed = [](const std::string& name) {
|
||||||
auto message = fmt::format("{}() failed: {}", name, getLastErrorAsString());
|
auto message
|
||||||
|
= fmt::format("{}() failed: {}", name, getLastErrorAsString());
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (is_server) {
|
if (is_server) {
|
||||||
// https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea
|
// https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea
|
||||||
m_pipe = CreateNamedPipe(
|
m_pipe = CreateNamedPipe(
|
||||||
(LPSTR)full_name.c_str(), // lpName
|
(LPSTR)full_name.c_str(), // lpName
|
||||||
PIPE_ACCESS_DUPLEX, // dwOpenMode
|
PIPE_ACCESS_DUPLEX, // dwOpenMode
|
||||||
PIPE_TYPE_BYTE, // dwPipeMode
|
PIPE_TYPE_BYTE, // dwPipeMode
|
||||||
1, // nMaxInstances
|
1, // nMaxInstances
|
||||||
0, // nOutBufferSize
|
0, // nOutBufferSize
|
||||||
0, // nInBufferSize
|
0, // nInBufferSize
|
||||||
0, // nDefaultTimeOut
|
0, // nDefaultTimeOut
|
||||||
NULL // lpSecurityAttributes
|
NULL // lpSecurityAttributes
|
||||||
);
|
);
|
||||||
|
|
||||||
if (m_pipe == INVALID_HANDLE_VALUE) {
|
if (m_pipe == INVALID_HANDLE_VALUE) {
|
||||||
@@ -112,18 +112,18 @@ Ipc::Ipc(const std::string& name, bool is_server, int verbose)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto time_step = 500ms;
|
auto time_step = 500ms;
|
||||||
auto time_current = 0ms;
|
auto time_current = 0ms;
|
||||||
while (time_current < 10s) {
|
while (time_current < 10s) {
|
||||||
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
|
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
|
||||||
m_pipe = CreateFile(
|
m_pipe = CreateFile(
|
||||||
(LPSTR)full_name.c_str(), // lpFileName
|
(LPSTR)full_name.c_str(), // lpFileName
|
||||||
GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
|
GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
|
||||||
0, // dwShareMode
|
0, // dwShareMode
|
||||||
NULL, // lpSecurityAttributes
|
NULL, // lpSecurityAttributes
|
||||||
OPEN_EXISTING, // dwCreationDisposition
|
OPEN_EXISTING, // dwCreationDisposition
|
||||||
FILE_ATTRIBUTE_NORMAL, // dwFlagsAndAttributes
|
FILE_ATTRIBUTE_NORMAL, // dwFlagsAndAttributes
|
||||||
NULL // hTemplateFile
|
NULL // hTemplateFile
|
||||||
);
|
);
|
||||||
|
|
||||||
if (m_pipe != INVALID_HANDLE_VALUE) {
|
if (m_pipe != INVALID_HANDLE_VALUE) {
|
||||||
@@ -150,12 +150,12 @@ Ipc::_write(const void* buffer, size_t bytes)
|
|||||||
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile
|
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile
|
||||||
|
|
||||||
DWORD numBytesWritten = 0;
|
DWORD numBytesWritten = 0;
|
||||||
auto result = WriteFile(
|
auto result = WriteFile(
|
||||||
m_pipe, // hFile
|
m_pipe, // hFile
|
||||||
buffer, // lpBuffer
|
buffer, // lpBuffer
|
||||||
bytes, // nNumberOfBytesToWrite
|
bytes, // nNumberOfBytesToWrite
|
||||||
&numBytesWritten, // lpNumberOfBytesWritten
|
&numBytesWritten, // lpNumberOfBytesWritten
|
||||||
NULL // lpOverlapped
|
NULL // lpOverlapped
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@@ -171,12 +171,12 @@ Ipc::_read(void* buffer, size_t bytes)
|
|||||||
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfile
|
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfile
|
||||||
|
|
||||||
DWORD numBytesRead = 0;
|
DWORD numBytesRead = 0;
|
||||||
auto result = ReadFile(
|
auto result = ReadFile(
|
||||||
m_pipe, // hFile
|
m_pipe, // hFile
|
||||||
buffer, // lpBuffer
|
buffer, // lpBuffer
|
||||||
bytes, // nNumberOfBytesToRead
|
bytes, // nNumberOfBytesToRead
|
||||||
&numBytesRead, // lpNumberOfBytesRead
|
&numBytesRead, // lpNumberOfBytesRead
|
||||||
NULL // lpOverlapped
|
NULL // lpOverlapped
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@@ -186,4 +186,4 @@ Ipc::_read(void* buffer, size_t bytes)
|
|||||||
return numBytesRead;
|
return numBytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace ipc
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
int
|
int
|
||||||
main(int /* argc */, char** /* argv */)
|
main(int /* argc */, char** /* argv */)
|
||||||
{
|
{
|
||||||
using ipc::Ipc;
|
|
||||||
using fmt::format;
|
using fmt::format;
|
||||||
using fmt::print;
|
using fmt::print;
|
||||||
|
using ipc::Ipc;
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
@@ -34,7 +34,7 @@ main(int /* argc */, char** /* argv */)
|
|||||||
|
|
||||||
int value;
|
int value;
|
||||||
double result;
|
double result;
|
||||||
while(1) {
|
while (1) {
|
||||||
{
|
{
|
||||||
server.read(value);
|
server.read(value);
|
||||||
print("[server] read int({})\n", value);
|
print("[server] read int({})\n", value);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ main(int /* argc */, char** /* argv */)
|
|||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
ipc_init_default(); // default name
|
ipc_init_default(); // default name
|
||||||
|
|
||||||
std::thread server_thread([verbose] {
|
std::thread server_thread([verbose] {
|
||||||
printf("[c-server] pre-start\n");
|
printf("[c-server] pre-start\n");
|
||||||
@@ -24,7 +24,7 @@ main(int /* argc */, char** /* argv */)
|
|||||||
|
|
||||||
int value;
|
int value;
|
||||||
double result;
|
double result;
|
||||||
while(1) {
|
while (1) {
|
||||||
{
|
{
|
||||||
ipc_read_int(server, &value, 1);
|
ipc_read_int(server, &value, 1);
|
||||||
printf("[c-server] read int(%d)\n", value);
|
printf("[c-server] read int(%d)\n", value);
|
||||||
|
|||||||
@@ -9,13 +9,13 @@
|
|||||||
int
|
int
|
||||||
main(int /* argc */, char** /* argv */)
|
main(int /* argc */, char** /* argv */)
|
||||||
{
|
{
|
||||||
using ipc::Ipc;
|
|
||||||
using fmt::format;
|
using fmt::format;
|
||||||
using fmt::print;
|
using fmt::print;
|
||||||
|
using ipc::Ipc;
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
ipc::init(); // default name
|
ipc::init(); // default name
|
||||||
|
|
||||||
ipc::start_external("python test_server.py", true);
|
ipc::start_external("python test_server.py", true);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user