<commit_before>/**
 * \file
 * \brief SerialPort class header
 *
 * \author Copyright (C) 2016-2019 <NAME> http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef INCLUDE_DISTORTOS_DEVICES_COMMUNICATION_SERIALPORT_HPP_
#define INCLUDE_DISTORTOS_DEVICES_COMMUNICATION_SERIALPORT_HPP_

#include "distortos/devices/communication/UartBase.hpp"
#include "distortos/devices/communication/UartParity.hpp"

#include "distortos/Mutex.hpp"

namespace distortos
{

class Semaphore;

namespace devices
{

class UartLowLevel;

/**
 * \brief SerialPort class is a serial port with an interface similar to standard files.
 *
 * \ingroup devices
 */

class SerialPort : private UartBase
{
public:

	/**
	 * \brief Thread-safe, lock-free raw circular buffer for single-producer and single-consumer
	 *
	 * Distinction between empty and full buffer is possible because most significant bits of read and write positions
	 * are used as single-bit counters or wrap-arounds. This limits the size of buffer to SIZE_MAX / 2, but allows full
	 * utilization of storage (no free slot is needed).
	 */

	class RawCircularBuffer
	{
	public:

		/**
		 * \brief RawCircularBuffer's constructor
		 *
		 * \param [in] buffer is a buffer for data
		 * \param [in] size is the size of \a buffer, bytes, must be less than or equal to SIZE_MAX / 2
		 */

		constexpr RawCircularBuffer(void* const buffer, const size_t size) :
				buffer_{static_cast<uint8_t*>(buffer)},
				size_{size & sizeMask_},
				readPosition_{},
				writePosition_{}
		{

		}

		/**
		 * \brief RawCircularBuffer's constructor, read-only variant
		 *
		 * \param [in] buffer is a read-only buffer with data
		 * \param [in] size is the size of \a buffer, bytes, must be less than or equal to SIZE_MAX / 2
		 */

		constexpr RawCircularBuffer(const void* const buffer, const size_t size) :
				buffer_{static_cast<uint8_t*>(const_cast<void*>(buffer))},
				size_{(size & sizeMask_) | readOnlyMask_},
				readPosition_{},
				writePosition_{}
		{

		}

		/**
		 * \brief Clears raw circular buffer
		 */

		void clear()
		{
			readPosition_ = {};
			writePosition_ = {};
		}

		/**
		 * \return total capacity of raw circular buffer, bytes
		 */

		size_t getCapacity() const
		{
			return size_ & sizeMask_;
		}

		/**
		 * \return first contiguous block (as a pair with pointer and size) available for reading
		 */

		std::pair<const uint8_t*, size_t> getReadBlock() const;

		/**
		 * \return total amount of valid data in raw circular buffer, bytes
		 */

		size_t getSize() const
		{
			const auto readPosition = readPosition_ ;
			const auto writePosition = writePosition_;
			if (isEmpty(readPosition, writePosition) == true)
				return 0;
			const auto capacity = getCapacity();
			if (isFull(readPosition, writePosition) == true)
				return capacity;
			return (capacity - (readPosition & positionMask_) + (writePosition & positionMask_)) % capacity;
		}

		/**
		 * \return first contiguous block (as a pair with pointer and size) available for writing
		 */

		std::pair<uint8_t*, size_t> getWriteBlock() const;

		/**
		 * \brief Increases read position by given value.
		 *
		 * \param [in] value is the value which will be added to read position, must come from previous call to
		 * getReadBlock()
		 */

		void increaseReadPosition(const size_t value)
		{
			readPosition_ = increasePosition(readPosition_, value);
		}

		/**
		 * \brief Increases write position by given value.
		 *
		 * \param [in] value is the value which will be added to write position, must come from previous call to
		 * getWriteBlock()
		 */

