diff --git a/psrdada_cpp/cli_utils.hpp b/psrdada_cpp/cli_utils.hpp index 5ac02413ffade1c037675e112a5e77984f86ae81..5ac4c8ffc275e07b8d5116510c3e4a870a0c6ecc 100644 --- a/psrdada_cpp/cli_utils.hpp +++ b/psrdada_cpp/cli_utils.hpp @@ -5,7 +5,26 @@ namespace psrdada_cpp { + /** + * @brief Convert a string into a shared memory key + * + * @param in A hexadecimal string (e.g. "dada") + * + * @note No error checking is performed on the conversion, meaning + * that non-hex valiues will still give an output (e.g. an input + * of "dag" will drop the non-hex "g" character giving an output + * of 0xda) + * + * @return A key_t representation of the hexadecimal string + */ key_t string_to_key(std::string const& in); + + /** + * @brief Sets the log level for boost logging. + * + * @param[in] level The desired log level as a string + * [debug, info, warning, error]. + */ void set_log_level(std::string level); } //namespace diff --git a/psrdada_cpp/dada_client_base.hpp b/psrdada_cpp/dada_client_base.hpp index e990ef74e41b3a1bc15b3b02f23098d6bb677481..1edf3f7d7ff5c1b5c6b7bded61e5e52b2ad09e68 100644 --- a/psrdada_cpp/dada_client_base.hpp +++ b/psrdada_cpp/dada_client_base.hpp @@ -17,12 +17,34 @@ namespace psrdada_cpp { MultiLog& _log; public: + /** + * @brief Create a new basic DADA client instance + * + * @param[in] key The hexidecimal shared memory key + * @param log A MultiLog instance for logging buffer transactions + */ DadaClientBase(key_t key, MultiLog& log); DadaClientBase(DadaClientBase const&) = delete; ~DadaClientBase(); + + /** + * @brief Get the sizes of each data block in the ring buffer + */ std::size_t data_buffer_size(); + + /** + * @brief Get the sizes of each header block in the ring buffer + */ std::size_t header_buffer_size(); + + /** + * @brief Get the number of data blocks in the ring buffer + */ std::size_t data_buffer_count(); + + /** + * @brief Get the number of header blocks in the ring buffer + */ std::size_t header_buffer_count(); private: diff --git a/psrdada_cpp/dada_dbnull.hpp b/psrdada_cpp/dada_dbnull.hpp index 80adf5e35d17e75b941c4f24878a9f53d21aab18..8529b60b2f4711b804639bc8fcdb24f67ade63c1 100644 --- a/psrdada_cpp/dada_dbnull.hpp +++ b/psrdada_cpp/dada_dbnull.hpp @@ -8,6 +8,14 @@ namespace psrdada_cpp { + /** + * @brief Class for reading from a DADA buffer + * and doing nothing with the data. + * + * @detail This class is intended as both an example + * for how to use CRTP with DadaIoLoopReader + * and as a tool for testing. + */ class DbNull : public DadaIoLoopReader<DbNull> { @@ -16,9 +24,37 @@ namespace psrdada_cpp bool _infinite; public: + /** + * @brief Create a new instance + * + * @param[in] key The shared memory key + * @param log A MultiLog instance + * @param[in] nbytes The number of bytes to read from the buffer. + * Setting this value to 0 will cause the instance + * to read forever. + */ DbNull(key_t key, MultiLog& log, std::size_t nbytes); ~DbNull(); + + /** + * @brief A callback to be called on connection + * to a ring buffer. + * + * @detail The first available header block in the + * in the ring buffer is provided as an argument. + * It is here that header parameters could be read + * if desired. + * + * @param block A RawBytes object wrapping a DADA header buffer + */ void on_connect(RawBytes& block); + + /** + * @brief A callback to be called on acqusition of a new + * data block. + * + * @param block A RawBytes object wrapping a DADA data buffer + */ void on_next(RawBytes& block); }; diff --git a/psrdada_cpp/dada_io_loop.hpp b/psrdada_cpp/dada_io_loop.hpp index ac08269b7200ad036aee57fdbe2c97d58fddd4f9..307fcb8208e24e8a87bc9a5ecfb7ee6b0c491cf1 100644 --- a/psrdada_cpp/dada_io_loop.hpp +++ b/psrdada_cpp/dada_io_loop.hpp @@ -16,10 +16,25 @@ namespace psrdada_cpp bool _running; public: + + /** + * @brief Create new instance + * + * @param[in] key A hexadecimal shared memory key + * @param log A MultiLog instance + */ DadaIoLoop(key_t key, MultiLog& log); DadaIoLoop(DadaIoLoop const&) = delete; ~DadaIoLoop(); + + /** + * @brief Stop the IO loop processing + */ void stop(); + + /** + * @brief Start the IO loop processing + */ virtual void run()=0; }; diff --git a/psrdada_cpp/dada_io_loop_reader.hpp b/psrdada_cpp/dada_io_loop_reader.hpp index ccfb633083049adfa6e8f8160c14ac79a6e179db..7f443dfb9cdeff5db8cfae3cf032935ee216fb30 100644 --- a/psrdada_cpp/dada_io_loop_reader.hpp +++ b/psrdada_cpp/dada_io_loop_reader.hpp @@ -11,8 +11,18 @@ namespace psrdada_cpp class DadaIoLoopReader: public DadaIoLoop { public: + /** + * @brief Create a IO loop for reading from a DADA buffer + * + * @param[in] key The hexidecimal shared memory key + * @param log A MultiLog instance for logging buffer transactions + */ DadaIoLoopReader(key_t key, MultiLog& log); ~DadaIoLoopReader(); + + /** + * @brief Start the IO loop processing + */ void run(); }; } //namespace psrdada_cpp diff --git a/psrdada_cpp/dada_io_loop_writer.hpp b/psrdada_cpp/dada_io_loop_writer.hpp index 905813c068f1cba2bb6f7139a4fb564d5d49eb06..8673637b1b1d311ffccc10ead8d5eedd081b22e8 100644 --- a/psrdada_cpp/dada_io_loop_writer.hpp +++ b/psrdada_cpp/dada_io_loop_writer.hpp @@ -11,8 +11,18 @@ namespace psrdada_cpp class DadaIoLoopWriter: public DadaIoLoop { public: + /** + * @brief Create a IO loop for writing to a DADA buffer + * + * @param[in] key The hexidecimal shared memory key + * @param log A MultiLog instance for logging buffer transactions + */ DadaIoLoopWriter(key_t key, MultiLog& log); ~DadaIoLoopWriter(); + + /** + * @brief Start the IO loop processing + */ void run(); }; } //namespace psrdada_cpp diff --git a/psrdada_cpp/dada_junkdb.hpp b/psrdada_cpp/dada_junkdb.hpp index 62ab8ba6a514846e02ad4d06f6babccb696f13bf..b665ce57e4f9f85c8a7866eebfa8aab825c714d5 100644 --- a/psrdada_cpp/dada_junkdb.hpp +++ b/psrdada_cpp/dada_junkdb.hpp @@ -8,6 +8,13 @@ namespace psrdada_cpp { + /** + * @brief Class for writing junk to a dada buffer + * + * @detail This class is intended as both an example + * for how to use CRTP with DadaIoLoopWriter + * and as a tool for testing. + */ class JunkDb : public DadaIoLoopWriter<JunkDb> { @@ -16,9 +23,37 @@ namespace psrdada_cpp bool _infinite; public: + /** + * @brief Create a new instance + * + * @param[in] key The shared memory key + * @param log A MultiLog instance + * @param[in] nbytes The number of bytes to write to the buffer. + * Setting this value to 0 will cause the instance + * to write forever. + */ JunkDb(key_t key, MultiLog& log, std::size_t nbytes); ~JunkDb(); + + /** + * @brief A callback to be called on connection + * to a ring buffer. + * + * @detail The first available header block in the + * in the ring buffer is provided as an argument. + * It is here that header parameters could be written + * to if desired. + * + * @param block A RawBytes object wrapping a DADA header buffer + */ void on_connect(RawBytes& block); + + /** + * @brief A callback to be called on acqusition of a new + * data block. + * + * @param block A RawBytes object wrapping a DADA data buffer + */ bool on_next(RawBytes& block); }; diff --git a/psrdada_cpp/dada_read_client.hpp b/psrdada_cpp/dada_read_client.hpp index d17b329c4307de78e578db5532dba28f75edb272..7bae53054be8ac323473acb8bfb9ffcb4c6de51c 100644 --- a/psrdada_cpp/dada_read_client.hpp +++ b/psrdada_cpp/dada_read_client.hpp @@ -7,6 +7,10 @@ namespace psrdada_cpp { + /** + * @brief Class that provides means for reading from + * a DADA ring buffer + */ class DadaReadClient: public DadaClientBase { public: @@ -17,11 +21,36 @@ namespace psrdada_cpp { std::unique_ptr<RawBytes> _current_block; public: + /** + * @brief Create a new instance + * + * @param parent A reference to the parent reading client + */ HeaderStream(DadaReadClient& parent); HeaderStream(HeaderStream const&) = delete; ~HeaderStream(); + + /** + * @brief Get the next header block in the ring buffer + * + * @detail As only one block can be open at a time, release() must + * be called between subsequenct next() calls. + * + * @return A RawBytes instance wrapping a pointer to share memory + */ RawBytes& next(); + + /** + * @brief Release the current data block. + * + * @detail This will mark the block as cleared, making it + * writeable by writing client. + */ void release(); + + /** + * @brief Check if we have read the last header block in buffer. + */ bool at_end() const; }; @@ -33,12 +62,41 @@ namespace psrdada_cpp { std::size_t _block_idx; public: + /** + * @brief Create a new instance + * + * @param parent A reference to the parent reading client + */ DataStream(DadaReadClient& parent); DataStream(DataStream const&) = delete; ~DataStream(); + + /** + * @brief Get the next data block in the ring buffer + * + * @detail As only one block can be open at a time, release() must + * be called between subsequenct next() calls. + * + * @return A RawBytes instance wrapping a pointer to share memory + */ RawBytes& next(); + + /** + * @brief Release the current data block. + * + * @detail This will mark the block as cleared, making it + * writeable by writing client. + */ void release(); + + /** + * @brief Check if we have read the last data block in buffer. + */ bool at_end() const; + + /** + * @brief Return the index of the currently open block + */ std::size_t block_idx() const; }; @@ -48,10 +106,28 @@ namespace psrdada_cpp { DataStream _data_stream; public: + /** + * @brief Create a new client for reading from a DADA buffer + * + * @param[in] key The hexidecimal shared memory key + * @param log A MultiLog instance for logging buffer transactions + */ DadaReadClient(key_t key, MultiLog& log); DadaReadClient(DadaReadClient const&) = delete; ~DadaReadClient(); + + /** + * @brief Get a reference to a header stream manager + * + * @return A HeaderStream manager object for the current buffer + */ HeaderStream& header_stream(); + + /** + * @brief Get a reference to a data stream manager + * + * @return A DataStream manager object for the current buffer + */ DataStream& data_stream(); private: diff --git a/psrdada_cpp/dada_write_client.hpp b/psrdada_cpp/dada_write_client.hpp index ddfb61a0683907e037d0e9bd6277c254d65b6e0f..a9ecdf39911d1ab76f318b76ba443a5300e99420 100644 --- a/psrdada_cpp/dada_write_client.hpp +++ b/psrdada_cpp/dada_write_client.hpp @@ -7,9 +7,18 @@ namespace psrdada_cpp { + /** + * @brief Class that provides means for writing to + * a DADA ring buffer + */ class DadaWriteClient: public DadaClientBase { public: + + /** + * @brief A helper class for encapsulating + * the DADA buffer header blocks. + */ class HeaderStream { private: @@ -17,10 +26,31 @@ namespace psrdada_cpp { std::unique_ptr<RawBytes> _current_block; public: + /** + * @brief Create a new instance + * + * @param parent A reference to the parent writing client + */ HeaderStream(DadaWriteClient& parent); HeaderStream(HeaderStream const&) = delete; ~HeaderStream(); + + /** + * @brief Get the next header block in the ring buffer + * + * @detail As only one block can be open at a time, release() must + * be called between subsequenct next() calls. + * + * @return A RawBytes instance wrapping a pointer to share memory + */ RawBytes& next(); + + /** + * @brief Release the current header block. + * + * @detail This will mark the block as filled, making it + * readable by reading client. + */ void release(); }; @@ -32,19 +62,62 @@ namespace psrdada_cpp { std::size_t _block_idx; public: + /** + * @brief Create a new instance + * + * @param parent A reference to the parent writing client + */ DataStream(DadaWriteClient& parent); DataStream(DataStream const&) = delete; ~DataStream(); + + /** + * @brief Get the next data block in the ring buffer + * + * @detail As only one block can be open at a time, release() must + * be called between subsequenct next() calls. + * + * @return A RawBytes instance wrapping a pointer to share memory + */ RawBytes& next(); + + /** + * @brief Release the current data block. + * + * @detail This will mark the block as filled, making it + * readable by reading client. + */ void release(bool eod=false); + + /** + * @brief Return the index of the currently open block + */ std::size_t block_idx() const; }; public: + /** + * @brief Create a new client for writing to a DADA buffer + * + * @param[in] key The hexidecimal shared memory key + * @param log A MultiLog instance for logging buffer transactions + */ DadaWriteClient(key_t key, MultiLog& log); DadaWriteClient(DadaWriteClient const&) = delete; ~DadaWriteClient(); + + /** + * @brief Get a reference to a header stream manager + * + * @return A HeaderStream manager object for the current buffer + */ HeaderStream& header_stream(); + + /** + * @brief Get a reference to a data stream manager + * + * @return A DataStream manager object for the current buffer + */ DataStream& data_stream(); private: diff --git a/psrdada_cpp/examples/dbnull.cpp b/psrdada_cpp/examples/dbnull.cpp index 40bffb819794a18bd561ebf96de0c4ac06aabb8e..b438cbb3325fbd5e9aaa7b3c7f13005e6c9832b6 100644 --- a/psrdada_cpp/examples/dbnull.cpp +++ b/psrdada_cpp/examples/dbnull.cpp @@ -70,9 +70,18 @@ int main(int argc, char** argv) std::cerr << desc << std::endl; return ERROR_IN_COMMAND_LINE; } + + /** + * All the application code goes here + */ + MultiLog log("dbnull"); DbNull proc(key, log, nbytes); proc.run(); + + /** + * End of application code + */ } catch(std::exception& e) { diff --git a/psrdada_cpp/examples/junkdb.cpp b/psrdada_cpp/examples/junkdb.cpp index 1d1656900aee44829fff7a7ab3fbba0076f4ee03..f9f22743d7fc3c9f70e9096e4bea3f4a61b981b4 100644 --- a/psrdada_cpp/examples/junkdb.cpp +++ b/psrdada_cpp/examples/junkdb.cpp @@ -69,9 +69,18 @@ int main(int argc, char** argv) std::cerr << desc << std::endl; return ERROR_IN_COMMAND_LINE; } + + /** + * All the application code goes here + */ + MultiLog log("junkdb"); JunkDb proc(key, log, nbytes); proc.run(); + + /** + * End of application code + */ } catch(std::exception& e) { diff --git a/psrdada_cpp/multilog.hpp b/psrdada_cpp/multilog.hpp index 707a78afc14e84c47deea335e033b16018e4b51b..7fbece1fdbe65c2de312184c3cab4a0815e2c568 100644 --- a/psrdada_cpp/multilog.hpp +++ b/psrdada_cpp/multilog.hpp @@ -6,6 +6,11 @@ namespace psrdada_cpp { + /** + * @brief A class for wrapping multilog_t instances + * required for logging with the underlying + * DADA API. + */ class MultiLog { private: @@ -14,12 +19,29 @@ namespace psrdada_cpp { bool _open; public: + /** + * @brief Create a new instance + * + * @param[in] name The name to give this logger + */ explicit MultiLog(std::string name); MultiLog(MultiLog const&) = delete; ~MultiLog(); + /** + * @brief Get a native handle to the wrapped multilog_t pointer + */ multilog_t* native_handle(); + /** + * @brief Write to the log + * + * @param[in] priority The priority (0, 1, 2...) + * @param[in] format The format string + * @param[in] ... Parameters for the format string + * + * @tparam Args The types of the parameters for the format string + */ template<class... Args> void write(int priority, const char* format, Args&&... args); diff --git a/psrdada_cpp/raw_bytes.hpp b/psrdada_cpp/raw_bytes.hpp index 3fed09bf8079a8540f1ea56d7c6d74e8bb7247c2..76bd32eb7e565e2d8b0ff29b34c494a0438cf027 100644 --- a/psrdada_cpp/raw_bytes.hpp +++ b/psrdada_cpp/raw_bytes.hpp @@ -5,6 +5,17 @@ namespace psrdada_cpp { + /** + * @brief Class for wrapping a raw pointer to a buffer of shared memory + * + * @detail This class is used to wrap pointers to shared memory + * returned by calls to the lower-level DADA API. + * + * This class is used to wrap buffers acquired by both reading + * and writing clients. For writing clients, it is necessary to + * set the number of bytes written using the used_bytes() method + * after writing. This value is used when releasing the buffer. + */ class RawBytes { private: @@ -13,12 +24,39 @@ namespace psrdada_cpp { std::size_t _used_bytes; public: + /** + * @brief Create a new RawBytes instance + * + * @param ptr The pointer to the buffer to wrap + * @param[in] total The total number of bytes in the buffer + * @param[in] used The number of bytes currently used in the buffer + */ RawBytes(char* ptr, std::size_t total, std::size_t used=0); RawBytes(RawBytes const&) = delete; ~RawBytes(); + + /** + * @brief Get the total number of bytes in the buffer + */ std::size_t total_bytes(); + + /** + * @brief Get the number of currently used bytes in the buffer + */ std::size_t used_bytes(); + + /** + * @brief Set the number of currently used bytes in the buffer + * + * @detail For writing clients, this method should be called after + * all writes are complete so that the number of used_bytes + * can be passed to reading clients. + */ void used_bytes(std::size_t); + + /** + * @brief Get a raw pointer to the start of the buffer + */ char* ptr(); };