nanomsgxx-design(7) -- Nanomsgxx Design
=======================================

## DESCRIPTION

This chapter exposes the main design decisions that were made when developping
nanomsgxx.

## CONSTANTS

nanomsg uses many constants to represent protocols, socket domains, options,
flags... Since C++ syntax is mostly compatible with C, standard nanomsg constants
(NN) can be simply used wherever constants are expected in the C++ API.
However nanomsgxx ports all constants within the nnxx namespace, removing the
leading `NN_`. For example the `NN_MSG` constant in the C API is ported by the
`nnxx::MSG` symbol. This applies to almost all constants, except in a few cases
where it conflicts with some existing symbols (more on that later).

## STRINGS

nanomsgxx functions accept string arguments in some cases, to bind or connect
to a node for example. Everywhere a string is expected the functions are designed
to receive any object that can be converted to a C-string (null-terminted char
sequence), this includes:

- objects of `const char *` type, or implicitly converted to this pointer type
- objects of `std::string` type, or any other specialization of `std::basic_string`
- any object with a c_str member function returning a `const char *`

This feature can be extended by providing a c_str function for new types, for example:

```
namespace X {
  const char *c_str(const other_string_type &s) {
    return s.c_string();
  }
}
```

## OBJECTS

The nanomsgxx API provides a few object types that abstracts concepts of the C
API, while trying to stay as close as possible it adds a few extra types to
integrate with the C++ standard library and take advantages of the rich features
of the language.

- **Moveable Objects**

All types in the nanomsgxx API provide a move constructor and a move assignment
operator, these are powerful features of C++11 and the library makes heavy use
of it to provide an easy resource management model, as well as protecting the
user from mis-using the library in some places.

- **Member vs Non-Member Functions**

Member functions are used of nanomsgxx objects to provide operations that are
part of the object's identity, providing the low-level pieces on which extensions
can be built.  
For example the `nnxx::socket` type will have the recv and send member functions
because receiving and sending messages are the core features of the this type,
but protocol extensions such as turning on or off Nagle's algorithm for TCP
connections will be provided as a non-member function because it's not an
operation that can be performed on any socket type.

## EXCEPTIONS

The nanomsg library uses the POSIX mechanism to report errors, setting errno
to some error number and returning a nagative number from the function.
C++ exceptions are used to report these conditions and almost all exceptions
thrown by the nanomsgxx functions are sub-classes of `std::system_error`, so the
original error number that was generated by the underlying nanomsg routine can
be accessed through the caught exception.

- **Signals**

When a program receives a signal it may cause any ongoing system call to be
cancelled to execute a signal handler instead, in that case the systeam call
terminates with the EINTR error code. While nanomsg mirrors this behavior,
nanomsgxx reports these conditions with the `nnxx::signal_error` exception.  
This can be deactivated on a per-call basis by passing `nnxx::NO_SIGNAL_ERROR`
in the flags argument on any blocking call, you should then refer to the
documentation of each function to understand how to handle this case.

- **Timeouts**

nanomsg's API lets the user define a timeout for any blocking operation
(typically receiving or sending messages), and reports any timeout in the
operation with a `nnxx::timeout_error` exception.  
This can be deactivated on a per-call basis by passing `nnxx::NO_TIMEOUT_ERROR`
in the flags argument on any blocking call, you should then refer to the
documentation of each function to understand how to handle this case.

- **Termination**

When the program is about to exit it is supposed to inform the nanomsg library
by calling nn_term, making any future or pending calls to nanomsg routines
failing and setting errno to ETERM. While this is still reported with an
exception in nanomsgxx it's on case where the exception thrown isn't a sub-class
of `std::system_error`. The `nnxx::term_error` exception is instead a sub-class of
`std::logic_error`. That allows the program to handle this condition away from
local error handling logic.

- **Memory Allocation**

The nanomsg library uses dynamic memory allocations in some places, if these
fail for whatever reasons the functions report the error with the ENOMEM errno
code.  
This is another case where nanomsgxx will report an error through an exception
that is not a subclass of `std::system_error`. The C++ standard library provides
the `std::bad_alloc` exception for this purpose, in order to easily integrate with
programs that are written for standard C++ nanomsgxx also reports memory
allocation failures by throwing an instance of `std::bad_alloc`. 

## SEE ALSO

nanomsgxx(7)  
nanomsgxx-messages(7)  
nanomsg(7)

## AUTHORS

Achille Roussel