		void increaseWritePosition(const size_t value)
		{
			writePosition_ = increasePosition(writePosition_, value);
		}<commit_msg>Improve comments for RawCircularBuffer::increase...Position()<commit_after>/**
 * \file
 * \brief SerialPort class header
 *
 * \author Copyright (C) 2016-2019 <NAME> http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef INCLUDE_DISTORTOS_DEVICES_COMMUNICATION_SERIALPORT_HPP_
#define INCLUDE_DISTORTOS_DEVICES_COMMUNICATION_SERIALPORT_HPP_

#include "distortos/devices/communication/UartBase.hpp"
#include "distortos/devices/communication/UartParity.hpp"

#include "distortos/Mutex.hpp"

namespace distortos
{

class Semaphore;

namespace devices
{

class UartLowLevel;

/**
 * \brief SerialPort class is a serial port with an interface similar to standard files.
 *
 * \ingroup devices
 */

class SerialPort : private UartBase
{
public:

	/**
	 * \brief Thread-safe, lock-free raw circular buffer for single-producer and single-consumer
	 *
	 * Distinction between empty and full buffer is possible because most significant bits of read and write positions
	 * are used as single-bit counters or wrap-arounds. This limits the size of buffer to SIZE_MAX / 2, but allows full
	 * utilization of storage (no free slot is needed).
	 */

	class RawCircularBuffer
	{
	public:

		/**
		 * \brief RawCircularBuffer's constructor
		 *
		 * \param [in] buffer is a buffer for data
		 * \param [in] size is the size of \a buffer, bytes, must be less than or equal to SIZE_MAX / 2
		 */

		constexpr RawCircularBuffer(void* const buffer, const size_t size) :
				buffer_{static_cast<uint8_t*>(buffer)},
				size_{size & sizeMask_},
				readPosition_{},
				writePosition_{}
		{

		}

		/**
		 * \brief RawCircularBuffer's constructor, read-only variant
		 *
		 * \param [in] buffer is a read-only buffer with data
		 * \param [in] size is the size of \a buffer, bytes, must be less than or equal to SIZE_MAX / 2
		 */

		constexpr RawCircularBuffer(const void* const buffer, const size_t size) :
				buffer_{static_cast<uint8_t*>(const_cast<void*>(buffer))},
				size_{(size & sizeMask_) | readOnlyMask_},
				readPosition_{},
				writePosition_{}
		{

		}

		/**
		 * \brief Clears raw circular buffer
		 */

		void clear()
		{
			readPosition_ = {};
			writePosition_ = {};
		}

		/**
		 * \return total capacity of raw circular buffer, bytes
		 */

		size_t getCapacity() const
		{
			return size_ & sizeMask_;
		}

		/**
		 * \return first contiguous block (as a pair with pointer and size) available for reading
		 */

		std::pair<const uint8_t*, size_t> getReadBlock() const;

		/**
		 * \return total amount of valid data in raw circular buffer, bytes
		 */

		size_t getSize() const
		{
			const auto readPosition = readPosition_ ;
			const auto writePosition = writePosition_;
			if (isEmpty(readPosition, writePosition) == true)
				return 0;
			const auto capacity = getCapacity();
			if (isFull(readPosition, writePosition) == true)
				return capacity;
			return (capacity - (readPosition & positionMask_) + (writePosition & positionMask_)) % capacity;
		}

		/**
		 * \return first contiguous block (as a pair with pointer and size) available for writing
		 */

		std::pair<uint8_t*, size_t> getWriteBlock() const;

		/**
		 * \brief Increases read position by given value.
		 *
		 * \param [in] value is the value which will be added to read position, must be less than or equal to the value
		 * from last call to getReadBlock()
		 */

		void increaseReadPosition(const size_t value)
		{
			readPosition_ = increasePosition(readPosition_, value);
		}

		/**
		 * \brief Increases write position by given value.
		 *
		 * \param [in] value is the value which will be added to write position, must be less than or equal to the value
		 * from last call to getWriteBlock()
		 */

		void increaseWritePosition(const size_t value)
		{
			writePosition_ = increasePosition(writePosition_, value);
		}
{'fraction_non_alphanumeric': 0.09731290808638875, 'fraction_numerical': 0.005022601707684581, 'mean_word_length': 3.407858328721638, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4149320', 'n_tokens_mistral': 2724, 'n_tokens_neox': 2304, 'n_words': 831}