├── .gitignore ├── AUTHORS ├── CMakeLists.txt ├── LICENSE ├── README ├── README.md ├── TODO ├── doc ├── colorsyntax ├── highlight-dark.css ├── highlight-light.css ├── index.txt ├── nanomsgxx.7.ronn ├── nanomsgxx │ ├── design.7.ronn │ ├── index.txt │ ├── messages.7.ronn │ ├── polling.7.ronn │ └── sockets.7.ronn ├── nnxx.3.ronn ├── nnxx.css ├── nnxx │ ├── index.txt │ ├── message.3.ronn │ └── this_thread.3.ronn └── wscript ├── libnnxx.pc.in ├── src ├── CMakeLists.txt ├── LICENSE ├── README ├── nanomsg │ └── ext │ │ ├── nnxx_ext.c │ │ ├── nnxx_ext.h │ │ └── wscript └── nnxx │ ├── README │ ├── bus.h │ ├── chrono.h │ ├── error.cpp │ ├── error.h │ ├── inproc.h │ ├── ipc.h │ ├── message │ ├── message.cpp │ ├── message.h │ ├── message_control.cpp │ ├── message_control.h │ ├── message_istream.cpp │ ├── message_istream.h │ ├── message_istream.hpp │ ├── message_iterator.cpp │ ├── message_iterator.h │ ├── message_ostream.cpp │ ├── message_ostream.h │ ├── message_ostream.hpp │ ├── message_streambuf.cpp │ ├── message_streambuf.h │ ├── message_streambuf.hpp │ ├── nn.cpp │ ├── nn.h │ ├── pair.h │ ├── pipeline.h │ ├── poll.cpp │ ├── poll.h │ ├── pubsub.cpp │ ├── pubsub.h │ ├── reqrep.cpp │ ├── reqrep.h │ ├── socket │ ├── socket.cpp │ ├── socket.h │ ├── socket.hpp │ ├── survey.cpp │ ├── survey.h │ ├── tcp.cpp │ ├── tcp.h │ ├── testing │ ├── timeout.cpp │ ├── timeout.h │ ├── unittest.h │ └── wscript ├── tests ├── CMakeLists.txt ├── README ├── test_message.cpp ├── test_message_istream.cpp ├── test_message_ostream.cpp ├── test_nnxx_ext.cpp ├── test_pair.cpp ├── test_pipeline.cpp ├── test_poll.cpp ├── test_pubsub.cpp ├── test_readme.cpp ├── test_reqrep.cpp ├── test_reqrep_multi.cpp ├── test_socket.cpp ├── test_survey.cpp ├── test_timeout.cpp └── wscript ├── waf └── wscript /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Compiled Dynamic libraries 8 | *.so 9 | *.dylib 10 | *.dll 11 | 12 | # Compiled Static libraries 13 | *.lai 14 | *.la 15 | *.a 16 | *.lib 17 | 18 | # Executables 19 | *.exe 20 | *.out 21 | *.app 22 | 23 | # Waf 24 | .waf* 25 | .lock* 26 | build/* 27 | 28 | # Emacs 29 | *~ 30 | \#*\# 31 | 32 | # Doc 33 | doc/*.gz 34 | doc/*.html 35 | doc/*.[1-9] 36 | doc/nnxx/*.gz 37 | doc/nnxx/*.html 38 | doc/nnxx/*.[1-9] 39 | doc/nanomsgxx/*.gz 40 | doc/nanomsgxx/*.html 41 | doc/nanomsgxx/*.[1-9] 42 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Complete list of copyright holders to nanomsgxx codebase: 2 | 3 | Achille Roussel 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin) 4 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}) 5 | set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}) 6 | 7 | set(VERSION_MAJOR 0) 8 | set(VERSION_MINOR 1) 9 | set(VERSION_PATCH 0) 10 | set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") 11 | 12 | project(nanomsgxx VERSION ${VERSION}) 13 | 14 | # project wide C++ options and include direcories: 15 | set (CMAKE_CXX_STANDARD 11) 16 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 17 | set(CMAKE_CXX_EXTENSIONS OFF) 18 | 19 | enable_testing() 20 | 21 | add_subdirectory(src) 22 | add_subdirectory(tests) 23 | 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Achille Roussel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | nanomsgxx 2 | ========= 3 | 4 | nanomsgxx is a binding of the nanomsg library for C++11. 5 | 6 | *The library is still under development and changes may be brought to the API.* 7 | 8 | 9 | Building and installing 10 | ----------------------- 11 | 12 | ### Building and installing with waf 13 | 14 | nanomsgxx's build is driven by waf, you can get more information about 15 | what waf is and how it works [here](https://waf.io/book/). 16 | 17 | waf is packaged with nanomsgxx, all you should need is a python interpreter and 18 | running these commands: 19 | 20 | ``` 21 | ./waf configure 22 | ./waf build 23 | ./waf install 24 | ``` 25 | 26 | The library and headers will be installed on your system and you'll be able to 27 | link your program against **libnanomsgxx**. 28 | 29 | ### Building and installing with CMake 30 | 31 | nanomsgxx also supports CMake builds on various architectures (tested with Windows 10 + VisualStudio2017 and Ubuntu16.04 + g++/clang/c++). 32 | 33 | - install [CMake](https://cmake.org/) and a *CMake generator*, e.g. [GNU make](https://www.gnu.org/software/make/). See [here](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html) for a list of available CMake generators and how to use them. 34 | 35 | #### On Linux 36 | 37 | ```bash 38 | mkdir -p build && cd $_ 39 | 40 | # available build types: Debug, Release 41 | # install location may be adapted with -DCMAKE_INSTALL_PREFIX=path/to/install/nanomsgxx 42 | cmake -DCMAKE_BUILD_TYPE=Release .. 43 | 44 | # build example with GNU make 45 | make 46 | 47 | # run tests 48 | make test 49 | 50 | # install to default location (warning: uninstalling is not that easy) 51 | sudo make install 52 | sudo ldconfig 53 | 54 | ``` 55 | 56 | #### On Windows using Visual Studio 2017 57 | 58 | Since VisualStudio 2017 CMake is supported (see this [tutorial](https://blogs.msdn.microsoft.com/vcblog/2016/10/05/cmake-support-in-visual-studio/)). 59 | 60 | ```cmd 61 | mkdir build 62 | cd build 63 | 64 | cmake -G "Visual Studio 15 2017" .. 65 | ``` 66 | 67 | This will generate a VisualStudio 2017 `nanomsgxx.sln` file in folder `build/`. Building project `ALL_BUILD` will build the whole solution. Building project `INSTALL` (with VS2017 started as administrator) will install the project. 68 | 69 | Getting started 70 | --------------- 71 | 72 | nanomsgxx aims to provide a very thin abstraction on top of the nanomsg C API, 73 | while taking advantage of C++11's features to make the code easier to read and 74 | write. 75 | 76 | **Quick example** 77 | ```c++ 78 | #include 79 | #include 80 | #include 81 | #include 82 | #include 83 | 84 | int main() { 85 | try { 86 | nnxx::socket s1 { nnxx::SP, nnxx::PAIR }; 87 | nnxx::socket s2 { nnxx::SP, nnxx::PAIR }; 88 | const char *addr = "inproc://example"; 89 | 90 | s1.bind(addr); 91 | s2.connect(addr); 92 | 93 | s1.send("Hello World!"); 94 | 95 | nnxx::message msg = s2.recv(); 96 | std::cout << msg << std::endl; 97 | return 0; 98 | } 99 | catch (const std::system_error &e) { 100 | std::cerr << e.what() << std::endl; 101 | return 1; 102 | } 103 | } 104 | ``` 105 | 106 | **What did we write?** 107 | 108 | You've probably recognized most of these calls if you're familiar with nanomsg's 109 | API. nanomsgxx uses the *nnxx* namespace, here we have... 110 | 111 | - declared two socket objects in the *SP* domain using the *PAIR* protcol 112 | and connected them together 113 | - sent *"Hello World!"* from the first socket to the second 114 | - used the *nnxx::socket::recv* method to retrieve the message on the 115 | receiver side 116 | - printed the received message to stdout 117 | 118 | **A few highlights** 119 | 120 | - as you can expect from a C++ abstraction there's no need to manually tell when 121 | to release resources, this is handled automatically in the destructors 122 | - the *nnxx::message* type automatically manages buffers for zero-copy, making 123 | high performance code easy to write. 124 | - error cases are reported throught exceptions that are subclasses of 125 | *std::system_error* 126 | 127 | **The next step** 128 | 129 | If you're getting excited about using nanomsgxx in your next C++ project then 130 | give the documentation a look and learn more about how it abstracts the pain 131 | away from building messages, polling, timeouts and more... 132 | The library provides many useful abstractions that make developing with nanomsg 133 | easy and safe. 134 | 135 | Resources 136 | --------- 137 | 138 | Documentation: http://achille-roussel.github.io/nanomsgxx 139 | 140 | nanomsg website: http://nanomsg.org/index.html 141 | 142 | nanomsg sources: https://github.com/nanomsg/nanomsg 143 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | README -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | With no specific order 2 | - Windows support 3 | - finish writing documentation 4 | - add version 5 | -------------------------------------------------------------------------------- /doc/colorsyntax: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from bs4 import BeautifulSoup 3 | from pygments import highlight 4 | from pygments.lexers import CppLexer 5 | from pygments.token import Keyword 6 | from pygments.token import Name 7 | from pygments.formatters import HtmlFormatter 8 | import argparse 9 | import sys 10 | 11 | class Lexer(CppLexer): 12 | 13 | EXTRA_CLASSES = ( 14 | 'istream_iterator', 15 | 'message', 16 | 'message_control', 17 | 'message_istream', 18 | 'message_ostream', 19 | 'message_streambuf', 20 | 'millisecond', 21 | 'other_string_type', 22 | 'poll_vector', 23 | 'poll_entry', 24 | 'nn_pollfd', 25 | 'second', 26 | 'socket', 27 | 'timeout_error', 28 | 'vector', 29 | ) 30 | 31 | EXTRA_FUNCTIONS = ( 32 | 'recv_int_vector', 33 | ) 34 | 35 | EXTRA_NAMESPACES = ( 36 | 'chrono', 37 | 'nnxx', 38 | 'std', 39 | 'X', 40 | ) 41 | 42 | EXTRA_KEYWORDS = ( 43 | 'noexcept', 44 | 'try', 45 | ) 46 | 47 | def get_tokens_unprocessed(self, text): 48 | for index, token, value in super(Lexer, self).get_tokens_unprocessed(text): 49 | if token is not Name: 50 | yield index, token, value 51 | continue 52 | 53 | if value in self.EXTRA_KEYWORDS: 54 | yield index, Keyword, value 55 | 56 | elif value in self.EXTRA_NAMESPACES: 57 | yield index, Name.Namespace, value 58 | 59 | elif value in self.EXTRA_CLASSES: 60 | yield index, Name.Class, value 61 | 62 | elif value in self.EXTRA_FUNCTIONS: 63 | yield index, Name.Function, value 64 | 65 | elif is_constant(value): 66 | yield index, Name.Constant, value 67 | 68 | else: 69 | yield index, Name, value 70 | 71 | def is_constant(s): 72 | for c in s: 73 | if c != '_' and not c.isupper(): 74 | return False 75 | return True 76 | 77 | def parse_arguments(): 78 | parser = argparse.ArgumentParser() 79 | parser.add_argument('-s', '--style', default='default', help='The Pygments style to use') 80 | return parser.parse_args() 81 | 82 | args = parse_arguments() 83 | style = args.style 84 | doc = BeautifulSoup(sys.stdin) 85 | 86 | for pre in doc.find_all('pre'): 87 | code = pre.find('code') 88 | data = code.string 89 | pre.replace_with(BeautifulSoup(highlight(data, Lexer(), HtmlFormatter(style=style)))) 90 | 91 | print doc 92 | -------------------------------------------------------------------------------- /doc/highlight-dark.css: -------------------------------------------------------------------------------- 1 | .highlight .hll { background-color: #49483e } 2 | .highlight { background: #272822; color: white } 3 | .highlight .c { color: salmon } /* Comment */ 4 | .highlight .err { color: #960050; background-color: #1e0010 } /* Error */ 5 | .highlight .k { color: aliceblue; font-weight: bold } /* Keyword */ 6 | .highlight .l { color: white } /* Literal */ 7 | .highlight .n { color: white } /* Name */ 8 | .highlight .o { color: lightyellow } /* Operator */ 9 | .highlight .p { color: lightyellow } /* Punctuation */ 10 | .highlight .cm { color: salmon } /* Comment.Multiline */ 11 | .highlight .cp { color: salmon } /* Comment.Preproc */ 12 | .highlight .c1 { color: salmon } /* Comment.Single */ 13 | .highlight .cs { color: salmon } /* Comment.Special */ 14 | .highlight .ge { font-style: italic } /* Generic.Emph */ 15 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 16 | .highlight .kc { color: aliceblue; font-weight: bold } /* Keyword.Constant */ 17 | .highlight .kd { color: aliceblue; font-weight: bold } /* Keyword.Declaration */ 18 | .highlight .kn { color: #f92672 } /* Keyword.Namespace */ 19 | .highlight .kp { color: aliceblue; font-weight: bold } /* Keyword.Pseudo */ 20 | .highlight .kr { color: aliceblue; font-weight: bold } /* Keyword.Reserved */ 21 | .highlight .kt { color: #A9FC63 } /* Keyword.Type */ 22 | .highlight .ld { color: #A9FC63 } /* Literal.Date */ 23 | .highlight .m { color: white } /* Literal.Number */ 24 | .highlight .s { color: #A9FC63 } /* Literal.String */ 25 | .highlight .na { color: white } /* Name.Attribute */ 26 | .highlight .nb { color: white } /* Name.Builtin */ 27 | .highlight .nc { color: #A9FC63 } /* Name.Class */ 28 | .highlight .no { color: white } /* Name.Constant */ 29 | .highlight .nd { color: white } /* Name.Decorator */ 30 | .highlight .ni { color: white } /* Name.Entity */ 31 | .highlight .ne { color: white } /* Name.Exception */ 32 | .highlight .nf { color: white } /* Name.Function */ 33 | .highlight .nl { color: white } /* Name.Label */ 34 | .highlight .nn { color: violet } /* Name.Namespace */ 35 | .highlight .nx { color: white } /* Name.Other */ 36 | .highlight .py { color: white } /* Name.Property */ 37 | .highlight .nt { color: white } /* Name.Tag */ 38 | .highlight .nv { color: white } /* Name.Variable */ 39 | .highlight .ow { color: lightyellow } /* Operator.Word */ 40 | .highlight .w { color: white } /* Text.Whitespace */ 41 | .highlight .mf { color: white } /* Literal.Number.Float */ 42 | .highlight .mh { color: white } /* Literal.Number.Hex */ 43 | .highlight .mi { color: white } /* Literal.Number.Integer */ 44 | .highlight .mo { color: white } /* Literal.Number.Oct */ 45 | .highlight .sb { color: #A9FC63 } /* Literal.String.Backtick */ 46 | .highlight .sc { color: #A9FC63 } /* Literal.String.Char */ 47 | .highlight .sd { color: #A9FC63 } /* Literal.String.Doc */ 48 | .highlight .s2 { color: #A9FC63 } /* Literal.String.Double */ 49 | .highlight .se { color: white } /* Literal.String.Escape */ 50 | .highlight .sh { color: #A9FC63 } /* Literal.String.Heredoc */ 51 | .highlight .si { color: #A9FC63 } /* Literal.String.Interpol */ 52 | .highlight .sx { color: #A9FC63 } /* Literal.String.Other */ 53 | .highlight .sr { color: #A9FC63 } /* Literal.String.Regex */ 54 | .highlight .s1 { color: #A9FC63 } /* Literal.String.Single */ 55 | .highlight .ss { color: #A9FC63 } /* Literal.String.Symbol */ 56 | .highlight .bp { color: white } /* Name.Builtin.Pseudo */ 57 | .highlight .vc { color: white } /* Name.Variable.Class */ 58 | .highlight .vg { color: white } /* Name.Variable.Global */ 59 | .highlight .vi { color: white } /* Name.Variable.Instance */ 60 | .highlight .il { color: white } /* Literal.Number.Integer.Long */ 61 | .mp { color: lightgray } 62 | -------------------------------------------------------------------------------- /doc/highlight-light.css: -------------------------------------------------------------------------------- 1 | .highlight .hll { background-color: #49483e } 2 | .highlight { background: #272822; color: #f8f8f2 } 3 | .highlight .c { color: #75715e } /* Comment */ 4 | .highlight .err { color: #960050; background-color: #1e0010 } /* Error */ 5 | .highlight .k { color: #66d9ef } /* Keyword */ 6 | .highlight .l { color: #ae81ff } /* Literal */ 7 | .highlight .n { color: #f8f8f2 } /* Name */ 8 | .highlight .o { color: #f92672 } /* Operator */ 9 | .highlight .p { color: #f8f8f2 } /* Punctuation */ 10 | .highlight .cm { color: #75715e } /* Comment.Multiline */ 11 | .highlight .cp { color: #75715e } /* Comment.Preproc */ 12 | .highlight .c1 { color: #75715e } /* Comment.Single */ 13 | .highlight .cs { color: #75715e } /* Comment.Special */ 14 | .highlight .ge { font-style: italic } /* Generic.Emph */ 15 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 16 | .highlight .kc { color: #66d9ef } /* Keyword.Constant */ 17 | .highlight .kd { color: #66d9ef } /* Keyword.Declaration */ 18 | .highlight .kn { color: #f92672 } /* Keyword.Namespace */ 19 | .highlight .kp { color: #66d9ef } /* Keyword.Pseudo */ 20 | .highlight .kr { color: #66d9ef } /* Keyword.Reserved */ 21 | .highlight .kt { color: #66d9ef } /* Keyword.Type */ 22 | .highlight .ld { color: #e6db74 } /* Literal.Date */ 23 | .highlight .m { color: #ae81ff } /* Literal.Number */ 24 | .highlight .s { color: #e6db74 } /* Literal.String */ 25 | .highlight .na { color: #a6e22e } /* Name.Attribute */ 26 | .highlight .nb { color: #f8f8f2 } /* Name.Builtin */ 27 | .highlight .nc { color: #66d9ef } /* Name.Class */ 28 | .highlight .no { color: #66d9ef } /* Name.Constant */ 29 | .highlight .nd { color: #a6e22e } /* Name.Decorator */ 30 | .highlight .ni { color: #f8f8f2 } /* Name.Entity */ 31 | .highlight .ne { color: #a6e22e } /* Name.Exception */ 32 | .highlight .nf { color: #a6e22e } /* Name.Function */ 33 | .highlight .nl { color: #f8f8f2 } /* Name.Label */ 34 | .highlight .nn { color: khaki } /* Name.Namespace */ 35 | .highlight .nx { color: #a6e22e } /* Name.Other */ 36 | .highlight .py { color: #f8f8f2 } /* Name.Property */ 37 | .highlight .nt { color: #f92672 } /* Name.Tag */ 38 | .highlight .nv { color: #f8f8f2 } /* Name.Variable */ 39 | .highlight .ow { color: #f92672 } /* Operator.Word */ 40 | .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ 41 | .highlight .mf { color: #ae81ff } /* Literal.Number.Float */ 42 | .highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ 43 | .highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ 44 | .highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ 45 | .highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ 46 | .highlight .sc { color: #e6db74 } /* Literal.String.Char */ 47 | .highlight .sd { color: #e6db74 } /* Literal.String.Doc */ 48 | .highlight .s2 { color: #e6db74 } /* Literal.String.Double */ 49 | .highlight .se { color: #ae81ff } /* Literal.String.Escape */ 50 | .highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ 51 | .highlight .si { color: #e6db74 } /* Literal.String.Interpol */ 52 | .highlight .sx { color: #e6db74 } /* Literal.String.Other */ 53 | .highlight .sr { color: #e6db74 } /* Literal.String.Regex */ 54 | .highlight .s1 { color: #e6db74 } /* Literal.String.Single */ 55 | .highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ 56 | .highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ 57 | .highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ 58 | .highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ 59 | .highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ 60 | .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ 61 | -------------------------------------------------------------------------------- /doc/index.txt: -------------------------------------------------------------------------------- 1 | ## 2 | # The MIT License (MIT) 3 | # 4 | # Copyright (c) 2014 Achille Roussel 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | ## 24 | 25 | # project's man pages 26 | nnxx(3) nnxx.3.ronn 27 | nnxx::message(3) nnxx/message.3.ronn 28 | nnxx::message_control(3) nnxx/message.3.ronn 29 | nnxx::message_istream(3) nnxx/message.3.ronn 30 | nnxx::message_ostream(3) nnxx/message.3.ronn 31 | nnxx::message_streambuf(3) nnxx/message.3.ronn 32 | nnxx::poll_entry(3) nnxx/poll.3.ronn 33 | nnxx::poll_vector(3) nnxx/poll.3.ronn 34 | nnxx::ready_iterator(3) nnxx/poll.3.ronn 35 | nnxx::ready_sequence(3) nnxx/poll.3.ronn 36 | nnxx::signal_error(3) nnxx/signal.3.ronn 37 | nnxx::socket(3) nnxx/socket.3.ronn 38 | nnxx::symbol_properties(3) nnxx/symbol.3.ronn 39 | nnxx::term_error(3) nnxx/term.3.ronn 40 | nnxx::timeout_error(3) nnxx/timeout.3.ronn 41 | nnxx::with_linger(3) nnxx/timeout.3.ronn 42 | nnxx::with_recv_timeout(3) nnxx/timeout.3.ronn 43 | nnxx::with_send_timeout(3) nnxx/timeout.3.ronn 44 | nnxx::c_str(3) nnxx/strings.3.ronn 45 | nnxx::device(3) nnxx/device.3.ronn 46 | nnxx::get_linger(3) nnxx/timeout.3.ronn 47 | nnxx::get_send_timeout(3) nnxx/timeout.3.ronn 48 | nnxx::get_surveyor_deadline(3) nnxx/timeout.3.ronn 49 | nnxx::poll(3) nnxx/poll.3.ronn 50 | nnxx::recv_ready(3) nnxx/poll.3.ronn 51 | nnxx::send_ready(3) nnxx/poll.3.ronn 52 | nnxx::set_linger(3) nnxx/timeout.3.ronn 53 | nnxx::set_recv_timeout(3) nnxx/timeout.3.ronn 54 | nnxx::set_resend_interval(3) nnxx/timeout.3.ronn 55 | nnxx::set_send_timeout(3) nnxx/timeout.3.ronn 56 | nnxx::set_surveyor_deadline(3) nnxx/timeout.3.ronn 57 | nnxx::strerror(3) nnxx/strings.3.ronn 58 | nnxx::subscribe(3) nnxx/pubsub.3.ronn 59 | nnxx::symbol(3) nnxx/symbol.3.ronn 60 | nnxx::term(3) nnxx/term.3.ronn 61 | nnxx::unsubscribe(3) nnxx/pubsub.3.ronn 62 | nnxx::this_thread(3) nnxx/this_thread.3.ronn 63 | nanomsgxx(7) nanomsgxx.7.ronn 64 | nanomsgxx-design(7) nanomsgxx/design.7.ronn 65 | nanomsgxx-messages(7) nanomsgxx/messages.7.ronn 66 | nanomsgxx-polling(7) nanomsgxx/polling.7.ronn 67 | nanomsgxx-sockets(7) nanomsgxx/sockets.7.ronn 68 | 69 | # external man pages 70 | nanomsg(7) http://nanomsg.org/v0.3/nanomsg.7.html 71 | -------------------------------------------------------------------------------- /doc/nanomsgxx.7.ronn: -------------------------------------------------------------------------------- 1 | nanomsgxx(7) -- C++11 binding for nanomsg 2 | ========================================= 3 | 4 | ## SYNOPSIS 5 | 6 | c++ -std=c++11 [flags] files **-lnnxx** [libraries] 7 | 8 | ## DESCRIPTION 9 | 10 | **nanomsgxx** is a binding of the **nanomsg** library for C++11, it is designed 11 | to take full advantage of C++11 features in order to make the code safe and easy 12 | to read and write. 13 | 14 | ## LICENSE 15 | 16 | **nanomsgxx** is released under the MIT license, you should have got a copy of 17 | the license along with the sources. 18 | 19 | ## INSTALL 20 | 21 | **nanomsgxx** build is driven by **waf**. 22 | 23 | waf is packaged with nanomsgxx, all you need a python interpreter, then run 24 | these commands: 25 | 26 | ** 27 | ./waf configure 28 | ./waf build 29 | ./waf install** 30 | 31 | The library and headers will be installed on your system and you'll be able to 32 | link your programs with **-lnnxx**. 33 | 34 | ## RESOURCES 35 | 36 | [Nanomsg](http://nanomsg.org/index.html) 37 | [The Waf Book](https://waf.io/book/) 38 | [MIT License](http://opensource.org/licenses/MIT) 39 | 40 | ## SEE ALSO 41 | 42 | nnxx(3) 43 | nnxx::this_thread(3) 44 | nanomsgxx-design(7) 45 | nanomsgxx-messages(7) 46 | nanomsgxx-sockets(7) 47 | nanomsgxx-polling(7) 48 | nanomsg(7) 49 | 50 | ## AUTHORS 51 | 52 | Achille Roussel 53 | -------------------------------------------------------------------------------- /doc/nanomsgxx/design.7.ronn: -------------------------------------------------------------------------------- 1 | nanomsgxx-design(7) -- Nanomsgxx Design 2 | ======================================= 3 | 4 | ## DESCRIPTION 5 | 6 | This chapter exposes the main design decisions that were made when developping 7 | nanomsgxx. 8 | 9 | ## CONSTANTS 10 | 11 | nanomsg uses many constants to represent protocols, socket domains, options, 12 | flags... Since C++ syntax is mostly compatible with C, standard nanomsg constants 13 | (NN) can be simply used wherever constants are expected in the C++ API. 14 | However nanomsgxx ports all constants within the nnxx namespace, removing the 15 | leading `NN_`. For example the `NN_MSG` constant in the C API is ported by the 16 | `nnxx::MSG` symbol. This applies to almost all constants, except in a few cases 17 | where it conflicts with some existing symbols (more on that later). 18 | 19 | ## STRINGS 20 | 21 | nanomsgxx functions accept string arguments in some cases, to bind or connect 22 | to a node for example. Everywhere a string is expected the functions are designed 23 | to receive any object that can be converted to a C-string (null-terminted char 24 | sequence), this includes: 25 | 26 | - objects of `const char *` type, or implicitly converted to this pointer type 27 | - objects of `std::string` type, or any other specialization of `std::basic_string` 28 | - any object with a c_str member function returning a `const char *` 29 | 30 | This feature can be extended by providing a c_str function for new types, for example: 31 | 32 | ``` 33 | namespace X { 34 | const char *c_str(const other_string_type &s) { 35 | return s.c_string(); 36 | } 37 | } 38 | ``` 39 | 40 | ## OBJECTS 41 | 42 | The nanomsgxx API provides a few object types that abstracts concepts of the C 43 | API, while trying to stay as close as possible it adds a few extra types to 44 | integrate with the C++ standard library and take advantages of the rich features 45 | of the language. 46 | 47 | - **Moveable Objects** 48 | 49 | All types in the nanomsgxx API provide a move constructor and a move assignment 50 | operator, these are powerful features of C++11 and the library makes heavy use 51 | of it to provide an easy resource management model, as well as protecting the 52 | user from mis-using the library in some places. 53 | 54 | - **Member vs Non-Member Functions** 55 | 56 | Member functions are used of nanomsgxx objects to provide operations that are 57 | part of the object's identity, providing the low-level pieces on which extensions 58 | can be built. 59 | For example the `nnxx::socket` type will have the recv and send member functions 60 | because receiving and sending messages are the core features of the this type, 61 | but protocol extensions such as turning on or off Nagle's algorithm for TCP 62 | connections will be provided as a non-member function because it's not an 63 | operation that can be performed on any socket type. 64 | 65 | ## EXCEPTIONS 66 | 67 | The nanomsg library uses the POSIX mechanism to report errors, setting errno 68 | to some error number and returning a nagative number from the function. 69 | C++ exceptions are used to report these conditions and almost all exceptions 70 | thrown by the nanomsgxx functions are sub-classes of `std::system_error`, so the 71 | original error number that was generated by the underlying nanomsg routine can 72 | be accessed through the caught exception. 73 | 74 | - **Signals** 75 | 76 | When a program receives a signal it may cause any ongoing system call to be 77 | cancelled to execute a signal handler instead, in that case the systeam call 78 | terminates with the EINTR error code. While nanomsg mirrors this behavior, 79 | nanomsgxx reports these conditions with the `nnxx::signal_error` exception. 80 | This can be deactivated on a per-call basis by passing `nnxx::NO_SIGNAL_ERROR` 81 | in the flags argument on any blocking call, you should then refer to the 82 | documentation of each function to understand how to handle this case. 83 | 84 | - **Timeouts** 85 | 86 | nanomsg's API lets the user define a timeout for any blocking operation 87 | (typically receiving or sending messages), and reports any timeout in the 88 | operation with a `nnxx::timeout_error` exception. 89 | This can be deactivated on a per-call basis by passing `nnxx::NO_TIMEOUT_ERROR` 90 | in the flags argument on any blocking call, you should then refer to the 91 | documentation of each function to understand how to handle this case. 92 | 93 | - **Termination** 94 | 95 | When the program is about to exit it is supposed to inform the nanomsg library 96 | by calling nn_term, making any future or pending calls to nanomsg routines 97 | failing and setting errno to ETERM. While this is still reported with an 98 | exception in nanomsgxx it's on case where the exception thrown isn't a sub-class 99 | of `std::system_error`. The `nnxx::term_error` exception is instead a sub-class of 100 | `std::logic_error`. That allows the program to handle this condition away from 101 | local error handling logic. 102 | 103 | - **Memory Allocation** 104 | 105 | The nanomsg library uses dynamic memory allocations in some places, if these 106 | fail for whatever reasons the functions report the error with the ENOMEM errno 107 | code. 108 | This is another case where nanomsgxx will report an error through an exception 109 | that is not a subclass of `std::system_error`. The C++ standard library provides 110 | the `std::bad_alloc` exception for this purpose, in order to easily integrate with 111 | programs that are written for standard C++ nanomsgxx also reports memory 112 | allocation failures by throwing an instance of `std::bad_alloc`. 113 | 114 | ## SEE ALSO 115 | 116 | nanomsgxx(7) 117 | nanomsgxx-messages(7) 118 | nanomsg(7) 119 | 120 | ## AUTHORS 121 | 122 | Achille Roussel 123 | -------------------------------------------------------------------------------- /doc/nanomsgxx/index.txt: -------------------------------------------------------------------------------- 1 | ## 2 | # The MIT License (MIT) 3 | # 4 | # Copyright (c) 2014 Achille Roussel 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | ## 24 | 25 | # project's man pages 26 | nnxx(3) ../nnxx.3.ronn 27 | nnxx::message(3) ../nnxx/message.3.ronn 28 | nnxx::message_control(3) ../nnxx/message.3.ronn 29 | nnxx::message_istream(3) ../nnxx/message.3.ronn 30 | nnxx::message_ostream(3) ../nnxx/message.3.ronn 31 | nnxx::poll(3) ../nnxx/poll.3.ronn 32 | nnxx::socket(3) ../nnxx/socket.3.ronn 33 | nanomsgxx(7) ../nanomsgxx.7.ronn 34 | nanomsgxx-design(7) design.7.ronn 35 | nanomsgxx-messages(7) messages.7.ronn 36 | nanomsgxx-polling(7) polling.7.ronn 37 | nanomsgxx-sockets(7) sockets.7.ronn 38 | 39 | # external man pages 40 | nanomsg(7) http://nanomsg.org/v0.3/nanomsg.7.html 41 | -------------------------------------------------------------------------------- /doc/nanomsgxx/messages.7.ronn: -------------------------------------------------------------------------------- 1 | nanomsgxx-messages(7) -- Nanomsgxx Messages 2 | =========================================== 3 | 4 | ## DESCRIPTION 5 | 6 | nanomsg is all about passing messages around from nodes to others, so nanomsgxx 7 | provides abstractions to make managing such messages easy and efficient. 8 | This chapter introduces the different abstraction types that allows you to deal 9 | with messages in nanomsgxx. 10 | 11 | ## MESSAGE 12 | 13 | Messages passed from and to sockets are represented by the nnxx::message type, 14 | it features: 15 | 16 | - automatic memory management 17 | - zero-copy operations when sending and recveiving on sockets 18 | 19 | Every memory buffer managed by a `nnxx::message` object is allocated and freed 20 | using the `nn_allocmsg` and `nn_freemsg` functions of the nanomsg C API. 21 | Here's an example of how you could use a `nnxx::message` instance: 22 | 23 | ``` 24 | void forward_message(nnxx::socket &from, nnxx::socket &to) 25 | { 26 | nnxx::message m; 27 | 28 | // These operations don't copy the message, it's simply passed 29 | // around. 30 | m = from.recv(); 31 | to.send(std::move(m)); 32 | 33 | // Could also be made shorter: 34 | // to.send(recv.from()); 35 | } 36 | ``` 37 | 38 | Messages are very useful objects for managing memory buffers but they don't provide 39 | any interface to work with these buffers. Standard C++ defines the iostream interface 40 | for this purpose, and nanomsgxx messages come along with input and output streams 41 | that provide compatibility with existing standard C++ code. 42 | 43 | ## OUTPUT STREAMS 44 | 45 | Output streams are useful for abstracting away the support on which we write 46 | formatted data to, if we want to build a message to send it over a socket we can 47 | use such stream to do so. 48 | Instances of `nnxx::message_ostream` are designed for this use case, here's an example: 49 | 50 | ``` 51 | void send_hello_world_42(nnxx::socket &s) 52 | { 53 | nnxx::message_ostream os; 54 | 55 | // Simply use the object like any standard output stream. 56 | os << "Hello World "; 57 | os << 42; 58 | 59 | // Get an instance of nnxx::message and send it through the 60 | // socket, the connected peer will receive "Hello World 42". 61 | s.send(os.msg()); 62 | } 63 | ``` 64 | 65 | ## INPUT STREAMS 66 | 67 | When receiving a message from a socket we can use parsers based on standard C++ 68 | streams to read the data. nanomsgxx provides the `nnxx::message_istream` type, 69 | here's a usage example: 70 | 71 | ``` 72 | std::vector recv_int_vector(nnxx::socket &s) 73 | { 74 | // Build a new input stream from a received message. 75 | std::message_istream is { s.recv() }; 76 | 77 | // Use a standard input stream iterator to read all integers. 78 | std::istream_iterator begin { is }; 79 | std::istream_iterator end { }; 80 | 81 | // It's that easy ;) 82 | return { begin, end }; 83 | } 84 | ``` 85 | 86 | ## CONTROLS 87 | 88 | When using nanomsg raw sockets (`nnxx::SP_RAW`), messages can be associated 89 | with control headers that provide meta informations relative to the underlying 90 | protocol (routing for example). 91 | In the basic C API provides the `nn_sendmsg` and `nn_recvmsg` for this purpose, 92 | which lets us retrieve the control information within the `nn_msghdr` object we 93 | pass to these functions. 94 | 95 | This feature is abstracted in nanomsgxx with the `nnxx::message_control` type, 96 | which we can get or set and receiving and sending messages, this is particulary 97 | useful when dealing with `nnxx::REP` sockets if we want to handle requests in 98 | parallel. 99 | 100 | ``` 101 | nnxx::socket s { nnxx::SP_RAW, nnxx::REP }; 102 | 103 | // ... 104 | 105 | nnxx::message_control ctl1; 106 | nnxx::message_control ctl2; 107 | nnxx::message req1; 108 | nnxx::message req2; 109 | int flags = 0; 110 | 111 | // Receiving messages and associated control headers. 112 | req1 = s.recv(flags, ctl1); 113 | req2 = s.recv(flags, ctl2); 114 | 115 | // ... 116 | 117 | // Sending responses in different order, it's a raw socket, 118 | // we're not bound to follow the end-to-end enforcements of 119 | // simple sockets. 120 | s.send(std::move(rep2), flags, std::move(ctl2)); 121 | s.send(std::move(rep1), flags, std::move(ctl1)); 122 | ``` 123 | 124 | ## SEE ALSO 125 | 126 | nnxx::message(3) 127 | nnxx::message_control(3) 128 | nnxx::message_istream(3) 129 | nnxx::message_ostream(3) 130 | nanomsgxx(7) 131 | nanomsgxx-polling(7) 132 | nanomsg(7) 133 | 134 | ## AUTHORS 135 | 136 | Achille Roussel 137 | -------------------------------------------------------------------------------- /doc/nanomsgxx/polling.7.ronn: -------------------------------------------------------------------------------- 1 | nanomsgxx-polling(7) -- Nanomsgxx Polling 2 | ========================================= 3 | 4 | ## DESCRIPTION 5 | 6 | The nanomsg C API provides a powerful polling system that is mirrored on POSIX's 7 | polling interface. C++ though doesn't have any sort of interface for polling 8 | events on file descriptors in the standard library, so nanomsgxx comes with its 9 | own API for polling on nanomsg sockets instead of integrating with an existing one. 10 | The wrapper is very small and mostly is syntaxing sugar on top of the C API. 11 | 12 | ## ENTRIES 13 | 14 | Polling is done by passing a vector or nnxx::poll_entry objects to the `nnxx::poll` 15 | function, such objects are defined as: 16 | 17 | ``` 18 | class poll_entry : public nn_pollfd { 19 | public: 20 | poll_entry() noexcept; 21 | poll_entry(int socket, int events) noexcept; 22 | poll_entry(socket &socket, int events) noexcept; 23 | 24 | void clear() noexcept; 25 | void set(int socket, int events) noexcept; 26 | void set(socket &socket, int events) noexcept; 27 | 28 | bool is(const socket &s) const noexcept; 29 | bool recv_ready() const noexcept; 30 | bool send_ready() const noexcept; 31 | }; 32 | ``` 33 | 34 | They are simple descriptors associtating sockets to a set of events that we wnat 35 | to wait for and will get filled with events that happened while calling `nnxx::poll`. 36 | They inherit from nn_pollfd for compatibility with the C API, and simply add some 37 | useful operations. 38 | Read `nn_poll`'s documentation to learn more about how the polling mechanism works. 39 | 40 | ## POLL 41 | 42 | `nnxx::poll` is available in different versions that makes it easy to use in 43 | multiple situations. The two main interfaces are as follow: 44 | 45 | ``` 46 | poll_vector poll(poll_vector &&, , ); 47 | poll_vector &poll(poll_vector &, , ); 48 | ``` 49 | 50 | The first version accepts a temporary vector object that is used for polling the 51 | entries it contains and will be returned by the function with a move operation, 52 | so no extra memory will be allocated. 53 | 54 | The second version accepts a reference to a vector object allocated somewhere 55 | else in the program. Based on the use case one may find useful to use one version 56 | or the other. 57 | 58 | The vector returned by nnxx::poll has its entries set with whatever events have 59 | been found on the sockets, the entries then should be iterated and checked to 60 | verify which events are available for which socket. 61 | nanomsgxx comes with two useful functions, `nnxx::recv_ready` and `nnxx::send_ready`, 62 | that return iterable objects that will filter entries that were marked by `nnxx::poll` 63 | as ready for receiving or sending messages. 64 | Here's an usage example: 65 | 66 | ``` 67 | nnxx::socket s1 { /* ... */ }; 68 | nnxx::socket s2 { /* ... */ }; 69 | 70 | // ... 71 | 72 | // Polling the socket, nnxx::poll_vector can be initialized from a 73 | // std::initializer_list 74 | nnxx::poll_vector entries = nnxx::poll({ 75 | { s1, nnxx::EV_POLLIN }, 76 | { s2, nnxx::EV_POLLIN | nnxx::EV_POLLOUT }, 77 | }); 78 | 79 | for (auto e : nnxx::recv_ready(entries)) { 80 | // All entries enumerated here won't block on a receive operation. 81 | } 82 | 83 | for (auto e : nnxx::send_ready(entries)) { 84 | // All entries enumerated here won't block on a send operation. 85 | } 86 | ``` 87 | 88 | - **Note** 89 | 90 | The C API uses NN_POLIN and NN_POLOUT as event flags, so nanomsgxx should have 91 | named its constants `nnxx::POLLIN` and `nnxx::POLLOUT`, but these names are macros 92 | defined on POSIX systems supporting the poll interface and would cause compilation 93 | to fail. That's why nanomsgxx uses `nnxx::EV_POLLIN` and `nnxx::EV_POLLOUT` instead. 94 | 95 | - **Timeouts** 96 | 97 | Polling is by nature a blocking operation, so the API has to provides a way to set 98 | a timeout that will give the hand back to the program in case nothing happens for 99 | a while because we may have to do some other things once in a while. 100 | 101 | As described in the design section, exceptions are used to report timeouts in the 102 | nanomsgxx API. 103 | A timeout can be specified as second argument to the nnxx::poll function, it may 104 | be give as a std::chrono::duration (if we want to set how long the function should 105 | wait), or as a std::chrono::time_point (if we want to set when the function should 106 | return). 107 | Here's how we'd handle a timeout: 108 | 109 | ``` 110 | nnxx::poll_vector entries; 111 | 112 | // ... 113 | 114 | try { 115 | // Polls for events, waits at most one second. 116 | entries = nnxx::poll({ 117 | { s1, nnxx::EV_POLLIN }, 118 | { s2, nnxx::EV_POLLIN | nnxx::EV_POLLOUT }, 119 | }, 120 | std::chrono::second(1)); 121 | } 122 | catch (const nnxx::timeout_error &) { 123 | // Nothing happened for more than one second. 124 | } 125 | ``` 126 | 127 | ## SEE ALSO 128 | 129 | nnxx::poll(3) 130 | nanomsgxx(7) 131 | nanomsgxx-sockets(7) 132 | nanomsg(7) 133 | 134 | ## AUTHORS 135 | 136 | Achille Roussel 137 | -------------------------------------------------------------------------------- /doc/nanomsgxx/sockets.7.ronn: -------------------------------------------------------------------------------- 1 | nanomsgxx-sockets(7) -- Nanomsgxx Sockets 2 | ========================================= 3 | 4 | ## DESCRIPTION 5 | 6 | Sockets are one main component of the nanomsg API, they're used to exchanged 7 | messages between nodes and are reprented by descriptors. 8 | nanomsgxx uses the nnxx::socket type to wrap around such descriptors and provide 9 | automatic resource management and low level abstractions around the C API socket 10 | routines. 11 | 12 | ## SEND 13 | 14 | The nnxx::socket type has a send member function that lets us send messages 15 | throught a socket, it comes with multiple signatures: 16 | 17 | ``` 18 | class socket { 19 | 20 | // ... 21 | 22 | // Working with any memory buffer. 23 | int send(const void *b, size_t n, int f, message_control &&c); 24 | int send(const void *b, size_t n, int f = 0); 25 | 26 | // Working with C-strings. 27 | int send(const char *s, int f, message_control &&c); 28 | int send(const char *s, int f = 0); 29 | 30 | // Working with any string-like types. 31 | template < typename T > 32 | int send(const T &s, int f, message_control &&c); 33 | template < typename T > 34 | int send(const T &s, int f = 0); 35 | 36 | // Zero-copy operations. 37 | int send(message &&m, int f, message_control &&c); 38 | int send(message &&m, int f = 0); 39 | 40 | // ... 41 | 42 | }; 43 | ``` 44 | 45 | As you can see the type of the first argument specifies which version will be 46 | selected by the compiler, and other arguments are always the same: 47 | 48 | - optional flags, that may be a combination of `nnxx::DONTWAIT`, `nnxx::NO_SIGNAL_ERROR` and `nnxx::NO_TIMEOUT_ERROR` 49 | - optional `nnxx::message_control` instance providing meta-information to the underlying procotol 50 | 51 | The template versions of the send functions accept any type that can be iterated. 52 | 53 | The send functions return the number of bytes in the sent messages, or a negative 54 | value under some conditions if the flags argument isn't zero. 55 | 56 | ## RECEIVE 57 | 58 | Receiving messages is just as easy as sending, using the recv member function 59 | that exists with these signatures: 60 | 61 | ``` 62 | class socket { 63 | 64 | // ... 65 | 66 | // Working with any memory buffer. 67 | int recv(void *buf, size_t len, int flags, message_control &ctl); 68 | int recv(void *buf, size_t len, int flags = 0); 69 | 70 | // Working with any string-like types. 71 | template < typename T > 72 | T recv(int flags, message_control &ctl); 73 | template < typename T > 74 | T recv(int flags = 0); 75 | 76 | // Zero-copy operations. 77 | message recv(int flags, message_control &ctl); 78 | message recv(nt flags = 0); 79 | 80 | // ... 81 | 82 | }; 83 | ``` 84 | 85 | As you can see the type of the first argument specifies which version will be 86 | selected by the compiler, and other arguments are always the same: 87 | 88 | - optional flags, that may be a combination of `nnxx::DONTWAIT`, `nnxx::NO_SIGNAL_ERROR` and `nnxx::NO_TIMEOUT_ERROR` 89 | - optional `nnxx::message_control` instance where meta-information coming from the underlying protocol will be stored 90 | 91 | The first version of recv functions return the number of bytes in the received 92 | message, or a negative value under some conditions if the flags argument isn't 93 | zero. 94 | The second version is templated, the template argument should be a sequence 95 | container (string, vector, list... ) that accepts two iterators (start and end) 96 | as argument. The third version return an instance `nnxx::message` carying a 97 | memory buffer with a message read from the socket, the object can be evaluated 98 | to false if something happened and the flags argument wasn't zero, for example: 99 | 100 | ``` 101 | nnxx::message msg { s.recv(nnxx::DONTWAIT) }; 102 | 103 | if (!msg) { 104 | // Check errno, it's probably be set to EAGAIN because 105 | // no message could be read from the socket. 106 | // ... 107 | } 108 | ``` 109 | 110 | ## OPTIONS 111 | 112 | Options can be set on sockets, some options apply to the socket properties, some 113 | other apply to the underlying protocol. nnxx::socket provides member functions 114 | that wrap around the nn_setsockopt and nn_getsockopt routine: 115 | 116 | ``` 117 | class socket { 118 | 119 | // ... 120 | 121 | void setopt(int lvl, int name, const void *val, size_t len); 122 | 123 | template < typename T > 124 | void setopt(int lvl, int name, const T &val); 125 | 126 | void getopt(int lvl, int name, void *val, size_t *len) const; 127 | 128 | template < typename T > 129 | void getopt(int lvl, int name, T &val) const; 130 | 131 | template < typename T > 132 | T getopt(int lvl, int name) const; 133 | 134 | // ... 135 | 136 | }; 137 | ``` 138 | 139 | The templated version uses the other one and is a simple wrapper for convenience 140 | so the option type must match the one required by the nanomsg C API. 141 | 142 | ## SEE ALSO 143 | 144 | nnxx::socket(3) 145 | nanomsgxx(7) 146 | nanomsg(7) 147 | 148 | ## AUTHORS 149 | 150 | Achille Roussel 151 | -------------------------------------------------------------------------------- /doc/nnxx.3.ronn: -------------------------------------------------------------------------------- 1 | nnxx(3) -- main nanomsgxx namespace 2 | =================================== 3 | 4 | ## SYNOPSIS 5 | 6 | **#include ** 7 | 8 | using namespace nnxx; 9 | 10 | ## DESCRIPTION 11 | 12 | The **nnxx** namespace is used as top-level namespace, it contains all types and 13 | symbols of the nanomsgxx library. 14 | 15 | ## TYPES 16 | 17 | **message** 18 | Message abstraction for zero-copy 19 | 20 | **message_control** 21 | Protocol dependant control data 22 | 23 | **message_istream** 24 | Parse messages using standard input streams 25 | 26 | **message_ostream** 27 | Format messages using standard input streams 28 | 29 | **message_streambuf** 30 | Stream buffer for message input and output streams 31 | 32 | **poll_entry** 33 | Objects used to poll events on sockets 34 | 35 | **poll_vector** 36 | Vector of poll_entry objects 37 | 38 | **ready_iterator** 39 | Iterate over poll events marked as ready for reading or writing 40 | 41 | **ready_sequence** 42 | Proxy object generating a begin and end ready_iterator 43 | 44 | **signal_error** 45 | Exception thrown when an operation is interrupted by a signal 46 | 47 | **socket** 48 | Abstraction of nanomsg sockets 49 | 50 | **symbol_properties** 51 | Representation of a nanomsg symbol 52 | 53 | **term_error** 54 | Exception thrown when the nanomsg library is terminating 55 | 56 | **timeout_error** 57 | Exception thrown when an operation times out 58 | 59 | **with_linger** 60 | Scope-based linger timeout setter 61 | 62 | **with_recv_timeout** 63 | Scope-based receive timeout setter 64 | 65 | **with_send_timeout** 66 | Scope-based send timeout setter 67 | 68 | ## FUNCTIONS 69 | 70 | *const char \** **c_str**(*string*) 71 | Convert types to c-string representations 72 | 73 | *void* **device**(*socket*, *socket*) 74 | Sets up a proxy routing messages from a socket to another 75 | 76 | *milliseconds* **get_linger**(*socket*) 77 | Gets the linger timeout on a socket 78 | 79 | *milliseconds* **get_recv_timeout**(*socket*) 80 | Gets the receive timeout on a socket 81 | 82 | *milliseconds* **get_resend_interval**(*socket*) 83 | Gets the resend timeout on a socket 84 | 85 | *milliseconds* **get_send_timeout**(*socket*) 86 | Gets the send timeout on a socket 87 | 88 | *milliseconds* **get_surveyor_deadline**(*socket*) 89 | Gets the surveyor timeout on a socket 90 | 91 | *void* **poll**(*poll_vector*, *milliseconds*, *flags*) 92 | Polls for events available on sockets 93 | 94 | *recv_ready_sequence* **recv_ready**(*poll_vector*) 95 | Get a sequence of poll entries ready for receive operations 96 | 97 | *send_ready_sequence* **send_ready**(*poll_vector*) 98 | Get a sequence of poll entries ready for send operations 99 | 100 | *void* **set_linger**(*socket*, *milliseconds*) 101 | Sets the linger timeout on a socket 102 | 103 | *void* **set_recv_timeout**(*socket*, *milliseconds*) 104 | Sets the receive timeout on a socket 105 | 106 | *void* **set_resend_interval**(*socket*, *milliseconds*) 107 | Sets the resend timeout on a socket 108 | 109 | *void* **set_send_timeout**(*socket*, *milliseconds*) 110 | Sets the send timeout on a socket 111 | 112 | *void* **set_surveyor_deadline**(*socket*, *milliseconds*) 113 | Sets the surveyor timeout on a socket 114 | 115 | *const char \** **strerror**(*code*) 116 | Returns a human-readable representation of an error code 117 | 118 | *void* **subscribe**(*socket*, *topic*) 119 | Subscribe a SUB socket to a topic 120 | 121 | *symbol_properties* **symbol**(*index*) 122 | Returns informations on a nanomsg symbol 123 | 124 | *void* **term**() 125 | Force all ongoing and future nanomsg operations to abort 126 | 127 | *void* **unsubscribe**(*socket*, *topic*) 128 | Gets the current error status on the calling thread 129 | 130 | ## SEE ALSO 131 | 132 | nnxx::message(3) 133 | nnxx::message_control(3) 134 | nnxx::message_istream(3) 135 | nnxx::message_ostream(3) 136 | nnxx::message_streambuf(3) 137 | nnxx::poll_entry(3) 138 | nnxx::poll_vector(3) 139 | nnxx::ready_iterator(3) 140 | nnxx::ready_sequence(3) 141 | nnxx::signal_error(3) 142 | nnxx::socket(3) 143 | nnxx::symbol_properties(3) 144 | nnxx::term_error(3) 145 | nnxx::timeout_error(3) 146 | nnxx::with_linger(3) 147 | nnxx::with_recv_timeout(3) 148 | nnxx::with_send_timeout(3) 149 | nnxx::c_str(3) 150 | nnxx::device(3) 151 | nnxx::get_linger(3) 152 | nnxx::get_send_timeout(3) 153 | nnxx::get_surveyor_deadline(3) 154 | nnxx::poll(3) 155 | nnxx::recv_ready(3) 156 | nnxx::send_ready(3) 157 | nnxx::set_linger(3) 158 | nnxx::set_recv_timeout(3) 159 | nnxx::set_resend_interval(3) 160 | nnxx::set_send_timeout(3) 161 | nnxx::set_surveyor_deadline(3) 162 | nnxx::strerror(3) 163 | nnxx::subscribe(3) 164 | nnxx::symbol(3) 165 | nnxx::term(3) 166 | nnxx::unsubscribe(3) 167 | nnxx::this_thread(3) 168 | nanomsgxx(7) 169 | 170 | ## AUTHORS 171 | 172 | Achille Roussel 173 | -------------------------------------------------------------------------------- /doc/nnxx.css: -------------------------------------------------------------------------------- 1 | #man { 2 | margin: auto; 3 | width: 100ex; 4 | } 5 | 6 | .mp { 7 | -webkit-text-size-adjust:none; 8 | -moz-text-size-adjust:none; 9 | -ms-text-size-adjust:none; 10 | -webkit-text-size-adjust:100%; 11 | -moz-text-size-adjust:100%; 12 | -ms-text-size-adjust:100%; 13 | } 14 | 15 | .mp pre { 16 | border: 1px solid dimgray; 17 | padding: 1em; 18 | overflow: auto; 19 | } 20 | 21 | .highlight { 22 | margin-left: 8ex; 23 | } 24 | -------------------------------------------------------------------------------- /doc/nnxx/index.txt: -------------------------------------------------------------------------------- 1 | ## 2 | # The MIT License (MIT) 3 | # 4 | # Copyright (c) 2014 Achille Roussel 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | ## 24 | 25 | # project's man pages 26 | nnxx(3) ../nnxx.3.ronn 27 | nnxx::message(3) message.3.ronn 28 | nnxx::message_control(3) message.3.ronn 29 | nnxx::message_istream(3) message.3.ronn 30 | nnxx::message_ostream(3) message.3.ronn 31 | nnxx::message_streambuf(3) message.3.ronn 32 | nnxx::poll_entry(3) poll.3.ronn 33 | nnxx::poll_vector(3) poll.3.ronn 34 | nnxx::ready_iterator(3) poll.3.ronn 35 | nnxx::ready_sequence(3) poll.3.ronn 36 | nnxx::signal_error(3) signal.3.ronn 37 | nnxx::socket(3) socket.3.ronn 38 | nnxx::symbol_properties(3) symbol.3.ronn 39 | nnxx::term_error(3) term.3.ronn 40 | nnxx::timeout_error(3) timeout.3.ronn 41 | nnxx::with_linger(3) timeout.3.ronn 42 | nnxx::with_recv_timeout(3) timeout.3.ronn 43 | nnxx::with_send_timeout(3) timeout.3.ronn 44 | nnxx::c_str(3) strings.3.ronn 45 | nnxx::device(3) device.3.ronn 46 | nnxx::get_linger(3) timeout.3.ronn 47 | nnxx::get_send_timeout(3) timeout.3.ronn 48 | nnxx::get_surveyor_deadline(3) timeout.3.ronn 49 | nnxx::poll(3) poll.3.ronn 50 | nnxx::recv_ready(3) poll.3.ronn 51 | nnxx::send_ready(3) poll.3.ronn 52 | nnxx::set_linger(3) timeout.3.ronn 53 | nnxx::set_recv_timeout(3) timeout.3.ronn 54 | nnxx::set_resend_interval(3) timeout.3.ronn 55 | nnxx::set_send_timeout(3) timeout.3.ronn 56 | nnxx::set_surveyor_deadline(3) timeout.3.ronn 57 | nnxx::strerror(3) strings.3.ronn 58 | nnxx::subscribe(3) pubsub.3.ronn 59 | nnxx::symbol(3) symbol.3.ronn 60 | nnxx::term(3) term.3.ronn 61 | nnxx::unsubscribe(3) pubsub.3.ronn 62 | nnxx::this_thread(3) this_thread.3.ronn 63 | nanomsgxx(7) ../nanomsgxx.7.ronn 64 | 65 | # external man pages 66 | nanomsg(7) http://nanomsg.org/v0.3/nanomsg.7.html 67 | -------------------------------------------------------------------------------- /doc/nnxx/message.3.ronn: -------------------------------------------------------------------------------- 1 | nnxx::message(3) -- Messages 2 | ============================ 3 | -------------------------------------------------------------------------------- /doc/nnxx/this_thread.3.ronn: -------------------------------------------------------------------------------- 1 | nnxx::this_thread(3) -- namespace for local thread related functions 2 | ==================================================================== 3 | 4 | 5 | ## SEE ALSO 6 | 7 | nnxx(3) 8 | nanomsgxx(7) 9 | 10 | ## AUTHORS 11 | 12 | Achille Roussel 13 | -------------------------------------------------------------------------------- /doc/wscript: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | # 4 | # Nanomsgxx doc build script. 5 | from waflib.Task import Task 6 | import os 7 | 8 | class ronn(Task): 9 | 10 | def make_ronn_command(self): 11 | cmd = [ 12 | 'RONN_STYLE=' + self.env.basename, 13 | 'ronn', 14 | '--organization', "'achille.roussel@gmail.com'", 15 | '--manual', 'nanomsgxx', 16 | self.inputs[0].abspath(), 17 | ] 18 | if self.env.docstyle == 'dark': 19 | cmd += ['--style', 'dark,nnxx,highlight-dark'] 20 | else: 21 | cmd += ['--style', 'nnxx,highlight-light'] 22 | return cmd 23 | 24 | def make_mv_command(self): 25 | return [ 26 | 'mv', 27 | self.outputs[0].abspath(), 28 | self.outputs[0].abspath() + '.tmp', 29 | ] 30 | 31 | def make_colorsyntax_command(self): 32 | return [ 33 | os.path.join(self.env.basename, 'colorsyntax'), 34 | '-s', 35 | 'monokai', 36 | '<', 37 | self.outputs[0].abspath() + '.tmp', 38 | '>', 39 | self.outputs[0].abspath(), 40 | ] 41 | 42 | def make_rm_command(self): 43 | return [ 44 | 'rm', 45 | '-f', 46 | self.outputs[0].abspath() + '.tmp', 47 | ] 48 | 49 | def make_command(self): 50 | return \ 51 | self.make_ronn_command() + ['&&'] + \ 52 | self.make_mv_command() + ['&&'] + \ 53 | self.make_colorsyntax_command() + ['&&'] + \ 54 | self.make_rm_command() 55 | 56 | def run(self): 57 | return self.exec_command(' '.join(self.make_command())) 58 | 59 | class gzip(Task): 60 | 61 | def run(self): 62 | return self.exec_command('gzip -c %s > %s' % ( 63 | self.inputs[0].abspath(), 64 | self.outputs[0].abspath(), 65 | )) 66 | 67 | def relative_parent_path(waf, file_node): 68 | return file_node.parent.abspath()[len(waf.path.abspath()):].lstrip('/') 69 | 70 | def html_output_file(waf, input_file): 71 | name = input_file.name.replace('.ronn', '.html') 72 | path = relative_parent_path(waf, input_file) 73 | return waf.path.make_node(os.path.join(path, name)) 74 | 75 | def roff_output_file(waf, input_file): 76 | name = input_file.name.replace('.ronn', '') 77 | path = relative_parent_path(waf, input_file) 78 | return waf.path.make_node(os.path.join(path, name)) 79 | 80 | def gzip_output_file(waf, input_file): 81 | name = input_file.name + '.gz' 82 | path = relative_parent_path(waf, input_file) 83 | return waf.path.make_node(os.path.join(path, name)) 84 | 85 | def gzip_install_file(waf, gzip_file): 86 | name = gzip_file.name 87 | path = relative_parent_path(waf, gzip_file) 88 | symbol, section, _ = name.split('.') 89 | if len(path) == 0: 90 | where = name 91 | elif path == 'nnxx': 92 | where = 'nnxx::' + name 93 | else: 94 | where = 'nanomsgxx-' + name 95 | return os.path.join('man' + section, where) 96 | 97 | def build(waf): 98 | waf.env.basename = waf.path.abspath() 99 | 100 | wscript = waf.path.ant_glob('wscript') 101 | colorsyntax = waf.path.ant_glob('colorsyntax') 102 | css_files = waf.path.ant_glob('**/*.css') 103 | idx_files = waf.path.ant_glob('**/index.txt') 104 | html_files = [] 105 | roff_files = [] 106 | gzip_files = [] 107 | 108 | for input_file in waf.path.ant_glob('**/*.ronn'): 109 | html_file = html_output_file(waf, input_file) 110 | html_files.append(html_file) 111 | 112 | roff_file = roff_output_file(waf, input_file) 113 | roff_files.append(roff_file) 114 | 115 | ronn_task = ronn(env=waf.env) 116 | ronn_task.set_inputs([input_file] + css_files + idx_files + colorsyntax + wscript) 117 | ronn_task.set_outputs([html_file, roff_file]) 118 | waf.add_to_group(ronn_task) 119 | 120 | gzip_file = gzip_output_file(waf, roff_file) 121 | gzip_task = gzip(env=waf.env) 122 | gzip_task.set_inputs([roff_file]) 123 | gzip_task.set_outputs([gzip_file]) 124 | gzip_files.append(gzip_file) 125 | waf.add_to_group(gzip_task) 126 | 127 | if waf.env.install_html_path: 128 | for hf in html_files: 129 | waf.install_as(os.path.join(waf.env.install_html_path, relative_parent_path(waf, hf), hf.name), hf) 130 | 131 | if waf.env.install_man_path: 132 | for gf in gzip_files: 133 | waf.install_as(os.path.join(waf.env.install_man_path, gzip_install_file(waf, gf)), gf) 134 | 135 | def configure(waf): 136 | assert waf.options.docstyle in ('dark', 'light') 137 | waf.load('python') 138 | waf.find_program('cat') 139 | waf.find_program('gzip') 140 | waf.find_program('ronn') 141 | waf.check_python_version((2,6,0)) 142 | waf.check_python_module('bs4') 143 | waf.check_python_module('pygments') 144 | waf.env.docstyle = waf.options.docstyle 145 | waf.env.install_html_path = waf.options.install_html_path 146 | waf.env.install_man_path = waf.options.install_man_path 147 | 148 | def options(waf): 149 | waf.add_option('--docstyle', nargs=1, default='dark', help='the doc style (dark or light)') 150 | waf.add_option('--install-html-path', nargs=1, default='/usr/local/share/doc/nanomsgxx', help='where to install html doc') 151 | waf.add_option('--install-man-path', nargs=1, default='/usr/local/share/man', help='where to install man pages') 152 | -------------------------------------------------------------------------------- /libnnxx.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | libdir=@libdir@ 3 | includedir=${prefix}/include 4 | 5 | Name: Nanomsgxx 6 | Description: Nanomsg binding for C++11 7 | URL: https://github.com/achille-roussel/nanomsgxx 8 | Version: 0.1 9 | Requires: libnanomsg 10 | Libs: -L${libdir} -lnnxx 11 | Cflags: -I${includedir} 12 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(nnxx) 2 | 3 | find_package(nanomsg CONFIG REQUIRED) 4 | 5 | IF(!nanomsg_FOUND) 6 | IF (WIN32) 7 | # This is not advanced yet, as it does not work for custom install locations. 8 | # The general directory, however, is found by `find_package`. 9 | # --> Throw an error, if nanomsg cannot be found 10 | message(FATAL_ERROR "nanomsg library is required, but not found in standard location.") 11 | ELSE() 12 | # on UNIX platforms pkg_config can be used as fallback solution 13 | find_package(PkgConfig REQUIRED) 14 | pkg_check_modules(nanomsg REQUIRED nanomsg) 15 | ENDIF() 16 | ENDIF() 17 | 18 | 19 | set(NANOMSG_SRCS ./nanomsg/ext/nnxx_ext.c) 20 | 21 | set(NNXX_SRCS ./nnxx/error.cpp 22 | ./nnxx/message.cpp 23 | ./nnxx/message_control.cpp 24 | ./nnxx/message_istream.cpp 25 | ./nnxx/message_iterator.cpp 26 | ./nnxx/message_ostream.cpp 27 | ./nnxx/message_streambuf.cpp 28 | ./nnxx/nn.cpp 29 | ./nnxx/poll.cpp 30 | ./nnxx/pubsub.cpp 31 | ./nnxx/reqrep.cpp 32 | ./nnxx/socket.cpp 33 | ./nnxx/survey.cpp 34 | ./nnxx/tcp.cpp 35 | ./nnxx/timeout.cpp) 36 | 37 | set(NNXX_HDRS ./nanomsg/ext/nnxx_ext.h 38 | ./nnxx/bus.h 39 | ./nnxx/chrono.h 40 | ./nnxx/error.h 41 | ./nnxx/inproc.h 42 | ./nnxx/ipc.h 43 | ./nnxx/message.h 44 | ./nnxx/message_control.h 45 | ./nnxx/message_istream.h 46 | ./nnxx/message_iterator.h 47 | ./nnxx/message_ostream.h 48 | ./nnxx/message_streambuf.h 49 | ./nnxx/nn.h 50 | ./nnxx/pair.h 51 | ./nnxx/pipeline.h 52 | ./nnxx/poll.h 53 | ./nnxx/pubsub.h 54 | ./nnxx/reqrep.h 55 | ./nnxx/socket.h 56 | ./nnxx/survey.h 57 | ./nnxx/tcp.h 58 | ./nnxx/timeout.h 59 | ./nnxx/unittest.h) 60 | 61 | add_library(${PROJECT_NAME} ${NANOMSG_SRCS} ${NNXX_SRCS}) 62 | add_library(lib::nnxx ALIAS ${PROJECT_NAME}) 63 | target_include_directories(${PROJECT_NAME} PUBLIC "." ${NANOMSG_INCLUDE_DIRS}) 64 | target_link_libraries(${PROJECT_NAME} PUBLIC nanomsg) 65 | 66 | install(TARGETS ${PROJECT_NAME} DESTINATION lib) 67 | install(FILES ${NNXX_HDRS} DESTINATION include/nnxx) -------------------------------------------------------------------------------- /src/LICENSE: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | -------------------------------------------------------------------------------- /src/README: -------------------------------------------------------------------------------- 1 | Source folder for nanomsgxx: 2 | - nnxx: subfolder containing all source files 3 | - ext: C extensions to the nanomsg library 4 | -------------------------------------------------------------------------------- /src/nanomsg/ext/nnxx_ext.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | static size_t nn_memhash (const char *s, size_t n) 32 | { 33 | size_t h = 0; 34 | size_t i; 35 | 36 | for (i = 0; i != n; ++i, ++s) { 37 | h = (*s) + (h << 6) + (h << 16) - h; 38 | } 39 | return h; 40 | } 41 | 42 | static int nn_check_raw_socket (int s) 43 | { 44 | size_t optlen; 45 | int optval; 46 | 47 | /* Making sure the socket domain is AF_SP_RAW. */ 48 | optlen = sizeof(optval); 49 | optval = 0; 50 | if (nn_getsockopt (s, NN_SOL_SOCKET, NN_DOMAIN, &optval, &optlen)) { 51 | return -1; 52 | } 53 | if (optval != AF_SP_RAW) { 54 | errno = ENOTSUP; 55 | return -1; 56 | } 57 | return 0; 58 | } 59 | 60 | void nn_msgctl_init (struct nn_msgctl *ctl) 61 | { 62 | memset (ctl, 0, sizeof(*ctl)); 63 | } 64 | 65 | void nn_msgctl_term (struct nn_msgctl *ctl) 66 | { 67 | if (ctl->ctl_base) { 68 | nn_freemsg (ctl->ctl_base); 69 | } 70 | } 71 | 72 | int nn_msgctl_copy (struct nn_msgctl *to, 73 | const struct nn_msgctl *from) 74 | { 75 | void * control = NULL; 76 | 77 | /* Copy control base if it was allocated. */ 78 | if (from->ctl_base) { 79 | control = nn_allocmsg (from->ctl_len, 0); 80 | if (!control) { 81 | errno = ENOMEM; 82 | return -1; 83 | } 84 | memmove (control, from->ctl_base, from->ctl_len); 85 | } 86 | 87 | /* Copy to destination object. */ 88 | to->ctl_base = control; 89 | to->ctl_len = from->ctl_len; 90 | return 0; 91 | } 92 | 93 | int nn_msgctl_cmp (const struct nn_msgctl *ctl1, 94 | const struct nn_msgctl *ctl2) 95 | { 96 | int k; 97 | int n; 98 | 99 | /* Compare type of control buffers. */ 100 | if (!ctl1->ctl_base && !ctl2->ctl_base) { 101 | return 0; 102 | } 103 | if (!ctl1->ctl_base) { 104 | return -1; 105 | } 106 | if (!ctl2->ctl_base) { 107 | return 1; 108 | } 109 | 110 | /* Compare content of control buffers. */ 111 | n = ctl1->ctl_len < ctl2->ctl_len ? ctl1->ctl_len : ctl2->ctl_len; 112 | k = memcmp (ctl1->ctl_base, ctl2->ctl_base, n); 113 | if (k != 0) { 114 | return k; 115 | } 116 | return ctl1->ctl_len - ctl2->ctl_len; 117 | } 118 | 119 | size_t nn_msgctl_hash (const struct nn_msgctl *ctl) 120 | { 121 | return ctl->ctl_base == NULL 122 | ? 0 123 | : nn_memhash ((const char *) ctl->ctl_base, ctl->ctl_len); 124 | } 125 | 126 | int nn_recvfrom (int s, void *buf, size_t buflen, int flags, 127 | struct nn_msgctl *ctl) 128 | { 129 | struct nn_iovec vec [1]; 130 | struct nn_msghdr msg; 131 | void * control; 132 | int n; 133 | 134 | /* If the caller is not interested in getting the sender's ctless we simply 135 | delegate to nn_recv. */ 136 | if (!ctl) { 137 | return nn_recv (s, buf, buflen, flags); 138 | } 139 | 140 | /* Making sure the operation is supported. */ 141 | if (nn_check_raw_socket (s)) { 142 | return -1; 143 | } 144 | 145 | /* Receiving a message. */ 146 | nn_msgctl_init (ctl); 147 | vec [0].iov_base = buf; 148 | vec [0].iov_len = buflen; 149 | memset (&msg, 0, sizeof(msg)); 150 | msg.msg_iov = vec; 151 | msg.msg_iovlen = 1; 152 | msg.msg_control = &control; 153 | msg.msg_controllen = NN_MSG; 154 | n = nn_recvmsg (s, &msg, flags); 155 | if (n < 0) { 156 | return -1; 157 | } 158 | 159 | /* Set control object. */ 160 | ctl->ctl_base = control; 161 | ctl->ctl_len = msg.msg_controllen; 162 | return n; 163 | } 164 | 165 | int nn_sendto (int s, const void *buf, size_t buflen, int flags, 166 | const struct nn_msgctl *ctl) 167 | { 168 | struct nn_iovec vec [1]; 169 | struct nn_msghdr msg; 170 | void * control; 171 | 172 | /* If the caller doesn't specify a receiver ctless we simply delegate to 173 | nn_send. */ 174 | if (!ctl) { 175 | return nn_send (s, buf, buflen, flags); 176 | } 177 | 178 | /* Make sure the operation is supported. */ 179 | if (nn_check_raw_socket (s)) { 180 | return -1; 181 | } 182 | 183 | /* Sending the message. */ 184 | control = ctl->ctl_base; 185 | vec [0].iov_base = (void *) buf; 186 | vec [0].iov_len = buflen; 187 | memset (&msg, 0, sizeof(msg)); 188 | msg.msg_iov = vec; 189 | msg.msg_iovlen = 1; 190 | msg.msg_control = &control; 191 | msg.msg_controllen = NN_MSG; 192 | return nn_sendmsg (s, &msg, flags); 193 | } 194 | -------------------------------------------------------------------------------- /src/nanomsg/ext/nnxx_ext.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_NN_EXT_H 26 | #define NNXX_NN_EXT_H 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | #include 32 | #include 33 | 34 | struct nn_msgctl { 35 | void * ctl_base; 36 | size_t ctl_len; 37 | }; 38 | 39 | void nn_msgctl_init (struct nn_msgctl *ctl); 40 | 41 | void nn_msgctl_term (struct nn_msgctl *ctl); 42 | 43 | int nn_msgctl_copy (struct nn_msgctl *to, const struct nn_msgctl *from); 44 | 45 | int nn_msgctl_cmp (const struct nn_msgctl *ctl1, const struct nn_msgctl *ctl2); 46 | 47 | size_t nn_msgctl_hash (const struct nn_msgctl *ctl); 48 | 49 | int nn_recvfrom (int s, void *buf, size_t buflen, int flags, struct nn_msgctl *ctl); 50 | 51 | int nn_sendto (int s, const void *buf, size_t buflen, int flags, const struct nn_msgctl *ctl); 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | #endif /* NNXX_NN_EXT_H */ 57 | 58 | -------------------------------------------------------------------------------- /src/nanomsg/ext/wscript: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | # 4 | # Extensions build script. 5 | from copy import copy 6 | 7 | def configure(waf): 8 | pass 9 | 10 | def build(waf): 11 | conf = copy(waf.env.C_CONF_KWARGS) 12 | conf['cflags'] += ['-fPIC'] 13 | conf.update({ 14 | 'source': waf.path.ant_glob('*.c'), 15 | 'target': 'nanomsgext', 16 | }) 17 | waf.env.nnext = waf.stlib(**conf) 18 | waf.env.nnext.post() 19 | waf.install_files('${PREFIX}/include/nanomsg/ext', waf.path.ant_glob('*.h')) 20 | -------------------------------------------------------------------------------- /src/nnxx/README: -------------------------------------------------------------------------------- 1 | Here are all the source files for nanomsgxx, the file names match the ones of 2 | nanomsg, for example C++ ports of symbols in nanomsg/nn.h will be found in 3 | nnxx/nn.h, etc... 4 | This C++ port also add some more abstractions that take advantage of C++11 new 5 | features and make the code easier to use, these are available in extra header 6 | files that don't match any in the C nanomsg API. 7 | -------------------------------------------------------------------------------- /src/nnxx/bus.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_BUS_H 26 | #define NNXX_BUS_H 27 | 28 | #include 29 | 30 | namespace nnxx { 31 | 32 | enum { 33 | BUS = NN_BUS, 34 | }; 35 | 36 | } 37 | 38 | #endif // NNXX_BUS_H 39 | -------------------------------------------------------------------------------- /src/nnxx/chrono.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_CHRONO_H 26 | #define NNXX_CHRONO_H 27 | 28 | #include 29 | 30 | namespace nnxx { 31 | 32 | typedef std::chrono::system_clock clock; 33 | typedef clock::duration duration; 34 | typedef clock::time_point time_point; 35 | 36 | using std::chrono::hours; 37 | using std::chrono::minutes; 38 | using std::chrono::seconds; 39 | using std::chrono::milliseconds; 40 | using std::chrono::microseconds; 41 | using std::chrono::nanoseconds; 42 | 43 | } 44 | 45 | #endif // NNXX_CHRONO_H 46 | -------------------------------------------------------------------------------- /src/nnxx/error.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | using namespace std; 29 | 30 | namespace nnxx { 31 | 32 | const char *term_error::what() const noexcept 33 | { return strerror(ETERM); } 34 | 35 | timeout_error::timeout_error(): 36 | system_error(make_error_code(errc(ETIMEDOUT)), strerror(ETIMEDOUT)) 37 | { } 38 | 39 | signal_error::signal_error(): 40 | system_error(make_error_code(errc(EINTR)), strerror(EINTR)) 41 | { } 42 | 43 | namespace this_thread { 44 | 45 | int get_errno() noexcept 46 | { return nn_errno(); } 47 | 48 | errc get_errc() noexcept 49 | { return errc(get_errno()); } 50 | 51 | } 52 | 53 | const char *strerror() noexcept 54 | { return strerror(this_thread::get_errno()); } 55 | 56 | const char *strerror(int code) noexcept 57 | { return nn_strerror(code); } 58 | 59 | void throw_error() 60 | { throw_error(this_thread::get_errno()); } 61 | 62 | void throw_error(int code) 63 | { 64 | switch (code) { 65 | case ENOMEM: 66 | throw bad_alloc{ }; 67 | 68 | case ETERM: 69 | throw term_error{ }; 70 | 71 | case ETIMEDOUT: 72 | throw timeout_error{ }; 73 | 74 | case EINTR: 75 | throw signal_error{ }; 76 | 77 | default: 78 | throw system_error{ make_error_code(errc(code)), strerror() }; 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/nnxx/error.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_EXCEPTION_H 26 | #define NNXX_EXCEPTION_H 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | namespace nnxx { 33 | using std::errc; 34 | 35 | class term_error : public std::exception { 36 | public: 37 | const char *what() const noexcept; 38 | }; 39 | 40 | class timeout_error : public std::system_error { 41 | public: 42 | timeout_error(); 43 | }; 44 | 45 | class signal_error : public std::system_error { 46 | public: 47 | signal_error(); 48 | }; 49 | 50 | namespace this_thread { 51 | int get_errno() noexcept; 52 | errc get_errc() noexcept; 53 | } 54 | 55 | const char *strerror() noexcept; 56 | const char *strerror(int code) noexcept; 57 | 58 | [[noreturn]] void throw_error(); 59 | [[noreturn]] void throw_error(int code); 60 | 61 | inline void *check_error(void *ptr) 62 | { 63 | if (ptr == nullptr) { 64 | throw_error(); 65 | } 66 | return ptr; 67 | } 68 | 69 | inline int check_error(int code) 70 | { 71 | if (code < 0) { 72 | throw_error(); 73 | } 74 | return code; 75 | } 76 | 77 | } 78 | 79 | #endif // NNXX_EXCEPTION_H 80 | -------------------------------------------------------------------------------- /src/nnxx/inproc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_INPROC_H 26 | #define NNXX_INPROC_H 27 | 28 | #include 29 | 30 | namespace nnxx { 31 | 32 | } 33 | 34 | #endif // NNXX_INPROC_H 35 | -------------------------------------------------------------------------------- /src/nnxx/ipc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_IPC_H 26 | #define NNXX_IPC_H 27 | 28 | #include 29 | 30 | namespace nnxx { 31 | 32 | } 33 | 34 | #endif // NNXX_IPC_H 35 | -------------------------------------------------------------------------------- /src/nnxx/message: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_MESSAGE 26 | #define NNXX_MESSAGE 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #endif // NNXX_MESSAGE 35 | -------------------------------------------------------------------------------- /src/nnxx/message.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | namespace nnxx { 32 | 33 | message::message() noexcept: 34 | m_data(nullptr), 35 | m_size(0) 36 | { } 37 | 38 | message::message(size_type size, int type): 39 | m_data(nn_allocmsg(size, type)), 40 | m_size(size) 41 | { check_error(m_data); } 42 | 43 | message::message(pointer data, size_type size) noexcept: 44 | m_data(data), 45 | m_size(size) 46 | { } 47 | 48 | message::message(message &&m) noexcept: 49 | m_data(m.m_data), 50 | m_size(m.m_size) 51 | { m.detach(); } 52 | 53 | message::~message() 54 | { 55 | if (m_data != nullptr) { 56 | #ifdef NDEBUG 57 | nn_freemsg(m_data); 58 | #else 59 | if (nn_freemsg(m_data) != 0) { 60 | std::fprintf(stderr, "warning: nn_freemsg: %s\n", strerror()); 61 | } 62 | #endif 63 | } 64 | } 65 | 66 | message &message::operator=(message &&m) noexcept 67 | { 68 | m.swap(*this); 69 | return *this; 70 | } 71 | 72 | void message::resize(size_type size) 73 | { 74 | if (size != m_size) { 75 | m_data = check_error(nn_reallocmsg(m_data, size)); 76 | m_size = size; 77 | } 78 | } 79 | 80 | void message::swap(message &m) noexcept 81 | { 82 | using std::swap; 83 | swap(m_data, m.m_data); 84 | swap(m_size, m.m_size); 85 | } 86 | 87 | void message::detach() noexcept 88 | { 89 | m_data = nullptr; 90 | m_size = 0; 91 | } 92 | 93 | bool message::empty() const noexcept 94 | { return m_size == 0; } 95 | 96 | message::operator bool () const noexcept 97 | { return !empty(); } 98 | 99 | message::pointer message::data() noexcept 100 | { return m_data; } 101 | 102 | message::const_pointer message::data() const noexcept 103 | { return m_data; } 104 | 105 | message::size_type message::size() const noexcept 106 | { return m_size; } 107 | 108 | message::iterator message::begin() noexcept 109 | { return reinterpret_cast(m_data); } 110 | 111 | message::iterator message::end() noexcept 112 | { return reinterpret_cast(m_data) + m_size; } 113 | 114 | message::const_iterator message::begin() const noexcept 115 | { return reinterpret_cast(m_data); } 116 | 117 | message::const_iterator message::end() const noexcept 118 | { return reinterpret_cast(m_data) + m_size; } 119 | 120 | message::size_type copy(const message &from, message &to) noexcept 121 | { return copy(from, to, 0, 0, std::min(from.size(), to.size())); } 122 | 123 | message::size_type copy(const message &from, 124 | message &to, 125 | message::size_type from_offset, 126 | message::size_type to_offset, 127 | message::size_type size) noexcept 128 | { 129 | using std::copy; 130 | using std::min; 131 | const message::size_type n1 = from.size(); 132 | const message::size_type n2 = to.size(); 133 | 134 | if ((from_offset >= n1) || (to_offset >= n2)) { 135 | return 0; 136 | } 137 | 138 | size = min(size, n1 - from_offset); 139 | size = min(size, n2 - to_offset); 140 | 141 | if (size == 0) { 142 | return 0; 143 | } 144 | 145 | copy(reinterpret_cast(from.data()) + from_offset, 146 | reinterpret_cast(from.data()) + from_offset + size, 147 | reinterpret_cast(to.data())); 148 | return size; 149 | } 150 | 151 | message copy(const message &msg, message::size_type size, int type) 152 | { 153 | using std::max; 154 | 155 | if ((size = max(size, msg.size())) == 0) { 156 | return { }; 157 | } 158 | 159 | message new_msg { size, type }; 160 | copy(msg, new_msg); 161 | return new_msg; 162 | } 163 | 164 | message make_message_from(message::pointer data, message::size_type size) noexcept 165 | { return message{ data, size }; } 166 | 167 | void swap(message &m1, message &m2) noexcept 168 | { m1.swap(m2); } 169 | 170 | std::string to_string(const message &msg) 171 | { return { msg.begin(), msg.end() }; } 172 | 173 | template std::ostream &operator<<(std::ostream &, const message &); 174 | 175 | } 176 | -------------------------------------------------------------------------------- /src/nnxx/message.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_MESSAGE_H 26 | #define NNXX_MESSAGE_H 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | namespace nnxx { 34 | 35 | class message { 36 | public: 37 | typedef void const * const_pointer; 38 | typedef void * pointer; 39 | typedef char * iterator; 40 | typedef char const * const_iterator; 41 | typedef size_t size_type; 42 | 43 | explicit message(size_type size, int type = 0); 44 | message() noexcept; 45 | message(message &&m) noexcept; 46 | message(message const &) = delete; 47 | 48 | ~message(); 49 | 50 | message &operator=(message &&m) noexcept; 51 | message &operator=(message const &) = delete; 52 | 53 | operator bool () const noexcept; 54 | 55 | void resize(size_type size); 56 | 57 | void swap(message &m) noexcept; 58 | 59 | void detach() noexcept; 60 | 61 | pointer data() noexcept; 62 | 63 | const_pointer data() const noexcept; 64 | 65 | size_type size() const noexcept; 66 | 67 | bool empty() const noexcept; 68 | 69 | iterator begin() noexcept; 70 | iterator end() noexcept; 71 | 72 | const_iterator begin() const noexcept; 73 | const_iterator end() const noexcept; 74 | 75 | friend message make_message_from(pointer data, size_type size) noexcept; 76 | 77 | private: 78 | pointer m_data; 79 | size_type m_size; 80 | 81 | explicit message(pointer, size_type) noexcept; 82 | }; 83 | 84 | void swap(message &m1, message &m2) noexcept; 85 | 86 | message make_message_from(message::pointer data, message::size_type size) noexcept; 87 | 88 | message copy(const message &msg, message::size_type size = 0, int type = 0); 89 | 90 | message::size_type copy(const message &from, message &to) noexcept; 91 | message::size_type copy(const message &from, 92 | message &to, 93 | message::size_type from_offset, 94 | message::size_type to_offset, 95 | message::size_type size) noexcept; 96 | 97 | std::string to_string(const message &msg); 98 | 99 | template < typename Iterator > 100 | message make_message(Iterator first, Iterator last) 101 | { 102 | typedef typename std::iterator_traits traits; 103 | typedef typename traits::value_type type; 104 | typedef typename traits::value_type * pointer; 105 | using std::copy; 106 | using std::distance; 107 | message msg (distance(first, last) * sizeof(type)); 108 | copy(first, 109 | last, 110 | reinterpret_cast(msg.data())); 111 | return msg; 112 | } 113 | 114 | template < typename Iterable > 115 | message make_message(Iterable &&obj) 116 | { 117 | using std::begin; 118 | using std::end; 119 | return make_message(begin(obj), end(obj)); 120 | } 121 | 122 | template < typename Char, typename Traits > 123 | std::basic_ostream & 124 | operator <<(std::basic_ostream &out, const message &msg) 125 | { 126 | const auto data = static_cast(msg.data()); 127 | const auto size = msg.size() / sizeof(Char); 128 | out.write(data, size); 129 | return out; 130 | } 131 | 132 | extern template std::ostream &operator<<(std::ostream &, const message &); 133 | 134 | } 135 | 136 | #include 137 | #endif // NNXX_MESSAGE_H 138 | -------------------------------------------------------------------------------- /src/nnxx/message_control.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | namespace nnxx { 30 | 31 | message_control::message_control() noexcept 32 | { nn_msgctl_init(this); } 33 | 34 | message_control::message_control(message_control &&a) noexcept: 35 | nn_msgctl(a) 36 | { a.detach(); } 37 | 38 | message_control::message_control(const message_control &a) 39 | { check_error(nn_msgctl_copy(this, &a)); } 40 | 41 | message_control::~message_control() 42 | { nn_msgctl_term(this); } 43 | 44 | message_control::operator bool () const noexcept 45 | { return this->ctl_base != nullptr; } 46 | 47 | message_control &message_control::operator=(message_control &&a) noexcept 48 | { 49 | a.swap(*this); 50 | return *this; 51 | } 52 | 53 | message_control &message_control::operator=(const message_control &a) 54 | { 55 | message_control{ a }.swap(*this); 56 | return *this; 57 | } 58 | 59 | void message_control::swap(message_control &a) noexcept 60 | { 61 | using std::swap; 62 | swap(static_cast(*this), 63 | static_cast(a)); 64 | } 65 | 66 | void message_control::clear() noexcept 67 | { 68 | nn_msgctl_term(this); 69 | nn_msgctl_init(this); 70 | } 71 | 72 | void message_control::detach() noexcept 73 | { nn_msgctl_init(this); } 74 | 75 | size_t message_control::hash() const noexcept 76 | { return nn_msgctl_hash(this); } 77 | 78 | void swap(message_control &a1, message_control &a2) noexcept 79 | { a1.swap(a2); } 80 | 81 | int compare(const message_control &a1, const message_control &a2) noexcept 82 | { return nn_msgctl_cmp(&a1, &a2); } 83 | 84 | bool operator==(const message_control &a1, const message_control &a2) noexcept 85 | { return compare(a1, a2) == 0; } 86 | 87 | bool operator!=(const message_control &a1, const message_control &a2) noexcept 88 | { return compare(a1, a2) != 0; } 89 | 90 | bool operator<(const message_control &a1, const message_control &a2) noexcept 91 | { return compare(a1, a2) < 0; } 92 | 93 | bool operator>(const message_control &a1, const message_control &a2) noexcept 94 | { return compare(a1, a2) > 0; } 95 | 96 | bool operator<=(const message_control &a1, const message_control &a2) noexcept 97 | { return compare(a1, a2) <= 0; } 98 | 99 | bool operator>=(const message_control &a1, const message_control &a2) noexcept 100 | { return compare(a1, a2) >= 0; } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/nnxx/message_control.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_MESSAGE_CONTROL_H 26 | #define NNXX_MESSAGE_CONTROL_H 27 | 28 | #include 29 | 30 | namespace nnxx { 31 | 32 | class message_control : public nn_msgctl { 33 | public: 34 | message_control() noexcept; 35 | message_control(message_control &&a) noexcept; 36 | message_control(message_control const &a); 37 | 38 | ~message_control(); 39 | 40 | operator bool () const noexcept; 41 | message_control &operator=(message_control &&a) noexcept; 42 | message_control &operator=(message_control const &a); 43 | 44 | void swap(message_control &a) noexcept; 45 | void clear() noexcept; 46 | void detach() noexcept; 47 | size_t hash() const noexcept; 48 | }; 49 | 50 | void swap(message_control &a1, message_control &a2) noexcept; 51 | 52 | int compare(const message_control &a1, const message_control &a2) noexcept; 53 | 54 | bool operator==(const message_control &a1, const message_control &a2) noexcept; 55 | bool operator!=(const message_control &a1, const message_control &a2) noexcept; 56 | bool operator<(const message_control &a1, const message_control &a2) noexcept; 57 | bool operator>(const message_control &a1, const message_control &a2) noexcept; 58 | bool operator<=(const message_control &a1, const message_control &a2) noexcept; 59 | bool operator>=(const message_control &a1, const message_control &a2) noexcept; 60 | 61 | struct message_control_hash { 62 | size_t operator()(const message_control &ctl) const noexcept 63 | { return ctl.hash(); } 64 | }; 65 | 66 | } 67 | 68 | #ifndef NNXX_NO_STD_EXT 69 | namespace std { 70 | 71 | template < > 72 | struct hash : public nnxx::message_control_hash 73 | { }; 74 | 75 | } 76 | #endif // NNXX_NO_STD_EXT 77 | #endif // NNXX_MESSAGE_CONTROL_H 78 | -------------------------------------------------------------------------------- /src/nnxx/message_istream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | namespace nnxx { 29 | 30 | template class basic_message_istream; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/nnxx/message_istream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_MESSAGE_ISTREAM_H 26 | #define NNXX_MESSAGE_ISTREAM_H 27 | 28 | #include 29 | #include 30 | 31 | namespace nnxx { 32 | 33 | template < typename Char, typename Traits = std::char_traits > 34 | class basic_message_istream : public std::basic_istream { 35 | typedef typename std::basic_istream base_type; 36 | typedef basic_message_streambuf message_streambuf; 37 | public: 38 | typedef typename base_type::char_type char_type; 39 | typedef typename base_type::int_type int_type; 40 | typedef typename base_type::pos_type pos_type; 41 | typedef typename base_type::off_type off_type; 42 | typedef typename base_type::traits_type traits_type; 43 | typedef typename message_streambuf::size_type size_type; 44 | 45 | explicit basic_message_istream() noexcept; 46 | explicit basic_message_istream(message &&msg) noexcept; 47 | basic_message_istream(basic_message_istream const &) = delete; 48 | ~basic_message_istream(); 49 | basic_message_istream &operator=(basic_message_istream const &&) = delete; 50 | 51 | basic_message_istream(basic_message_istream &&m) noexcept; 52 | basic_message_istream &operator=(basic_message_istream &&m) noexcept; 53 | void swap(basic_message_istream &m) noexcept; 54 | 55 | void msg(message &&m) noexcept; 56 | 57 | private: 58 | message_streambuf m_buffer; 59 | }; 60 | 61 | template < typename Char, typename Traits > 62 | void swap(basic_message_istream &m1, 63 | basic_message_istream &m2) noexcept 64 | { m1.swap(m2); } 65 | 66 | typedef basic_message_istream message_istream; 67 | 68 | extern template class basic_message_istream; 69 | 70 | } 71 | 72 | #endif // NNXX_MESSAGE_ISTREAM_H 73 | -------------------------------------------------------------------------------- /src/nnxx/message_istream.hpp: -------------------------------------------------------------------------------- 1 | #ifndef NNXX_MESSAGE_ISTREAM_HPP 2 | #define NNXX_MESSAGE_ISTREAM_HPP 3 | 4 | #include 5 | 6 | namespace nnxx { 7 | 8 | template < typename Char, typename Traits > 9 | basic_message_istream:: 10 | basic_message_istream() noexcept: 11 | base_type(nullptr), 12 | m_buffer() 13 | { this->rdbuf(&m_buffer); } 14 | 15 | template < typename Char, typename Traits > 16 | basic_message_istream:: 17 | basic_message_istream(message &&msg) noexcept: 18 | base_type(nullptr), 19 | m_buffer(std::move(msg)) 20 | { this->rdbuf(&m_buffer); } 21 | 22 | template < typename Char, typename Traits > 23 | basic_message_istream:: 24 | ~basic_message_istream() 25 | { } 26 | 27 | template < typename Char, typename Traits > 28 | void basic_message_istream::msg(message &&m) noexcept 29 | { m_buffer.msg(std::move(m)); } 30 | 31 | template < typename Char, typename Traits > 32 | basic_message_istream:: 33 | basic_message_istream(basic_message_istream &&m) noexcept: 34 | base_type(std::move(m)), 35 | m_buffer(std::move(m.m_buffer)) 36 | { 37 | this->rdbuf(&m_buffer); 38 | m.rdbuf(&(m.m_buffer)); 39 | } 40 | 41 | template < typename Char, typename Traits > 42 | basic_message_istream & 43 | basic_message_istream:: 44 | operator=(basic_message_istream &&m) noexcept 45 | { 46 | m.swap(*this); 47 | return *this; 48 | } 49 | 50 | template < typename Char, typename Traits > 51 | void basic_message_istream:: 52 | swap(basic_message_istream &m) noexcept 53 | { 54 | using std::swap; 55 | base_type::swap(m); 56 | swap(m_buffer, m.m_buffer); 57 | } 58 | 59 | } 60 | 61 | #endif // NNXX_MESSAGE_ISTREAM_HPP 62 | -------------------------------------------------------------------------------- /src/nnxx/message_iterator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | namespace nnxx { 30 | 31 | message_iterator::message_iterator() noexcept: 32 | m_socket(nullptr), 33 | m_message() 34 | { } 35 | 36 | message_iterator::message_iterator(socket &s): 37 | m_socket(&s), 38 | m_message(s.recv()) 39 | { } 40 | 41 | bool message_iterator::operator==(const message_iterator &it) const noexcept 42 | { return m_socket == it.m_socket; } 43 | 44 | bool message_iterator::operator!=(const message_iterator &it) const noexcept 45 | { return m_socket != it.m_socket; } 46 | 47 | message_iterator::pointer message_iterator::operator->() noexcept 48 | { return &m_message; } 49 | 50 | message_iterator::reference message_iterator::operator*() noexcept 51 | { return m_message; } 52 | 53 | message_iterator &message_iterator::operator++() 54 | { 55 | try { 56 | m_message = m_socket->recv(); 57 | } 58 | catch (const timeout_error &) { 59 | m_socket = nullptr; 60 | } 61 | catch (...) { 62 | m_socket = nullptr; 63 | throw; 64 | } 65 | return *this; 66 | } 67 | 68 | message_iterator message_iterator::operator++(int) 69 | { 70 | message_iterator tmp; 71 | tmp.m_socket = m_socket; 72 | tmp.m_message = std::move(m_message); 73 | ++(*this); 74 | return tmp; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/nnxx/message_iterator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_MESSAGE_ITERATOR_H 26 | #define NNXX_MESSAGE_ITERATOR_H 27 | 28 | #include 29 | 30 | namespace nnxx { 31 | 32 | class socket; 33 | 34 | class message_iterator : 35 | public std::iterator { 40 | public: 41 | typedef typename std::input_iterator_tag iterator_category; 42 | typedef typename std::ptrdiff_t difference_type; 43 | typedef message value_type; 44 | typedef message * pointer; 45 | typedef message & reference; 46 | 47 | message_iterator() noexcept; 48 | message_iterator(socket &s); 49 | message_iterator(message_iterator &&) = default; 50 | message_iterator(message_iterator const &) = default; 51 | 52 | message_iterator &operator=(message_iterator &&) = default; 53 | message_iterator &operator=(message_iterator const &) = default; 54 | 55 | bool operator==(const message_iterator &it) const noexcept; 56 | bool operator!=(const message_iterator &it) const noexcept; 57 | 58 | pointer operator->() noexcept; 59 | reference operator *() noexcept; 60 | 61 | message_iterator &operator++(); 62 | message_iterator operator++(int); 63 | 64 | private: 65 | socket *m_socket; 66 | message m_message; 67 | }; 68 | 69 | } 70 | 71 | #endif // NNXX_MESSAGE_ITERATOR_H 72 | -------------------------------------------------------------------------------- /src/nnxx/message_ostream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | namespace nnxx { 29 | 30 | template class basic_message_ostream; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/nnxx/message_ostream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_MESSAGE_OSTREAM_H 26 | #define NNXX_MESSAGE_OSTREAM_H 27 | 28 | #include 29 | #include 30 | 31 | namespace nnxx { 32 | 33 | template < typename Char, typename Traits = std::char_traits > 34 | class basic_message_ostream : public std::basic_ostream { 35 | typedef typename std::basic_ostream base_type; 36 | typedef basic_message_streambuf message_streambuf; 37 | public: 38 | typedef typename base_type::char_type char_type; 39 | typedef typename base_type::int_type int_type; 40 | typedef typename base_type::pos_type pos_type; 41 | typedef typename base_type::off_type off_type; 42 | typedef typename base_type::traits_type traits_type; 43 | typedef typename message_streambuf::size_type size_type; 44 | 45 | explicit basic_message_ostream(size_type base_size = 1000) noexcept; 46 | explicit basic_message_ostream(message &&msg) noexcept; 47 | basic_message_ostream(basic_message_ostream const &) = delete; 48 | ~basic_message_ostream(); 49 | basic_message_ostream &operator=(basic_message_ostream const &) = delete; 50 | 51 | basic_message_ostream(basic_message_ostream &&m) noexcept; 52 | basic_message_ostream &operator=(basic_message_ostream &&m) noexcept; 53 | void swap(basic_message_ostream &m) noexcept; 54 | 55 | void msg(message &&m) noexcept; 56 | message msg(int type = 0); 57 | message move_msg(); 58 | 59 | private: 60 | message_streambuf m_buffer; 61 | }; 62 | 63 | template < typename Char, typename Traits > 64 | void swap(basic_message_ostream &m1, 65 | basic_message_ostream &m2) noexcept 66 | { m1.swap(m2); } 67 | 68 | typedef basic_message_ostream message_ostream; 69 | 70 | extern template class basic_message_ostream; 71 | 72 | } 73 | 74 | #endif // NNXX_MESSAGE_OSTREAM_H 75 | -------------------------------------------------------------------------------- /src/nnxx/message_ostream.hpp: -------------------------------------------------------------------------------- 1 | #ifndef NNXX_MESSAGE_OSTREAM_HPP 2 | #define NNXX_MESSAGE_OSTREAM_HPP 3 | 4 | #include 5 | 6 | namespace nnxx { 7 | 8 | template < typename Char, typename Traits > 9 | basic_message_ostream:: 10 | basic_message_ostream(size_type base_size) noexcept: 11 | base_type(nullptr), 12 | m_buffer(base_size) 13 | { this->rdbuf(&m_buffer); } 14 | 15 | template < typename Char, typename Traits > 16 | basic_message_ostream:: 17 | basic_message_ostream(message &&msg) noexcept: 18 | base_type(nullptr), 19 | m_buffer(std::move(msg)) 20 | { this->rdbuf(&m_buffer); } 21 | 22 | template < typename Char, typename Traits > 23 | basic_message_ostream:: 24 | ~basic_message_ostream() 25 | { } 26 | 27 | template < typename Char, typename Traits > 28 | void basic_message_ostream::msg(message &&m) noexcept 29 | { m_buffer.msg(std::move(m)); } 30 | 31 | template < typename Char, typename Traits > 32 | message basic_message_ostream::msg(int type) 33 | { return m_buffer.msg(type); } 34 | 35 | template < typename Char, typename Traits > 36 | message basic_message_ostream::move_msg() 37 | { return m_buffer.move_msg(); } 38 | 39 | template < typename Char, typename Traits > 40 | basic_message_ostream:: 41 | basic_message_ostream(basic_message_ostream &&m) noexcept: 42 | base_type(std::move(m)), 43 | m_buffer(std::move(m.m_buffer)) 44 | { 45 | this->rdbuf(&m_buffer); 46 | m.rdbuf(&(m.m_buffer)); 47 | } 48 | 49 | template < typename Char, typename Traits > 50 | basic_message_ostream & 51 | basic_message_ostream:: 52 | operator=(basic_message_ostream &&m) noexcept 53 | { 54 | m.swap(*this); 55 | return *this; 56 | } 57 | 58 | template < typename Char, typename Traits > 59 | void basic_message_ostream:: 60 | swap(basic_message_ostream &m) noexcept 61 | { 62 | using std::swap; 63 | base_type::swap(m); 64 | swap(m_buffer, m.m_buffer); 65 | } 66 | 67 | } 68 | 69 | #endif // NNXX_MESSAGE_OSTREAM_HPP 70 | -------------------------------------------------------------------------------- /src/nnxx/message_streambuf.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | namespace nnxx { 29 | 30 | template class basic_message_streambuf; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/nnxx/message_streambuf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_MESSAGE_SREAMBUF_H 26 | #define NNXX_MESSAGE_SREAMBUF_H 27 | 28 | #include 29 | #include 30 | 31 | namespace nnxx { 32 | 33 | template < typename Char, typename Traits = std::char_traits > 34 | class basic_message_streambuf : public std::basic_streambuf { 35 | typedef typename std::basic_streambuf base_type; 36 | typedef typename std::streamsize streamsize; 37 | public: 38 | typedef typename message::size_type size_type; 39 | typedef typename base_type::char_type char_type; 40 | typedef typename base_type::int_type int_type; 41 | typedef typename base_type::pos_type pos_type; 42 | typedef typename base_type::off_type off_type; 43 | typedef typename base_type::traits_type traits_type; 44 | 45 | explicit basic_message_streambuf(size_type base_size = 1000) noexcept; 46 | explicit basic_message_streambuf(message &&msg) noexcept; 47 | basic_message_streambuf(basic_message_streambuf const &) = delete; 48 | basic_message_streambuf(size_type size, int type); 49 | ~basic_message_streambuf(); 50 | basic_message_streambuf &operator=(basic_message_streambuf const &) = delete; 51 | 52 | basic_message_streambuf(basic_message_streambuf &&m) noexcept; 53 | basic_message_streambuf &operator=(basic_message_streambuf &&m) noexcept; 54 | void swap(basic_message_streambuf &m) noexcept; 55 | 56 | void msg(message &&m) noexcept; 57 | void clear() noexcept; 58 | 59 | message msg(int type = 0); 60 | message move_msg(); 61 | 62 | protected: 63 | streamsize xsputn(const char_type *, streamsize); 64 | int_type overflow(int_type); 65 | 66 | private: 67 | size_type m_base_size; 68 | message m_msg; 69 | }; 70 | 71 | template < typename Char, typename Traits > 72 | void swap(basic_message_streambuf &m1, 73 | basic_message_streambuf &m2) noexcept 74 | { m1.swap(m2); } 75 | 76 | typedef basic_message_streambuf message_streambuf; 77 | 78 | extern template class basic_message_streambuf; 79 | 80 | } 81 | 82 | #endif // NNXX_MESSAGE_SREAMBUF_H 83 | -------------------------------------------------------------------------------- /src/nnxx/message_streambuf.hpp: -------------------------------------------------------------------------------- 1 | #ifndef NNXX_MESSAGE_SREAMBUF_HPP 2 | #define NNXX_MESSAGE_SREAMBUF_HPP 3 | 4 | #include 5 | 6 | namespace nnxx { 7 | 8 | template < typename Char, typename Traits > 9 | basic_message_streambuf:: 10 | basic_message_streambuf(size_type base_size) noexcept: 11 | base_type(), 12 | m_base_size(base_size), 13 | m_msg() 14 | { } 15 | 16 | template < typename Char, typename Traits > 17 | basic_message_streambuf:: 18 | basic_message_streambuf(size_type size, int type): 19 | base_type(), 20 | m_base_size(size), 21 | m_msg(size * sizeof(char_type), type) 22 | { clear(); } 23 | 24 | template < typename Char, typename Traits > 25 | basic_message_streambuf:: 26 | basic_message_streambuf(message &&msg) noexcept: 27 | base_type(), 28 | m_base_size(msg.empty() ? 1000 : msg.size()), 29 | m_msg(std::move(msg)) 30 | { clear(); } 31 | 32 | template < typename Char, typename Traits > 33 | basic_message_streambuf:: 34 | ~basic_message_streambuf() 35 | { } 36 | 37 | template < typename Char, typename Traits > 38 | void basic_message_streambuf::clear() noexcept 39 | { 40 | const auto b = reinterpret_cast(m_msg.data()); 41 | const auto e = reinterpret_cast(m_msg.data()) + m_msg.size(); 42 | this->setg(b, b, e); 43 | this->setp(b, e); 44 | } 45 | 46 | template < typename Char, typename Traits > 47 | void basic_message_streambuf::msg(message &&m) noexcept 48 | { 49 | m_msg = std::move(m); 50 | clear(); 51 | } 52 | 53 | template < typename Char, typename Traits > 54 | message basic_message_streambuf::msg(int type) 55 | { message m(this->pptr() - this->pbase(), type); 56 | 57 | std::copy(reinterpret_cast(this->pbase()), 58 | reinterpret_cast(this->pptr()), 59 | reinterpret_cast(m.data())); 60 | 61 | return m;} 62 | 63 | template < typename Char, typename Traits > 64 | message basic_message_streambuf::move_msg() 65 | { 66 | message m; 67 | m_msg.resize(this->pptr() - this->pbase()); 68 | m_msg.swap(m); 69 | clear(); 70 | return m; 71 | } 72 | 73 | template < typename Char, typename Traits > 74 | typename 75 | basic_message_streambuf::streamsize 76 | basic_message_streambuf::xsputn(const char_type *s, streamsize n) 77 | { 78 | using std::copy; 79 | streamsize ret = 0; 80 | 81 | while (ret < n) { 82 | streamsize buflen = static_cast(this->epptr() - this->pptr()); 83 | 84 | if (buflen) { 85 | streamsize len = std::min(buflen, n - ret); 86 | copy(s, s + len, this->pptr()); 87 | this->pbump(len); 88 | ret += len; 89 | s += len; 90 | } 91 | if (ret < n) 92 | overflow(traits_type::eof()); 93 | } 94 | return ret; 95 | } 96 | 97 | template < typename Char, typename Traits > 98 | typename 99 | basic_message_streambuf::int_type 100 | basic_message_streambuf::overflow(int_type c) 101 | { 102 | const auto n = m_msg.size(); 103 | 104 | if (!m_msg) { 105 | m_msg = message{ m_base_size * sizeof(char_type) }; 106 | } 107 | else { 108 | m_msg.resize(2 * m_msg.size()); 109 | } 110 | 111 | const auto b = reinterpret_cast(m_msg.data()); 112 | const auto e = reinterpret_cast(m_msg.data()) + m_msg.size(); 113 | this->setp(b, e); 114 | this->pbump(n); 115 | 116 | if (!traits_type::eq_int_type(c, traits_type::eof())) { 117 | *(this->pptr()) = char_type(c); 118 | this->pbump(1); 119 | } 120 | 121 | return ~traits_type::eof(); 122 | } 123 | 124 | template < typename Char, typename Traits > 125 | basic_message_streambuf:: 126 | basic_message_streambuf(basic_message_streambuf &&m) noexcept: 127 | base_type(std::move(m)), 128 | m_base_size(m.m_base_size), 129 | m_msg(std::move(m.m_msg)) 130 | { m.clear(); } 131 | 132 | template < typename Char, typename Traits > 133 | basic_message_streambuf & 134 | basic_message_streambuf:: 135 | operator=(basic_message_streambuf &&m) noexcept 136 | { 137 | m.swap(*this); 138 | return *this; 139 | } 140 | 141 | template < typename Char, typename Traits > 142 | void basic_message_streambuf:: 143 | swap(basic_message_streambuf &m) noexcept 144 | { 145 | using std::swap; 146 | base_type::swap(m); 147 | swap(m_base_size, m.m_base_size); 148 | swap(m_msg, m.m_msg); 149 | } 150 | 151 | } 152 | 153 | #endif // NNXX_MESSAGE_SREAMBUF_H 154 | -------------------------------------------------------------------------------- /src/nnxx/nn.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | namespace nnxx { 30 | 31 | symbol_properties symbol(int i) 32 | { 33 | symbol_properties sp; 34 | sp.value = 0; 35 | sp.name = nullptr; 36 | sp.ns = 0; 37 | sp.type = 0; 38 | sp.unit = 0; 39 | nn_symbol_info(i, &sp, sizeof(sp)); 40 | return sp; 41 | } 42 | 43 | void term() 44 | { nn_term(); } 45 | 46 | void device(socket &s1) 47 | { 48 | socket s2; 49 | device(s1, s2); 50 | } 51 | 52 | void device(socket &s1, socket &s2) 53 | { 54 | nn_device(s1.fd(), s2.fd()); 55 | throw_error(); 56 | } 57 | 58 | int poll(pollfd *fds, int nfds, int timeout) 59 | { return check_error(nn_poll(fds, nfds, timeout)); } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/nnxx/nn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_NN_H 26 | #define NNXX_NN_H 27 | 28 | #include 29 | 30 | namespace nnxx { 31 | 32 | typedef struct nn_pollfd pollfd; 33 | 34 | enum { 35 | SOCKADDR_MAX = NN_SOCKADDR_MAX, 36 | }; 37 | 38 | enum { 39 | SP = AF_SP, 40 | SP_RAW = AF_SP_RAW, 41 | }; 42 | 43 | enum { 44 | NS_NAMESPACE = NN_NS_NAMESPACE, 45 | NS_VERSION = NN_NS_VERSION, 46 | NS_DOMAIN = NN_NS_DOMAIN, 47 | NS_TRANSPORT = NN_NS_TRANSPORT, 48 | NS_PROTOCOL = NN_NS_PROTOCOL, 49 | NS_OPTION_LEVEL = NN_NS_OPTION_LEVEL, 50 | NS_SOCKET_OPTION = NN_NS_SOCKET_OPTION, 51 | NS_TRANSPORT_OPTION = NN_NS_TRANSPORT_OPTION, 52 | NS_OPTION_TYPE = NN_NS_OPTION_TYPE, 53 | NS_FLAG = NN_NS_FLAG, 54 | NS_ERROR = NN_NS_ERROR, 55 | NS_LIMIT = NN_NS_LIMIT, 56 | }; 57 | 58 | enum { 59 | TYPE_NONE = NN_TYPE_NONE, 60 | TYPE_INT = NN_TYPE_INT, 61 | TYPE_STR = NN_TYPE_STR, 62 | }; 63 | 64 | enum { 65 | UNIT_NONE = NN_UNIT_NONE, 66 | UNIT_BYTES = NN_UNIT_BYTES, 67 | UNIT_MILLISECONDS = NN_UNIT_MILLISECONDS, 68 | UNIT_PRIORITY = NN_UNIT_PRIORITY, 69 | UNIT_BOOLEAN = NN_UNIT_BOOLEAN, 70 | }; 71 | 72 | enum { 73 | // POLLIN and POLLOUT may already be defined for the standard poll function 74 | EV_POLLIN = NN_POLLIN, 75 | EV_POLLOUT = NN_POLLOUT, 76 | }; 77 | 78 | enum { 79 | DONTWAIT = NN_DONTWAIT, 80 | // These constant shall not collide with NN_DONTWAIT or any other flag used 81 | // on the nn_recv and nn_send functions. 82 | NO_SIGNAL_ERROR = 1 << 14, 83 | NO_TIMEOUT_ERROR = 1 << 15, 84 | }; 85 | 86 | struct symbol_properties : public nn_symbol_properties { 87 | operator bool () const noexcept { return name != nullptr; } 88 | }; 89 | 90 | symbol_properties symbol(int cst); 91 | 92 | void term(); 93 | 94 | void device(class socket &s); 95 | 96 | void device(class socket &s1, class socket &s2); 97 | 98 | int poll(pollfd *fds, int nfds, int timeout); 99 | 100 | } 101 | 102 | #endif // NNXX_NN_H 103 | -------------------------------------------------------------------------------- /src/nnxx/pair.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_PAIR_H 26 | #define NNXX_PAIR_H 27 | 28 | #include 29 | 30 | namespace nnxx { 31 | 32 | enum { 33 | PAIR = NN_PAIR, 34 | }; 35 | 36 | } 37 | 38 | #endif // NNXX_PAIR_H 39 | -------------------------------------------------------------------------------- /src/nnxx/pipeline.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_PIPELINE_H 26 | #define NNXX_PIPELINE_H 27 | 28 | #include 29 | 30 | namespace nnxx { 31 | 32 | enum { 33 | PULL = NN_PULL, 34 | PUSH = NN_PUSH, 35 | }; 36 | 37 | } 38 | 39 | #endif // NNXX_PIPELINE_H 40 | -------------------------------------------------------------------------------- /src/nnxx/pubsub.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | namespace nnxx { 30 | 31 | void subscribe(socket &s, const void *topic, size_t topiclen) 32 | { s.setopt(SUB, SUB_SUBSCRIBE, topic, topiclen); } 33 | 34 | void subscribe(socket &s, const char *topic) 35 | { subscribe(s, topic, std::strlen(topic)); } 36 | 37 | void subscribe(socket &s, const std::string &topic) 38 | { subscribe(s, topic.data(), topic.size()); } 39 | 40 | void subscribe(socket &s) 41 | { subscribe(s, "", 0); } 42 | 43 | void unsubscribe(socket &s, const void *topic, size_t topiclen) 44 | { s.setopt(SUB, SUB_UNSUBSCRIBE, topic, topiclen); } 45 | 46 | void unsubscribe(socket &s, const char *topic) 47 | { unsubscribe(s, topic, std::strlen(topic)); } 48 | 49 | void unsubscribe(socket &s, const std::string &topic) 50 | { unsubscribe(s, topic.data(), topic.size()); } 51 | 52 | void unsubscribe(socket &s) 53 | { unsubscribe(s, "", 0); } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/nnxx/pubsub.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_PUBSUB_H 26 | #define NNXX_PUBSUB_H 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | namespace nnxx { 33 | 34 | class socket; 35 | 36 | enum { 37 | PUB = NN_PUB, 38 | SUB = NN_SUB, 39 | }; 40 | 41 | enum { 42 | SUB_SUBSCRIBE = NN_SUB_SUBSCRIBE, 43 | SUB_UNSUBSCRIBE = NN_SUB_UNSUBSCRIBE, 44 | }; 45 | 46 | void subscribe(socket &s, const void *topic, size_t topiclen); 47 | 48 | void subscribe(socket &s, const char *topic); 49 | 50 | void subscribe(socket &s, const std::string &topic); 51 | 52 | void subscribe(socket &s); 53 | 54 | void unsubscribe(socket &s, const void *topic, size_t topiclen); 55 | 56 | void unsubscribe(socket &s, const char *topic); 57 | 58 | void unsubscribe(socket &s, const std::string &topic); 59 | 60 | void unsubscribe(socket &s); 61 | 62 | } 63 | 64 | #endif // NNXX_PUBSUB_H 65 | -------------------------------------------------------------------------------- /src/nnxx/reqrep.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | namespace nnxx { 29 | 30 | milliseconds get_resend_interval(const socket &s) 31 | { return milliseconds(s.getopt(REQ, REQ_RESEND_IVL)); } 32 | 33 | void set_resend_interval(socket &s, milliseconds i) 34 | { s.setopt(REQ, REQ_RESEND_IVL, static_cast(i.count())); } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/nnxx/reqrep.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_REQREP_H 26 | #define NNXX_REQREP_H 27 | 28 | #include 29 | #include 30 | 31 | namespace nnxx { 32 | 33 | class socket; 34 | 35 | enum { 36 | REQ = NN_REQ, 37 | REP = NN_REP, 38 | }; 39 | 40 | enum { 41 | REQ_RESEND_IVL = NN_REQ_RESEND_IVL, 42 | }; 43 | 44 | milliseconds get_resend_interval(const socket &s); 45 | 46 | template < typename Duration > 47 | Duration get_resend_interval(const socket &s) 48 | { return std::chrono::duration_cast(get_resend_interval(s)); } 49 | 50 | void set_resend_interval(socket &s, milliseconds i); 51 | 52 | template < typename Rep, typename Period > 53 | void set_resend_interval(socket &s, 54 | const std::chrono::duration &i) 55 | { set_resend_interval(s, std::chrono::duration_cast(i)); } 56 | 57 | } 58 | 59 | #endif // NNXX_REQREP_H 60 | -------------------------------------------------------------------------------- /src/nnxx/socket: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_SOCKET 26 | #define NNXX_SOCKET 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #endif // NNXX_SOCKET 43 | 44 | -------------------------------------------------------------------------------- /src/nnxx/socket.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | namespace nnxx { 34 | 35 | static int check_socket_error(int flags) 36 | { 37 | const auto err = this_thread::get_errc(); 38 | 39 | if (err != std::errc::resource_unavailable_try_again) { 40 | if ((err != std::errc::interrupted) || !(flags & NO_SIGNAL_ERROR)) { 41 | throw_error(); 42 | } 43 | } 44 | 45 | else if (!(flags & DONTWAIT)) { 46 | if (!(flags & NO_TIMEOUT_ERROR)) { 47 | throw_error(ETIMEDOUT); 48 | } 49 | } 50 | 51 | return -1; 52 | } 53 | 54 | socket::socket() noexcept: 55 | m_fd(-1) 56 | { } 57 | 58 | socket::socket(socket &&s) noexcept: 59 | m_fd(s.m_fd) 60 | { s.detach(); } 61 | 62 | socket::socket(int domain, int protocol): 63 | m_fd(nn_socket(domain, protocol)) 64 | { check_error(m_fd); } 65 | 66 | socket::~socket() 67 | { force_close(); } 68 | 69 | socket &socket::operator=(socket &&s) noexcept 70 | { 71 | s.swap(*this); 72 | return *this; 73 | } 74 | 75 | socket::operator bool () const noexcept 76 | { return m_fd >= 0; } 77 | 78 | void socket::swap(socket &s) noexcept 79 | { 80 | using std::swap; 81 | swap(m_fd, s.m_fd); 82 | } 83 | 84 | void socket::detach() noexcept 85 | { m_fd = -1; } 86 | 87 | void socket::close() 88 | { 89 | if (m_fd >= 0) { 90 | check_error(nn_close(m_fd)); 91 | m_fd = -1; 92 | } 93 | } 94 | 95 | void socket::force_close() noexcept 96 | { 97 | while (true) { 98 | try { 99 | close(); 100 | break; 101 | } 102 | catch (const std::exception &) { 103 | } 104 | } 105 | } 106 | 107 | endpoint socket::bind(const char *addr) 108 | { return check_error(nn_bind(m_fd, addr)); } 109 | 110 | endpoint socket::bind(const std::string &addr) 111 | { return bind(addr.c_str()); } 112 | 113 | endpoint socket::connect(const char *addr) 114 | { return check_error(nn_connect(m_fd, addr)); } 115 | 116 | endpoint socket::connect(const std::string &addr) 117 | { return connect(addr.c_str()); } 118 | 119 | void socket::shutdown(endpoint how) 120 | { check_error(nn_shutdown(m_fd, how)); } 121 | 122 | void socket::force_shutdown(endpoint how) 123 | { 124 | while (true) { 125 | try { 126 | shutdown(how); 127 | break; 128 | } 129 | catch (const term_error &) { 130 | throw; 131 | } 132 | catch (const std::exception &) { 133 | } 134 | } 135 | } 136 | 137 | void socket::setopt(int level, int option, const void *val, size_t len) 138 | { check_error(nn_setsockopt(m_fd, level, option, val, len)); } 139 | 140 | void socket::getopt(int level, int option, void *val, size_t *len) const 141 | { check_error(nn_getsockopt(m_fd, level, option, val, len)); } 142 | 143 | int socket::send(const void *buf, size_t len, int flags, message_control &&ctl) 144 | { 145 | int n; 146 | 147 | if ((n = nn_sendto(m_fd, buf, len, flags, &ctl)) < 0) { 148 | return check_socket_error(flags); 149 | } 150 | 151 | ctl.detach(); 152 | return n; 153 | } 154 | 155 | int socket::send(const void *buf, size_t len, int flags) 156 | { 157 | int n; 158 | 159 | if ((n = nn_send(m_fd, buf, len, flags)) < 0) { 160 | return check_socket_error(flags); 161 | } 162 | 163 | return n; 164 | } 165 | 166 | int socket::send(const char *str, int flags, message_control &&ctl) 167 | { return send(str, std::strlen(str), flags, std::move(ctl)); } 168 | 169 | int socket::send(const char *str, int flags) 170 | { return send(str, std::strlen(str), flags); } 171 | 172 | int socket::send(message &&msg, int flags, message_control &&ctl) 173 | { 174 | message::pointer data = msg.data(); 175 | int n; 176 | 177 | if ((n = nn_sendto(m_fd, &data, MSG, flags, &ctl)) < 0) { 178 | return check_socket_error(flags); 179 | } 180 | 181 | ctl.detach(); 182 | msg.detach(); 183 | return n; 184 | } 185 | 186 | int socket::send(message &&msg, int flags) 187 | { 188 | message::pointer data = msg.data(); 189 | int n; 190 | 191 | if ((n = nn_send(m_fd, &data, MSG, flags)) < 0) { 192 | return check_socket_error(flags); 193 | } 194 | 195 | msg.detach(); 196 | return n; 197 | } 198 | 199 | int socket::recv(void *buf, size_t len, int flags, message_control &ctl) 200 | { 201 | message_control tmp; 202 | int n; 203 | 204 | if ((n = nn_recvfrom(m_fd, buf, len, flags, &tmp)) < 0) { 205 | return check_socket_error(flags); 206 | } 207 | 208 | ctl = std::move(tmp); 209 | return n; 210 | } 211 | 212 | int socket::recv(void *buf, size_t len, int flags) 213 | { 214 | int n; 215 | 216 | if ((n = nn_recv(m_fd, buf, len, flags)) < 0) { 217 | return check_socket_error(flags); 218 | } 219 | 220 | return n; 221 | } 222 | 223 | message socket::recv(int flags, message_control &ctl) 224 | { 225 | message_control tmp; 226 | void *p; 227 | int n; 228 | 229 | if ((n = nn_recvfrom(m_fd, &p, MSG, flags, &tmp)) < 0) { 230 | check_socket_error(flags); 231 | return { }; 232 | } 233 | 234 | ctl = std::move(tmp); 235 | return make_message_from(p, n); 236 | } 237 | 238 | message socket::recv(int flags) 239 | { 240 | void *p; 241 | int n; 242 | 243 | if ((n = nn_recv(m_fd, &p, MSG, flags)) < 0) { 244 | check_socket_error(flags); 245 | return { }; 246 | } 247 | 248 | return make_message_from(p, n); 249 | } 250 | 251 | int socket::fd() const noexcept 252 | { return m_fd; } 253 | 254 | socket::iterator socket::begin() 255 | { return { *this }; } 256 | 257 | socket::iterator socket::end() 258 | { return { }; } 259 | 260 | void swap(socket &s1, socket &s2) noexcept 261 | { s1.swap(s2); } 262 | 263 | } 264 | -------------------------------------------------------------------------------- /src/nnxx/socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_SOCKET_H 26 | #define NNXX_SOCKET_H 27 | 28 | #include 29 | #include 30 | 31 | // Some system define DOMAIN in math.h, this constant is defined for internal use 32 | // only so we're fine undefining it. 33 | #ifdef DOMAIN 34 | #undef DOMAIN 35 | #endif 36 | 37 | namespace nnxx { 38 | 39 | enum { 40 | SOCKET = NN_SOL_SOCKET, // SOL_SOCKET is already defined 41 | }; 42 | 43 | enum { 44 | DOMAIN = NN_DOMAIN, 45 | PROTOCOL = NN_PROTOCOL, 46 | LINGER = NN_LINGER, 47 | SNDBUF = NN_SNDBUF, 48 | RCVBUF = NN_RCVBUF, 49 | SNDTIMEO = NN_SNDTIMEO, 50 | RCVTIMEO = NN_RCVTIMEO, 51 | RECONNECT_IVL = NN_RECONNECT_IVL, 52 | RECONNECT_IVL_MAX = NN_RECONNECT_IVL_MAX, 53 | SNDPRIO = NN_SNDPRIO, 54 | IPV4ONLY = NN_IPV4ONLY, 55 | SOCKET_NAME = NN_SOCKET_NAME, 56 | RCVMAXSIZE = NN_RCVMAXSIZE, 57 | MAXTTL = NN_MAXTTL, 58 | }; 59 | 60 | enum { 61 | MSG = NN_MSG, 62 | }; 63 | 64 | typedef int endpoint; 65 | 66 | class message; 67 | class message_control; 68 | class message_iterator; 69 | 70 | class socket { 71 | public: 72 | typedef message value_type; 73 | typedef message * pointer; 74 | typedef message & reference; 75 | typedef message_iterator iterator; 76 | typedef message const * const_pointer; 77 | typedef message const & const_reference; 78 | 79 | socket() noexcept; 80 | socket(socket &&s) noexcept; 81 | socket(socket const &) = delete; 82 | socket(int domain, int protocol); 83 | 84 | ~socket(); 85 | 86 | socket &operator=(socket &&s) noexcept; 87 | socket &operator=(socket const &) = delete; 88 | 89 | operator bool () const noexcept; 90 | 91 | void swap(socket &s) noexcept; 92 | 93 | void detach() noexcept; 94 | 95 | void close(); 96 | 97 | void force_close() noexcept; 98 | 99 | endpoint bind(const char *addr); 100 | 101 | endpoint bind(const std::string &addr); 102 | 103 | endpoint connect(const char *addr); 104 | 105 | endpoint connect(const std::string &addr); 106 | 107 | void shutdown(endpoint how); 108 | 109 | void force_shutdown(endpoint how); 110 | 111 | void setopt(int level, int option, const void *val, size_t len); 112 | 113 | template < typename T > 114 | void setopt(int level, int option, const T &val); 115 | 116 | void getopt(int level, int option, void *optval, size_t *len) const; 117 | 118 | template < typename T > 119 | void getopt(int level, int option, T &val) const; 120 | 121 | template < typename T > 122 | T getopt(int level, int option) const; 123 | 124 | int send(const void *buf, size_t len, int flags, message_control &&ctl); 125 | 126 | int send(const void *buf, size_t len, int flags = 0); 127 | 128 | int send(const char *str, int flags, message_control &&ctl); 129 | 130 | int send(const char *str, int flags = 0); 131 | 132 | int send(message &&msg, int flags, message_control &&ctl); 133 | 134 | int send(message &&msg, int flags = 0); 135 | 136 | template < typename T > 137 | int send(const T &obj, int flags, message_control &&ctl); 138 | 139 | template < typename T > 140 | int send(const T &obj, int flags = 0); 141 | 142 | int recv(void *buf, size_t len, int flags, message_control &ctl); 143 | 144 | int recv(void *buf, size_t len, int flags = 0); 145 | 146 | template < typename T > 147 | T recv(int flags, message_control &ctl); 148 | 149 | template < typename T > 150 | T recv(int flags = 0); 151 | 152 | message recv(int flags, message_control &ctl); 153 | 154 | message recv(int flags = 0); 155 | 156 | int fd() const noexcept; 157 | 158 | iterator begin(); 159 | iterator end(); 160 | 161 | private: 162 | int m_fd; 163 | }; 164 | 165 | void swap(socket &s1, socket &s2) noexcept; 166 | 167 | } 168 | 169 | #include 170 | 171 | namespace std { 172 | 173 | template < > 174 | class back_insert_iterator 175 | : public std::iterator { 176 | public: 177 | typedef typename std::output_iterator_tag iterator_category; 178 | typedef void difference_type; 179 | typedef void value_type; 180 | typedef void pointer; 181 | typedef void reference; 182 | 183 | back_insert_iterator(nnxx::socket &s) noexcept; 184 | back_insert_iterator(back_insert_iterator &&) = default; 185 | back_insert_iterator(back_insert_iterator const &) = default; 186 | 187 | template < typename T > 188 | back_insert_iterator &operator=(T &&obj); 189 | back_insert_iterator &operator=(back_insert_iterator &&) = default; 190 | back_insert_iterator &operator=(back_insert_iterator const &) = default; 191 | 192 | back_insert_iterator &operator*(); 193 | back_insert_iterator &operator++(); 194 | back_insert_iterator &operator++(int); 195 | 196 | private: 197 | nnxx::socket *m_socket; 198 | }; 199 | 200 | inline 201 | back_insert_iterator:: 202 | back_insert_iterator(nnxx::socket &s) noexcept: 203 | m_socket(&s) 204 | { } 205 | 206 | template < typename T > 207 | inline 208 | back_insert_iterator & 209 | back_insert_iterator::operator=(T &&obj) 210 | { 211 | m_socket->send(std::forward(obj)); 212 | return *this; 213 | } 214 | 215 | inline 216 | back_insert_iterator & 217 | back_insert_iterator::operator*() 218 | { return *this; } 219 | 220 | inline 221 | back_insert_iterator & 222 | back_insert_iterator::operator++() 223 | { return *this; } 224 | 225 | inline 226 | back_insert_iterator & 227 | back_insert_iterator::operator++(int) 228 | { return *this; } 229 | 230 | } 231 | 232 | #include 233 | #endif // NNXX_SOCKET_H 234 | -------------------------------------------------------------------------------- /src/nnxx/socket.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifdef NNXX_SOCKET_H 26 | #ifndef NNXX_SOCKET_HPP 27 | #define NNXX_SOCKET_HPP 28 | 29 | namespace nnxx { 30 | 31 | template < typename T > 32 | void socket::setopt(int level, int option, const T &val) 33 | { setopt(level, option, &val, sizeof(val)); } 34 | 35 | template < typename T > 36 | void socket::getopt(int level, int option, T &val) const 37 | { 38 | size_t len = sizeof(val); 39 | getopt(level, option, &val, &len); 40 | } 41 | 42 | template < typename T > 43 | T socket::getopt(int level, int option) const 44 | { 45 | T optval; 46 | getopt(level, option, optval); 47 | return optval; 48 | } 49 | 50 | } 51 | 52 | #endif // NNXX_SOCKET_HPP 53 | #endif // NNXX_SOCKET_H 54 | 55 | #if defined(NNXX_SOCKET_H) && defined(NNXX_MESSAGE_H) 56 | #ifndef NNXX_SOCKET_MESSAGE 57 | #define NNXX_SOCKET_MESSAGE 58 | 59 | #include 60 | 61 | namespace nnxx { 62 | 63 | template < typename T > 64 | T socket::recv(int flags, message_control &ctl) 65 | { 66 | using std::begin; 67 | using std::end; 68 | const auto msg = this->recv(flags, ctl); 69 | return T{ begin(msg), end(msg) }; 70 | } 71 | 72 | template < typename T > 73 | T socket::recv(int flags) 74 | { 75 | using std::begin; 76 | using std::end; 77 | const auto msg = this->recv(flags); 78 | return T{ begin(msg), end(msg) }; 79 | } 80 | 81 | template < typename T > 82 | int socket::send(const T &obj, int flags, message_control &&ctl) 83 | { return send(make_message(obj), flags, ctl); } 84 | 85 | template < typename T > 86 | int socket::send(const T &obj, int flags) 87 | { return send(make_message(obj), flags); } 88 | 89 | } 90 | 91 | #endif // NNXX_SOCKET_MESSAGE 92 | #endif // NNXX_SOCKET_H && NNXX_MESSAGE_H 93 | 94 | -------------------------------------------------------------------------------- /src/nnxx/survey.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | namespace nnxx { 29 | 30 | milliseconds get_surveyor_deadline(const socket &s) 31 | { return milliseconds(s.getopt(SURVEYOR, SURVEYOR_DEADLINE)); } 32 | 33 | void set_surveyor_deadline(socket &s, milliseconds t) 34 | { s.setopt(SURVEYOR, SURVEYOR_DEADLINE, static_cast(t.count())); } 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/nnxx/survey.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_SURVEY_H 26 | #define NNXX_SURVEY_H 27 | 28 | #include 29 | #include 30 | 31 | namespace nnxx { 32 | 33 | class socket; 34 | 35 | enum { 36 | SURVEYOR = NN_SURVEYOR, 37 | RESPONDENT = NN_RESPONDENT, 38 | }; 39 | 40 | enum { 41 | SURVEYOR_DEADLINE = NN_SURVEYOR_DEADLINE, 42 | }; 43 | 44 | milliseconds get_surveyor_deadline(const socket &s); 45 | 46 | template < typename Duration > 47 | Duration get_surveyor_deadline(const socket &s) 48 | { return std::chrono::duration_cast(get_surveyor_deadline(s)); } 49 | 50 | void set_surveyor_deadline(socket &s, milliseconds t); 51 | 52 | template < typename Rep, typename Period > 53 | void set_surveyor_deadline(socket &s, const std::chrono::duration &t) 54 | { set_deadline(s, std::chrono::duration_cast(t)); } 55 | 56 | } 57 | 58 | #endif // NNXX_SURVEY_H 59 | -------------------------------------------------------------------------------- /src/nnxx/tcp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | namespace nnxx { 29 | 30 | bool get_tcp_no_delay(const socket &s) 31 | { return s.getopt(SOCKET, TCP_NODELAY); } 32 | 33 | void set_tcp_no_delay(socket &s, bool enable) 34 | { s.setopt(SOCKET, TCP_NODELAY, static_cast(enable)); } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/nnxx/tcp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_TCP_H 26 | #define NNXX_TCP_H 27 | 28 | #include 29 | 30 | namespace nnxx { 31 | 32 | class socket; 33 | 34 | enum { 35 | TCP_NODELAY = NN_TCP_NODELAY, 36 | }; 37 | 38 | bool get_tcp_no_delay(const socket &s); 39 | 40 | void set_tcp_no_delay(socket &s, bool enable); 41 | 42 | } 43 | 44 | #endif // NNXX_TCP_H 45 | -------------------------------------------------------------------------------- /src/nnxx/testing: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_TESTING 26 | #define NNXX_TESTING 27 | 28 | #include 29 | 30 | #endif // NNXX_TESTING 31 | -------------------------------------------------------------------------------- /src/nnxx/timeout.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | namespace nnxx { 29 | 30 | milliseconds get_linger(const socket &s) 31 | { return milliseconds(s.getopt(SOCKET, LINGER)); } 32 | 33 | milliseconds get_recv_timeout(const socket &s) 34 | { return milliseconds(s.getopt(SOCKET, RCVTIMEO)); } 35 | 36 | milliseconds get_send_timeout(const socket &s) 37 | { return milliseconds(s.getopt(SOCKET, SNDTIMEO)); } 38 | 39 | void set_linger(socket &s, milliseconds t) 40 | { s.setopt(SOCKET, LINGER, static_cast(t.count())); } 41 | 42 | void set_recv_timeout(socket &s, milliseconds t) 43 | { s.setopt(SOCKET, RCVTIMEO, static_cast(t.count())); } 44 | 45 | void set_send_timeout(socket &s, milliseconds t) 46 | { s.setopt(SOCKET, SNDTIMEO, static_cast(t.count())); } 47 | 48 | with_linger::with_linger(socket &s, milliseconds t): 49 | m_socket(s), 50 | m_old_timeout(get_linger(s)) 51 | { set_linger(s, t); } 52 | 53 | with_linger::~with_linger() 54 | { set_linger(m_socket, m_old_timeout); } 55 | 56 | with_recv_timeout::with_recv_timeout(socket &s, milliseconds t): 57 | m_socket(s), 58 | m_old_timeout(get_recv_timeout(s)) 59 | { set_recv_timeout(s, t); } 60 | 61 | with_recv_timeout::~with_recv_timeout() 62 | { set_recv_timeout(m_socket, m_old_timeout); } 63 | 64 | with_send_timeout::with_send_timeout(socket &s, milliseconds t): 65 | m_socket(s), 66 | m_old_timeout(get_send_timeout(s)) 67 | { set_send_timeout(s, t); } 68 | 69 | with_send_timeout::~with_send_timeout() 70 | { set_send_timeout(m_socket, m_old_timeout); } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/nnxx/timeout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_TIMEOUT_H 26 | #define NNXX_TIMEOUT_H 27 | 28 | #include 29 | 30 | namespace nnxx { 31 | 32 | class socket; 33 | 34 | milliseconds get_linger(const socket &s); 35 | milliseconds get_recv_timeout(const socket &s); 36 | milliseconds get_send_timeout(const socket &s); 37 | 38 | template < typename Duration > 39 | Duration get_linger(const socket &s) 40 | { return std::chrono::duration_cast(get_linger(s)); } 41 | 42 | template < typename Duration > 43 | Duration get_recv_timeout(const socket &s) 44 | { return std::chrono::duration_cast(get_recv_timeout(s)); } 45 | 46 | template < typename Duration > 47 | Duration get_send_timeout(const socket &s) 48 | { return std::chrono::duration_cast(get_send_timeout(s)); } 49 | 50 | void set_linger(socket &s, milliseconds t); 51 | void set_recv_timeout(socket &s, milliseconds t); 52 | void set_send_timeout(socket &s, milliseconds t); 53 | 54 | template < typename Rep, typename Period > 55 | void set_linger(socket &s, const std::chrono::duration &t) 56 | { set_linger(s, std::chrono::duration_cast(t)); } 57 | 58 | template < typename Rep, typename Period > 59 | void set_recv_timeout(socket &s, const std::chrono::duration &t) 60 | { set_recv_timeout(s, std::chrono::duration_cast(t)); } 61 | 62 | template < typename Rep, typename Period > 63 | void set_send_timeout(socket &s, const std::chrono::duration &t) 64 | { set_send_timeout(s, std::chrono::duration_cast(t)); } 65 | 66 | class with_linger { 67 | public: 68 | with_linger(socket &s, milliseconds t); 69 | 70 | template < typename Rep, typename Period > 71 | with_linger(socket &s, const std::chrono::duration &t): 72 | m_socket(s), 73 | m_old_timeout(get_linger(s)) 74 | { set_linger(s, t); } 75 | 76 | with_linger(with_linger &&) = delete; 77 | with_linger(with_linger const &) = delete; 78 | 79 | ~with_linger() ; 80 | 81 | with_linger &operator=(with_linger &&) = delete; 82 | with_linger &operator=(with_linger const &) = delete; 83 | 84 | private: 85 | socket & m_socket; 86 | milliseconds m_old_timeout; 87 | }; 88 | 89 | class with_recv_timeout { 90 | public: 91 | with_recv_timeout(socket &s, milliseconds t); 92 | 93 | template < typename Rep, typename Period > 94 | with_recv_timeout(socket &s, const std::chrono::duration &t): 95 | m_socket(s), 96 | m_old_timeout(get_recv_timeout(s)) 97 | { set_recv_timeout(s, t); } 98 | 99 | with_recv_timeout(with_recv_timeout &&) = delete; 100 | with_recv_timeout(with_recv_timeout const &) = delete; 101 | 102 | ~with_recv_timeout() ; 103 | 104 | with_recv_timeout &operator=(with_recv_timeout &&) = delete; 105 | with_recv_timeout &operator=(with_recv_timeout const &) = delete; 106 | 107 | private: 108 | socket & m_socket; 109 | milliseconds m_old_timeout; 110 | }; 111 | 112 | class with_send_timeout { 113 | public: 114 | with_send_timeout(socket &s, milliseconds t); 115 | 116 | template < typename Rep, typename Period > 117 | with_send_timeout(socket &s, const std::chrono::duration &t): 118 | m_socket(s), 119 | m_old_timeout(get_send_timeout(s)) 120 | { set_send_timeout(s, t); } 121 | 122 | with_send_timeout(with_send_timeout &&) = delete; 123 | with_send_timeout(with_send_timeout const &) = delete; 124 | 125 | ~with_send_timeout(); 126 | 127 | with_send_timeout &operator=(with_send_timeout &&) = delete; 128 | with_send_timeout &operator=(with_send_timeout const &) = delete; 129 | 130 | private: 131 | socket & m_socket; 132 | milliseconds m_old_timeout; 133 | }; 134 | 135 | } 136 | 137 | #endif // NNXX_TIMEOUT_H 138 | -------------------------------------------------------------------------------- /src/nnxx/unittest.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef NNXX_UNITTEST_H 26 | #define NNXX_UNITTEST_H 27 | 28 | #include 29 | #include 30 | 31 | namespace nnxx { namespace unittest { 32 | 33 | volatile int result = EXIT_SUCCESS; 34 | 35 | } } 36 | 37 | #define nnxx_check(x) \ 38 | do { \ 39 | if (!(x)) { \ 40 | std::fprintf(stderr, "%s:%d: check failed: %s\n", __FILE__, __LINE__, #x); \ 41 | nnxx::unittest::result = EXIT_FAILURE; \ 42 | } \ 43 | } while (0) 44 | 45 | #define nnxx_assert(x) \ 46 | do { \ 47 | if (!(x)) { \ 48 | std::fprintf(stderr, "%s:%d: assertion failed: %s\n", __FILE__, __LINE__, #x); \ 49 | std::exit(EXIT_FAILURE); \ 50 | } \ 51 | } while (0) 52 | 53 | #endif // NNXX_UNITTEST_H 54 | -------------------------------------------------------------------------------- /src/nnxx/wscript: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | # 4 | # Nanomsgxx build script. 5 | from copy import copy 6 | from waflib.Task import Task 7 | 8 | class strip(Task): 9 | 10 | def run(self): 11 | cmd = 'strip -x src/nnxx/' + self.env.libnanomsgxx_name 12 | print(cmd) 13 | return self.exec_command(cmd) 14 | 15 | def configure(waf): 16 | waf.check_cxx(lib='nanomsg') 17 | if waf.options.strip: 18 | waf.find_program('strip') 19 | 20 | def build(waf): 21 | conf = copy(waf.env.CXX_CONF_KWARGS) 22 | conf.update({ 23 | 'lib' : ['nanomsgext', 'nanomsg'], 24 | 'source': waf.path.ant_glob('*.cpp'), 25 | 'target': 'nnxx', 26 | }) 27 | 28 | # Generate tasks for building either a static or shared library 29 | if waf.options.static: 30 | waf.env.libnanomsgxx_name = waf.env.cxxstlib_PATTERN % conf['target'] 31 | waf.env.nnxx = waf.stlib(**conf) 32 | else: 33 | waf.env.libnanomsgxx_name = waf.env.cxxshlib_PATTERN % conf['target'] 34 | waf.env.nnxx = waf.shlib(**conf) 35 | waf.env.nnxx.post() 36 | 37 | # Make sure we don't build the library before building the extensions 38 | for t1 in waf.env.nnxx.tasks: 39 | for t2 in waf.env.nnext.tasks: 40 | t1.set_run_after(t2) 41 | 42 | # Run strip after the build was complete 43 | if waf.env.with_strip: 44 | strip_task = strip(env=waf.env) 45 | strip_task.set_inputs([waf.path.find_or_declare(waf.env.libnanomsgxx_name)]) 46 | waf.add_to_group(strip_task) 47 | 48 | # Define which files will be installed 49 | waf.install_files('${PREFIX}/include/nnxx', waf.path.ant_glob('*.h *.hpp message socket testing')) 50 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(nnxx_tests) 2 | include(CTest) 3 | 4 | message(STATUS ${EXECUTABLE_OUTPUT_PATH}) 5 | 6 | add_executable(test_message ./test_message.cpp) 7 | target_link_libraries(test_message nnxx) 8 | add_test(message ${EXECUTABLE_OUTPUT_PATH}/test_message) 9 | 10 | add_executable(test_message_istream ./test_message_istream.cpp) 11 | target_link_libraries(test_message_istream nnxx) 12 | add_test(message_istream ${EXECUTABLE_OUTPUT_PATH}/test_message_istream) 13 | 14 | add_executable(test_message_ostream ./test_message_ostream.cpp) 15 | target_link_libraries(test_message_ostream nnxx) 16 | add_test(message_ostream ${EXECUTABLE_OUTPUT_PATH}/test_message_ostream) 17 | 18 | add_executable(test_nnxx_ext ./test_nnxx_ext.cpp) 19 | target_link_libraries(test_nnxx_ext nnxx) 20 | add_test(nnxx_ext ${EXECUTABLE_OUTPUT_PATH}/test_nnxx_ext) 21 | 22 | add_executable(test_pair ./test_pair.cpp) 23 | target_link_libraries(test_pair nnxx) 24 | add_test(pair ${EXECUTABLE_OUTPUT_PATH}/test_pair) 25 | 26 | add_executable(test_pipeline ./test_pipeline.cpp) 27 | target_link_libraries(test_pipeline nnxx) 28 | add_test(pipeline ${EXECUTABLE_OUTPUT_PATH}/test_pipeline) 29 | 30 | add_executable(test_poll ./test_poll.cpp) 31 | target_link_libraries(test_poll nnxx) 32 | add_test(poll ${EXECUTABLE_OUTPUT_PATH}/test_poll) 33 | 34 | add_executable(test_pubsub ./test_pubsub.cpp) 35 | target_link_libraries(test_pubsub nnxx) 36 | add_test(pubsub ${EXECUTABLE_OUTPUT_PATH}/test_pubsub) 37 | 38 | add_executable(test_readme ./test_readme.cpp) 39 | target_link_libraries(test_readme nnxx) 40 | add_test(readme ${EXECUTABLE_OUTPUT_PATH}/test_readme) 41 | 42 | add_executable(test_reqrep ./test_reqrep.cpp) 43 | target_link_libraries(test_reqrep nnxx) 44 | add_test(reqrep ${EXECUTABLE_OUTPUT_PATH}/test_reqrep) 45 | 46 | add_executable(test_reqrep_multi ./test_reqrep_multi.cpp) 47 | target_link_libraries(test_reqrep_multi nnxx) 48 | add_test(reqrep_multi ${EXECUTABLE_OUTPUT_PATH}/test_reqrep_multi) 49 | 50 | add_executable(test_socket ./test_socket.cpp) 51 | target_link_libraries(test_socket nnxx) 52 | add_test(socket ${EXECUTABLE_OUTPUT_PATH}/test_socket) 53 | 54 | add_executable(test_survey ./test_survey.cpp) 55 | target_link_libraries(test_survey nnxx) 56 | add_test(survey ${EXECUTABLE_OUTPUT_PATH}/test_survey) 57 | 58 | add_executable(test_timeout ./test_timeout.cpp) 59 | target_link_libraries(test_timeout nnxx) 60 | add_test(timeout ${EXECUTABLE_OUTPUT_PATH}/test_timeout) 61 | 62 | -------------------------------------------------------------------------------- /tests/README: -------------------------------------------------------------------------------- 1 | This folder contains the source files for all nanomsgxx tests. 2 | -------------------------------------------------------------------------------- /tests/test_message.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | int main() { 31 | nnxx::message m1; 32 | nnxx::message m2 { 12 }; 33 | 34 | nnxx_check(!m1); 35 | nnxx_check(m2); 36 | 37 | nnxx_check(m1.data() == nullptr); 38 | nnxx_check(m1.size() == 0); 39 | 40 | nnxx_check(m2.data() != nullptr); 41 | nnxx_check(m2.size() == 12); 42 | 43 | m1 = std::move(m2); 44 | nnxx_check(m1); 45 | nnxx_check(!m2); 46 | 47 | std::strcpy(reinterpret_cast(m1.data()), "Hello World!"); 48 | m2 = copy(m1); 49 | nnxx_check(to_string(m2) == "Hello World!"); 50 | return nnxx::unittest::result; 51 | } 52 | -------------------------------------------------------------------------------- /tests/test_message_istream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | int main() { 30 | nnxx::message m { 1000 }; 31 | std::strcpy(reinterpret_cast(m.data()), "1 2 3"); 32 | 33 | nnxx::message_istream s { std::move(m) }; 34 | int a; 35 | int b; 36 | int c; 37 | 38 | s >> a; 39 | s >> b; 40 | s >> c; 41 | 42 | nnxx_check(a == 1); 43 | nnxx_check(b == 2); 44 | nnxx_check(c == 3); 45 | return nnxx::unittest::result; 46 | } 47 | -------------------------------------------------------------------------------- /tests/test_message_ostream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | int main() { 30 | nnxx::message_ostream s; 31 | nnxx::message m; 32 | 33 | s << "Hello World! "; 34 | s << 42; 35 | m = s.move_msg(); 36 | 37 | nnxx_check(m.size() == 15); 38 | nnxx_check(std::strncmp(reinterpret_cast(m.data()), "Hello World! 42", 15) == 0); 39 | return nnxx::unittest::result; 40 | } 41 | -------------------------------------------------------------------------------- /tests/test_nnxx_ext.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | int main() { 31 | struct nn_msgctl ctl1; 32 | struct nn_msgctl ctl2; 33 | int s1 = nn_socket (AF_SP_RAW, NN_REP); 34 | int s2 = nn_socket (AF_SP, NN_REQ); 35 | int s3 = nn_socket (AF_SP, NN_REQ); 36 | void *buf1 = nullptr; 37 | void *buf2 = nullptr; 38 | 39 | nnxx_assert (s1 >= 0); 40 | nnxx_assert (s2 >= 0); 41 | 42 | /* Connecting sockets. */ 43 | nnxx_assert (nn_bind (s1, "inproc://test") >= 0); 44 | nnxx_assert (nn_connect (s2, "inproc://test") >= 0); 45 | nnxx_assert (nn_connect (s3, "inproc://test") >= 0); 46 | 47 | /* Sending requests. */ 48 | nnxx_assert (nn_send (s2, "Hello World! (1)", 16, 0) == 16); 49 | nnxx_assert (nn_send (s3, "Hello World! (2)", 16, 0) == 16); 50 | 51 | /* Recieving requests. */ 52 | nnxx_assert (nn_recvfrom (s1, &buf1, NN_MSG, 0, &ctl1) == 16); 53 | nnxx_assert (nn_recvfrom (s1, &buf2, NN_MSG, 0, &ctl2) == 16); 54 | 55 | /* Making sure we have the correct data. */ 56 | nnxx_assert (memcmp (buf1, "Hello World! (1)", 16) == 0); 57 | nnxx_assert (memcmp (buf2, "Hello World! (2)", 16) == 0); 58 | 59 | /* Sending responses back in reverse order. */ 60 | nnxx_assert (nn_sendto (s1, &buf2, NN_MSG, 0, &ctl2) == 16); 61 | nnxx_assert (nn_sendto (s1, &buf1, NN_MSG, 0, &ctl1) == 16); 62 | 63 | /* Recieving responses. */ 64 | nnxx_assert (nn_recv (s2, &buf1, NN_MSG, 0) == 16); 65 | nnxx_assert (nn_recv (s3, &buf2, NN_MSG, 0) == 16); 66 | 67 | /* Making sure the clients got the right responses. */ 68 | nnxx_assert (memcmp (buf1, "Hello World! (1)", 16) == 0); 69 | nnxx_assert (memcmp (buf2, "Hello World! (2)", 16) == 0); 70 | 71 | /* Releasing resources. */ 72 | nn_freemsg (buf2); 73 | nn_freemsg (buf1); 74 | nn_close (s2); 75 | nn_close (s1); 76 | return nnxx::unittest::result; 77 | } 78 | -------------------------------------------------------------------------------- /tests/test_pair.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | int main() { 33 | const std::vector messages { "Hello World!" }; 34 | 35 | nnxx::socket s1 { nnxx::SP, nnxx::PAIR }; 36 | nnxx::socket s2 { nnxx::SP, nnxx::PAIR }; 37 | s1.bind("inproc://test"); 38 | s2.connect("inproc://test"); 39 | 40 | std::copy(messages.begin(), messages.end(), std::back_inserter(s1)); 41 | 42 | for (const nnxx::message &msg : s2) { 43 | nnxx_check(to_string(msg) == messages[0]); 44 | break; 45 | } 46 | 47 | return nnxx::unittest::result; 48 | } 49 | -------------------------------------------------------------------------------- /tests/test_pipeline.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | int main() { 30 | nnxx::socket s1 { nnxx::SP, nnxx::PUSH }; 31 | nnxx::socket s2 { nnxx::SP, nnxx::PULL }; 32 | nnxx::socket s3 { nnxx::SP, nnxx::PULL }; 33 | 34 | s1.bind("inproc://test"); 35 | s2.connect("inproc://test"); 36 | s3.connect("inproc://test"); 37 | 38 | nnxx_check(s1.send("Hello World! 1") == 14); 39 | nnxx_check(s1.send("Hello World! 2") == 14); 40 | 41 | nnxx_check(to_string(s2.recv()) == "Hello World! 1"); 42 | nnxx_check(to_string(s3.recv()) == "Hello World! 2"); 43 | return nnxx::unittest::result; 44 | } 45 | -------------------------------------------------------------------------------- /tests/test_poll.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | int main() { 30 | nnxx::socket s1 { nnxx::SP, nnxx::PAIR }; 31 | nnxx::socket s2 { nnxx::SP, nnxx::PAIR }; 32 | nnxx::poll_vector events; 33 | nnxx::recv_ready_sequence r1; 34 | nnxx::send_ready_sequence r2; 35 | 36 | s1.bind("inproc://test"); 37 | s2.connect("inproc://test"); 38 | 39 | try { 40 | // Poll for sockets that are ready for output operations, both s1 and s2 41 | // should be set. 42 | events = nnxx::poll({{ s1, nnxx::EV_POLLOUT }, { s2, nnxx::EV_POLLOUT }}); 43 | r1 = nnxx::recv_ready(events); 44 | r2 = nnxx::send_ready(events); 45 | nnxx_assert(std::distance(r1.begin(), r1.end()) == 0); 46 | nnxx_assert(std::distance(r2.begin(), r2.end()) == 2); 47 | 48 | // Send a message on s1 and poll s2 for input operations, s1 should be set 49 | // and there should be no socket ready for output operations. 50 | s1.send("Hello World!"); 51 | events = nnxx::poll({{ s2, nnxx::EV_POLLIN }}, std::chrono::seconds(0)); 52 | 53 | for (auto &e : nnxx::recv_ready(events)) { 54 | nnxx_assert(e == s2); 55 | nnxx_assert(e.is(s2)); 56 | nnxx_assert(e.recv_ready()); 57 | nnxx_check(to_string(s2.recv()) == "Hello World!"); 58 | } 59 | 60 | for (auto &e : nnxx::send_ready(events)) { 61 | nnxx_assert(false); // there should be no send-ready sockets 62 | (void)e; 63 | } 64 | 65 | // Poll for input operations on s2 which has already been flushed, so we 66 | // should get a timeout there. 67 | try { 68 | nnxx::poll({{ s2, nnxx::EV_POLLIN }}, std::chrono::milliseconds(10)); 69 | nnxx_assert(false); 70 | } 71 | catch (const nnxx::timeout_error &) { 72 | } 73 | } 74 | 75 | // None of these conditions should happen. 76 | catch (const nnxx::signal_error &) { 77 | nnxx_assert(false); 78 | } 79 | catch (const nnxx::timeout_error &) { 80 | nnxx_assert(false); 81 | } 82 | catch (const std::exception &) { 83 | nnxx_assert(false); 84 | } 85 | 86 | return nnxx::unittest::result; 87 | } 88 | -------------------------------------------------------------------------------- /tests/test_pubsub.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | int main() { 30 | nnxx::socket s1 { nnxx::SP, nnxx::PUB }; 31 | nnxx::socket s2 { nnxx::SP, nnxx::SUB }; 32 | nnxx::socket s3 { nnxx::SP, nnxx::SUB }; 33 | 34 | s1.bind("inproc://test"); 35 | s2.connect("inproc://test"); 36 | s3.connect("inproc://test"); 37 | 38 | nnxx::subscribe(s2); 39 | nnxx::subscribe(s3); 40 | 41 | nnxx_check(s1.send("Hello World!") == 12); 42 | 43 | nnxx_check(to_string(s2.recv()) == "Hello World!"); 44 | nnxx_check(to_string(s3.recv()) == "Hello World!"); 45 | return nnxx::unittest::result; 46 | } 47 | -------------------------------------------------------------------------------- /tests/test_readme.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | int main() { 31 | try { 32 | nnxx::socket s1 { nnxx::SP, nnxx::PAIR }; 33 | nnxx::socket s2 { nnxx::SP, nnxx::PAIR }; 34 | const char *addr = "inproc://example"; 35 | 36 | s1.bind(addr); 37 | s2.connect(addr); 38 | 39 | s1.send("Hello World!"); 40 | 41 | nnxx::message msg = s2.recv(); 42 | std::cout << msg << std::endl; 43 | return 0; 44 | } 45 | catch (const std::system_error &e) { 46 | std::cerr << e.what() << std::endl; 47 | return 1; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tests/test_reqrep.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | int main() { 30 | nnxx::socket s1 { nnxx::SP, nnxx::REP }; 31 | nnxx::socket s2 { nnxx::SP, nnxx::REQ }; 32 | nnxx::socket s3 { nnxx::SP, nnxx::REQ }; 33 | 34 | s1.bind("inproc://test"); 35 | s2.connect("inproc://test"); 36 | s3.connect("inproc://test"); 37 | 38 | nnxx_check(s2.send("Hello World! 1") == 14); 39 | nnxx_check(s3.send("Hello World! 2") == 14); 40 | 41 | nnxx_check(s1.recv() == "Hello World! 1"); 42 | nnxx_check(s1.send(std::string{ "1" }) == 1); 43 | 44 | nnxx_check(s1.recv() == "Hello World! 2"); 45 | nnxx_check(s1.send(std::string{ "2" }) == 1); 46 | 47 | nnxx_check(to_string(s2.recv()) == "1"); 48 | nnxx_check(to_string(s3.recv()) == "2"); 49 | return nnxx::unittest::result; 50 | } 51 | -------------------------------------------------------------------------------- /tests/test_reqrep_multi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | int main() { 30 | nnxx::socket s1 { nnxx::SP_RAW, nnxx::REP }; 31 | nnxx::socket s2 { nnxx::SP, nnxx::REQ }; 32 | nnxx::socket s3 { nnxx::SP, nnxx::REQ }; 33 | nnxx::message_control c1; 34 | nnxx::message_control c2; 35 | 36 | s1.bind("inproc://test"); 37 | s2.connect("inproc://test"); 38 | s3.connect("inproc://test"); 39 | 40 | nnxx_check(s2.send("Hello World! 1") == 14); 41 | nnxx_check(s3.send("Hello World! 2") == 14); 42 | 43 | auto m1 = s1.recv(0, c1); 44 | auto m2 = s1.recv(0, c2); 45 | 46 | nnxx_check(s1.send(std::move(m2), 0, std::move(c2)) == 14); 47 | nnxx_check(s1.send(std::move(m1), 0, std::move(c1)) == 14); 48 | 49 | nnxx_check(to_string(s2.recv()) == "Hello World! 1"); 50 | nnxx_check(to_string(s3.recv()) == "Hello World! 2"); 51 | return nnxx::unittest::result; 52 | } 53 | -------------------------------------------------------------------------------- /tests/test_socket.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | int main() { 29 | nnxx::socket s; 30 | nnxx_check(!s); 31 | nnxx_check(s.fd() == -1); 32 | return nnxx::unittest::result; 33 | } 34 | -------------------------------------------------------------------------------- /tests/test_survey.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | int main() { 30 | nnxx::socket s1 { nnxx::SP, nnxx::SURVEYOR }; 31 | nnxx::socket s2 { nnxx::SP, nnxx::RESPONDENT }; 32 | nnxx::socket s3 { nnxx::SP, nnxx::RESPONDENT }; 33 | 34 | s1.bind("inproc://test"); 35 | s2.connect("inproc://test"); 36 | s3.connect("inproc://test"); 37 | 38 | nnxx_check(s1.send("Hello World!") == 12); 39 | 40 | nnxx_check(to_string(s2.recv()) == "Hello World!"); 41 | nnxx_check(to_string(s3.recv()) == "Hello World!"); 42 | return nnxx::unittest::result; 43 | } 44 | -------------------------------------------------------------------------------- /tests/test_timeout.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2014 Achille Roussel 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | int main() { 30 | nnxx::socket s { nnxx::SP, nnxx::PAIR }; 31 | 32 | s.bind("inproc://test"); 33 | 34 | // Set a timeout of receive operations peformed in this scope. 35 | try { nnxx::with_recv_timeout _ { s, std::chrono::milliseconds(10) }; 36 | s.recv(); 37 | nnxx_assert(false); 38 | } 39 | catch (const nnxx::timeout_error &) { 40 | } 41 | catch (const std::exception &) { 42 | nnxx_assert(false); 43 | } 44 | 45 | return nnxx::unittest::result; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /tests/wscript: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | # 4 | # Tests build script. 5 | from copy import copy 6 | from waflib.Tools import waf_unit_test 7 | 8 | def configure(waf): 9 | pass 10 | 11 | def build(waf): 12 | features = ['cxx', 'cxxprogram', 'test'] 13 | lib = ['nanomsg', 'nanomsgext', 'nnxx'] 14 | for f in waf.path.ant_glob('*.cpp'): 15 | source = str(f) 16 | target = str(f)[:-4] 17 | conf = copy(waf.env.CXX_CONF_KWARGS) 18 | conf.update({ 19 | 'target' : target, 20 | 'source' : source, 21 | 'features' : features, 22 | 'lib' : lib, 23 | 'install_path': None, 24 | }) 25 | test = waf(**conf) 26 | test.post() 27 | for t1 in test.tasks: 28 | for t2 in waf.env.nnxx.tasks: 29 | t1.set_run_after(t2) 30 | waf.add_post_fun(waf_unit_test.summary) 31 | -------------------------------------------------------------------------------- /waf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/achille-roussel/nanomsgxx/4426567809a79352f65bbd2d69488df237442d33/waf -------------------------------------------------------------------------------- /wscript: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | import os 4 | import sys 5 | 6 | APPNAME = 'nanomsgxx' 7 | VERSION = '0.1' 8 | 9 | def build(waf): 10 | cflags = ['-W', '-Wall', '-Wextra', '-fvisibility=hidden'] 11 | cxxflags = ['-W', '-Wall', '-Wextra', '-std=c++11'] 12 | defines = [] 13 | includes = [os.path.join(waf.path.abspath(), 'src')] 14 | libpath = ['src/nanomsg/ext', 'src/nnxx'] 15 | 16 | if waf.options.debug: 17 | cflags += ['-g3'] 18 | cxxflags += ['-g3'] 19 | else: 20 | cflags += ['-O3'] 21 | cxxflags += ['-O3'] 22 | defines += ['NDEBUG=1'] 23 | 24 | waf.env.C_CONF_KWARGS = { 25 | 'includes': includes, 26 | 'libpath' : libpath, 27 | 'defines' : defines, 28 | 'cflags' : cflags, 29 | } 30 | 31 | waf.env.CXX_CONF_KWARGS = { 32 | 'includes': includes, 33 | 'libpath' : libpath, 34 | 'defines' : defines, 35 | 'cflags' : cflags, 36 | 'cxxflags': cxxflags, 37 | } 38 | 39 | waf.recurse('src/nanomsg/ext') 40 | waf.recurse('src/nnxx') 41 | if not waf.options.notests: 42 | waf.recurse('tests') 43 | if waf.env.with_doc: 44 | waf.recurse('doc') 45 | if waf.env.with_pkgconfig: 46 | waf(source='libnnxx.pc.in', install_path='${LIBDIR}/pkgconfig/') 47 | 48 | def configure(waf): 49 | waf.load('compiler_c compiler_cxx c_config waf_unit_test') 50 | waf.recurse('src/nanomsg/ext') 51 | waf.recurse('src/nnxx') 52 | 53 | if waf.options.nodoc: 54 | waf.env.with_doc = False 55 | else: 56 | waf.env.with_doc = True 57 | try: 58 | waf.recurse('doc') 59 | except Exception: 60 | sys.stderr.write('Disabling documentation build...\n') 61 | waf.env.with_doc = False 62 | 63 | waf.env.with_pkgconfig = not waf.options.nopkgconfig 64 | waf.env.with_strip = waf.options.strip 65 | waf.env.install_html_path = waf.options.install_html_path 66 | 67 | def dist(waf): 68 | waf.algo = 'tar.gz' 69 | waf.files = all_files(waf) 70 | 71 | def options(waf): 72 | def add_bool(name, help): 73 | waf.add_option(name, action='store_true', help=help) 74 | waf.load('compiler_c compiler_cxx waf_unit_test') 75 | add_bool('--debug', 'build in debug mode') 76 | add_bool('--static', 'build static library') 77 | add_bool('--shared', 'build shared library (default)') 78 | add_bool('--notests', 'turn off tests') 79 | add_bool('--nodoc', 'turn off documentation') 80 | add_bool('--nopkgconfig', 'turn off pkg-config support') 81 | add_bool('--strip', 'runs the \'strip\' utility on the build') 82 | waf.recurse('doc') 83 | --------------------------------------------------------------------------------