diff --git a/include/Nazara/Core/ByteArray.inl b/include/Nazara/Core/ByteArray.inl index 1597758fd..2a8ab59a8 100644 --- a/include/Nazara/Core/ByteArray.inl +++ b/include/Nazara/Core/ByteArray.inl @@ -6,59 +6,141 @@ namespace Nz { + /*! + * \brief Constructs a ByteArray object with a reserved size + * + * \param n Space reserved + */ + inline ByteArray::ByteArray(size_type n) : m_array() { m_array.reserve(n); } + /*! + * \brief Constructs a ByteArray object with a raw memory and a size + * + * \param ptr Pointer to raw memory + * \param n Size that can be accessed + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + */ + inline ByteArray::ByteArray(const void* buffer, size_type n) : m_array(static_cast(buffer), static_cast(buffer) + n) { } + /*! + * \brief Constructs a ByteArray object with n times the same value + * + * \param n Number of repetitions + * \param value Value to repeat + */ + inline ByteArray::ByteArray(size_type n, const value_type value) : m_array(n, value) { } + /*! + * \brief Constructs a ByteArray object from two iterators + * + * \param first First iterator + * \param last Second iterator + */ + template ByteArray::ByteArray(InputIterator first, InputIterator last) : m_array(first, last) { } + /*! + * \brief Appends the content of raw memory + * + * \param ptr Constant pointer to raw memory + * \param n Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + * + * \see Insert + */ + inline ByteArray::iterator ByteArray::Append(const void* buffer, size_type n) { return Insert(end(), static_cast(buffer), static_cast(buffer) + n); } + /*! + * \brief Appends another array of bytes + * + * \param other ByteArray to add + * + * \see Insert + */ + inline ByteArray::iterator ByteArray::Append(const ByteArray& other) { return Insert(end(), other.begin(), other.end()); } + /*! + * \brief Assigns this with n times the same value + * + * \param n Number of repetitions + * \param value Value to repeat + */ + inline void ByteArray::Assign(size_type n, value_type value) { m_array.assign(n, value); } + /*! + * \brief Assigns this with the content between two iterators + * + * \param first First iterator + * \param last Second iterator + */ + template void ByteArray::Assign(InputIterator first, InputIterator last) { m_array.assign(first, last); } + /*! + * \brief Gets last element + * \return A reference to last element + * + * \remark If ByteArray is empty, behaviour is undefined + */ + inline ByteArray::reference ByteArray::Back() { return m_array.back(); } + /*! + * \brief Gets last element + * \return A constant reference to last element + * + * \remark If ByteArray is empty, behaviour is undefined + */ + inline ByteArray::const_reference ByteArray::Back() const { return m_array.back(); } + /*! + * \brief Clears the content of the string + * + * \param keepBuffer Should the buffer be kept + */ + inline void ByteArray::Clear(bool keepBuffer) { m_array.clear(); @@ -66,142 +148,326 @@ namespace Nz m_array.shrink_to_fit(); } + /*! + * \brief Erases an element from the byte array + * + * \param pos Iterator to the element + */ + inline ByteArray::iterator ByteArray::Erase(const_iterator pos) { return m_array.erase(pos); } + /*! + * \brief Erases the elements between the two pointers from the byte array + * + * \param first First iterator + * \param last Second iterator + */ + inline ByteArray::iterator ByteArray::Erase(const_iterator first, const_iterator last) { return m_array.erase(first, last); } + /*! + * \brief Gets first element + * \return A reference to first element + * + * \remark If ByteArray is empty, behaviour is undefined + */ + inline ByteArray::reference ByteArray::Front() { return m_array.front(); } + /*! + * \brief Gets first element + * \return A constant reference to first element + * + * \remark If ByteArray is empty, behaviour is undefined + */ + inline ByteArray::const_reference ByteArray::Front() const { return m_array.front(); } + /*! + * \brief Gets the internal allocator of the byte array + * \return Allocator + */ + inline ByteArray::allocator_type ByteArray::GetAllocator() const { return m_array.get_allocator(); } + /*! + * \brief Gets the raw buffer + * \return Raw buffer + */ + inline ByteArray::pointer ByteArray::GetBuffer() { return m_array.data(); } + /*! + * \brief Gets the capacity of the byte array + * \return Capacity of the byte array + */ + inline ByteArray::size_type ByteArray::GetCapacity() const noexcept { return m_array.capacity(); } + /*! + * \brief Gets the raw buffer + * \return Raw buffer + */ + inline ByteArray::const_pointer ByteArray::GetConstBuffer() const { return m_array.data(); } + /*! + * \brief Gets the maximal size supported by the byte array + * \return Biggest size handled + */ + inline ByteArray::size_type ByteArray::GetMaxSize() const noexcept { return m_array.max_size(); } + /*! + * \brief Gets the size of the byte array + * \return Size of the byte array + */ + inline ByteArray::size_type ByteArray::GetSize() const noexcept { return m_array.size(); } + /*! + * \brief Returns a sub byte array of the byte array + * \return Sub byte array + * + * \param startPos First iterator + * \param endPos Second iterator + */ + inline ByteArray ByteArray::GetSubArray(const_iterator startPos, const_iterator endPos) const { return ByteArray(startPos, endPos); } + /*! + * \brief Inserts the content of raw memory at the iterator position + * + * \param pos Iterator to the position + * \param buffer Constant pointer to raw memory + * \param n Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + */ + inline ByteArray::iterator ByteArray::Insert(const_iterator pos, const void* buffer, size_type n) { return m_array.insert(pos, static_cast(buffer), static_cast(buffer) + n); } + /*! + * \brief Inserts the content of another byte array at the iterator position + * + * \param pos Iterator to the position + * \param other Other byte array + */ + inline ByteArray::iterator ByteArray::Insert(const_iterator pos, const ByteArray& other) { return m_array.insert(pos, other.begin(), other.end()); } + /*! + * \brief Inserts n times the same value at the iterator position + * + * \param pos Iterator to the position + * \param n Number of repetitions + * \param value Value to repeat + */ + inline ByteArray::iterator ByteArray::Insert(const_iterator pos, size_type n, value_type byte) { return m_array.insert(pos, n, byte); } + /*! + * \brief Inserts the content from two iterators at the iterator position + * + * \param pos Iterator to the position + * \param first First iterator + * \param last Second iterator + */ + template ByteArray::iterator ByteArray::Insert(const_iterator pos, InputIterator first, InputIterator last) { return m_array.insert(pos, first, last); } + /*! + * \brief Checks whether the byte array is empty + * \return true if byte array is empty + */ + inline bool ByteArray::IsEmpty() const noexcept { return m_array.empty(); } + /*! + * \brief Erases the last element + * + * \remark If byte array is empty, the behaviour is undefined + */ + inline void ByteArray::PopBack() { Erase(end() - 1); } + /*! + * \brief Erases the first element + * + * \remark If byte array is empty, the behaviour is undefined + */ + inline void ByteArray::PopFront() { Erase(begin()); } + /*! + * \brief Prepends the content of raw memory + * + * \param ptr Constant pointer to raw memory + * \param n Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + * + * \see Insert + */ + inline ByteArray::iterator ByteArray::Prepend(const void* buffer, size_type n) { return Insert(begin(), buffer, n); } + /*! + * \brief Prepends another array of bytes + * + * \param other ByteArray to add + * + * \see Insert + */ + inline ByteArray::iterator ByteArray::Prepend(const ByteArray& other) { return Insert(begin(), other); } + /*! + * \brief Pushes the byte at the end + * + * \param byte Byte to add + */ + inline void ByteArray::PushBack(const value_type byte) { m_array.push_back(byte); } + /*! + * \brief Pushes the byte at the beginning + * + * \param byte Byte to add + */ + inline void ByteArray::PushFront(const value_type byte) { m_array.insert(begin(), 1, byte); } + /*! + * \brief Reserves enough memory for the buffer size + * + * \param bufferSize Size of the buffer to allocate + * + * \remark If bufferSize is smaller than the old one, nothing is done + */ + inline void ByteArray::Reserve(size_type bufferSize) { m_array.reserve(bufferSize); } + /*! + * \brief Resizes the string + * \return A reference to this + * + * \param newSize Target size + */ + inline void ByteArray::Resize(size_type newSize) { m_array.resize(newSize); } + /*! + * \brief Resizes the string + * \return A reference to this + * + * \param newSize Target size + * \param byte Byte to add if newSize is greather than actual size + */ + inline void ByteArray::Resize(size_type newSize, const value_type byte) { m_array.resize(newSize, byte); } + /*! + * \brief Releases the excedent memory + */ + inline void ByteArray::ShrinkToFit() { m_array.shrink_to_fit(); } + /*! + * \brief Swaps the content with the other byte array + * + * \param other Other byte array to swap with + */ + inline void ByteArray::Swap(ByteArray& other) { m_array.swap(other.m_array); } + /*! + * \brief Gives a string representation in base 16 + * \return String in base 16 + */ + inline String ByteArray::ToHex() const { std::size_t length = m_array.size() * 2; @@ -213,76 +479,153 @@ namespace Nz return hexOutput; } + /*! + * \brief Gives a string representation + * \return String where each byte is converted to char + */ + inline String ByteArray::ToString() const { return String(reinterpret_cast(GetConstBuffer()), GetSize()); } + /*! + * \brief Returns an iterator pointing to the beggining of the string + * \return Beggining of the string + */ + inline ByteArray::iterator ByteArray::begin() noexcept { return m_array.begin(); } + /*! + * \brief Returns an iterator pointing to the beggining of the string + * \return Beggining of the string + */ + inline ByteArray::const_iterator ByteArray::begin() const noexcept { return m_array.begin(); } + /*! + * \brief Returns a constant iterator pointing to the beggining of the string + * \return Beggining of the string + */ + inline ByteArray::const_iterator ByteArray::cbegin() const noexcept { return m_array.cbegin(); } + /*! + * \brief Returns a constant iterator pointing to the end of the string + * \return End of the string + */ + inline ByteArray::const_iterator ByteArray::cend() const noexcept { return m_array.cend(); } + /*! + * \brief Returns a constant reversed iterator pointing to the beggining of the string + * \return Beggining of the string + */ + inline ByteArray::const_reverse_iterator ByteArray::crbegin() const noexcept { return m_array.crbegin(); } + /*! + * \brief Returns a constant reversed iterator pointing to the end of the string + * \return End of the string + */ + inline ByteArray::const_reverse_iterator ByteArray::crend() const noexcept { return m_array.crend(); } + /*! + * \brief Checks whether the byte array is empty + * \return true if byte array is empty + */ + inline bool ByteArray::empty() const noexcept { return m_array.empty(); } + /*! + * \brief Returns an iterator pointing to the end of the string + * \return End of the string + */ + inline ByteArray::iterator ByteArray::end() noexcept { return m_array.end(); } + /*! + * \brief Returns an iterator pointing to the end of the string + * \return End of the string + */ + inline ByteArray::const_iterator ByteArray::end() const noexcept { return m_array.end(); } + /*! + * \brief Returns a reversed iterator pointing to the beggining of the string + * \return Beggining of the string + */ + inline ByteArray::reverse_iterator ByteArray::rbegin() noexcept { return m_array.rbegin(); } + /*! + * \brief Returns a reversed iterator pointing to the beggining of the string + * \return Beggining of the string + */ + inline ByteArray::const_reverse_iterator ByteArray::rbegin() const noexcept { return m_array.rbegin(); } + /*! + * \brief Returns a reversed iterator pointing to the end of the string + * \return End of the string + */ + inline ByteArray::reverse_iterator ByteArray::rend() noexcept { return m_array.rend(); } + /*! + * \brief Gets the size of the byte array + * \return Size of the byte array + */ + inline ByteArray::size_type ByteArray::size() const noexcept { return GetSize(); } + /*! + * \brief Gets the ith byte + * \return A reference to the byte at the ith position + * + * \remark Produces a NazaraAssert if pos is greather than the size + */ + inline ByteArray::reference ByteArray::operator[](size_type pos) { NazaraAssert(pos < GetSize(), "Index out of range"); @@ -290,6 +633,13 @@ namespace Nz return m_array[pos]; } + /*! + * \brief Gets the ith byte + * \return A constant reference to the byte at the ith position + * + * \remark Produces a NazaraAssert if pos is greather than the size + */ + inline ByteArray::const_reference ByteArray::operator[](size_type pos) const { NazaraAssert(pos < GetSize(), "Index out of range"); @@ -297,6 +647,13 @@ namespace Nz return m_array[pos]; } + /*! + * \brief Concatenates the byte array to another + * \return ByteArray which is the result of the concatenation + * + * \param other ByteArray to add + */ + inline ByteArray ByteArray::operator+(const ByteArray& other) const { ByteArray tmp(*this); @@ -305,6 +662,13 @@ namespace Nz return tmp; } + /*! + * \brief Concatenates the byte array to this byte array + * \return A reference to this + * + * \param other ByteArray to add + */ + inline ByteArray& ByteArray::operator+=(const ByteArray& other) { Append(other); @@ -312,31 +676,79 @@ namespace Nz return *this; } + /*! + * \brief Checks whether the first byte array is equal to the second byte array + * \return true if it is the case + * + * \param first ByteArray to compare in left hand side + * \param second ByteArray to compare in right hand side + */ + inline bool ByteArray::operator==(const ByteArray& rhs) const { return m_array == rhs.m_array; } + /*! + * \brief Checks whether the first byte array is equal to the second byte array + * \return false if it is the case + * + * \param first ByteArray to compare in left hand side + * \param second ByteArray to compare in right hand side + */ + inline bool ByteArray::operator!=(const ByteArray& rhs) const { return !operator==(rhs); } + /*! + * \brief Checks whether the first byte array is less than the second byte array + * \return true if it is the case + * + * \param first ByteArray to compare in left hand side + * \param second ByteArray to compare in right hand side + */ + inline bool ByteArray::operator<(const ByteArray& rhs) const { return m_array < rhs.m_array; } + /*! + * \brief Checks whether the first byte array is less or equal than the second byte array + * \return true if it is the case + * + * \param first ByteArray to compare in left hand side + * \param second ByteArray to compare in right hand side + */ + inline bool ByteArray::operator<=(const ByteArray& rhs) const { return m_array <= rhs.m_array; } + /*! + * \brief Checks whether the first byte array is greather than the second byte array + * \return true if it is the case + * + * \param first ByteArray to compare in left hand side + * \param second ByteArray to compare in right hand side + */ + inline bool ByteArray::operator>(const ByteArray& rhs) const { return m_array > rhs.m_array; } + /*! + * \brief Checks whether the first byte array is greather or equal than the second byte array + * \return true if it is the case + * + * \param first ByteArray to compare in left hand side + * \param second ByteArray to compare in right hand side + */ + inline bool ByteArray::operator>=(const ByteArray& rhs) const { return m_array >= rhs.m_array; @@ -351,6 +763,13 @@ namespace Nz namespace std { + /*! + * \brief Swaps two byte arrays, specialisation of std + * + * \param lhs First byte array + * \param rhs Second byte array + */ + inline void swap(Nz::ByteArray& lhs, Nz::ByteArray& rhs) { lhs.Swap(rhs); diff --git a/include/Nazara/Core/ByteStream.inl b/include/Nazara/Core/ByteStream.inl index f6e765175..83062d3ba 100644 --- a/include/Nazara/Core/ByteStream.inl +++ b/include/Nazara/Core/ByteStream.inl @@ -7,11 +7,25 @@ namespace Nz { + /*! + * \brief Constructs a ByteStream object with a stream + * + * \remark Produces a NazaraAssert if stream is invalid + */ + inline ByteStream::ByteStream(Stream* stream) { + NazaraAssert(stream, "Invalid stream"); + m_context.stream = stream; } + /*! + * \brief Constructs a ByteStream object by move semantic + * + * \param stream ByteStream to move into this + */ + inline ByteStream::ByteStream(ByteStream&& stream) : m_ownedStream(std::move(stream.m_ownedStream)), m_context(stream.m_context) @@ -19,17 +33,35 @@ namespace Nz stream.m_context.stream = nullptr; } + /*! + * \brief Destructs the object and calls FlushBits + * + * \remark Produces a NazaraWarning if flush did not work + * + * \see FlushBits + */ + inline ByteStream::~ByteStream() { if (!FlushBits()) NazaraWarning("Failed to flush bits at serializer destruction"); } + /*! + * \brief Gets the stream endianness + * \return Type of the endianness + */ + inline Endianness ByteStream::GetDataEndianness() const { return m_context.endianness; } + /*! + * \brief Gets the size of the byte stream + * \return Size of the stream + */ + inline Nz::UInt64 ByteStream::GetSize() const { if (m_context.stream) @@ -38,11 +70,21 @@ namespace Nz return 0; } + /*! + * \brief Gets the internal stream + * \return Internal stream + */ + inline Stream* ByteStream::GetStream() const { return m_context.stream; } + /*! + * \brief Flushes the stream + * \return true if flushing is successful + */ + inline bool ByteStream::FlushBits() { if (!m_context.stream) @@ -59,6 +101,14 @@ namespace Nz return true; } + /*! + * \brief Reads data + * \return Number of data read + * + * \param buffer Preallocated buffer to contain information read + * \param size Size of the read and thus of the buffer + */ + inline std::size_t ByteStream::Read(void* ptr, std::size_t size) { if (!m_context.stream) @@ -68,13 +118,29 @@ namespace Nz return m_context.stream->Read(ptr, size); } + /*! + * \brief Sets the stream endianness + * + * \param Type of the endianness + */ + inline void ByteStream::SetDataEndianness(Endianness endiannes) { m_context.endianness = endiannes; } + /*! + * \brief Sets this with a stream + * + * \param stream Stream existing + * + * \remark Produces a NazaraAssert if stream is invalid + */ + inline void ByteStream::SetStream(Stream* stream) { + NazaraAssert(stream, "Invalid stream"); + // We don't want to lose some bits.. FlushBits(); @@ -82,6 +148,16 @@ namespace Nz m_ownedStream.reset(); } + /*! + * \brief Writes data + * \return Number of data written + * + * \param buffer Preallocated buffer containing information to write + * \param size Size of the writting and thus of the buffer + * + * \remark Produces a NazaraAssert if buffer is nullptr + */ + inline void ByteStream::Write(const void* data, std::size_t size) { if (!m_context.stream) @@ -91,6 +167,15 @@ namespace Nz m_context.stream->Write(data, size); } + /*! + * \brief Outputs a data from the stream + * \return A reference to this + * + * \param value Value to unserialize + * + * \remark Produces a NazaraError if unserialization failed + */ + template ByteStream& ByteStream::operator>>(T& value) { @@ -103,6 +188,15 @@ namespace Nz return *this; } + /*! + * \brief Adds the data to the stream + * \return A reference to this + * + * \param value Value to serialize + * + * \remark Produces a NazaraError if serialization failed + */ + template ByteStream& ByteStream::operator<<(const T& value) { @@ -115,6 +209,13 @@ namespace Nz return *this; } + /*! + * \brief Moves the other byte stream into this + * \return A reference to this + * + * \param stream ByteStream to move in this + */ + inline ByteStream& ByteStream::operator=(ByteStream&& stream) { m_context = stream.m_context; diff --git a/src/Nazara/Core/ByteArray.cpp b/src/Nazara/Core/ByteArray.cpp index cc5734822..9763e6336 100644 --- a/src/Nazara/Core/ByteArray.cpp +++ b/src/Nazara/Core/ByteArray.cpp @@ -9,6 +9,19 @@ namespace Nz { + /*! + * \class Nz::ByteArray + * \brief Core class that represents an array of bytes + */ + + /*! + * \brief Output operator + * \return The stream + * + * \param out The stream + * \param byteArray The ByteArray to output + */ + std::ostream& operator<<(std::ostream& out, const Nz::ByteArray& byteArray) { out << byteArray.ToHex(); diff --git a/src/Nazara/Core/ByteStream.cpp b/src/Nazara/Core/ByteStream.cpp index 175212b48..1b0fc853e 100644 --- a/src/Nazara/Core/ByteStream.cpp +++ b/src/Nazara/Core/ByteStream.cpp @@ -11,24 +11,61 @@ namespace Nz { + /*! + * \class Nz::ByteStream + * \brief Core class that represents a stream of bytes + */ + + /*! + * \brief Constructs a ByteStream object with a byte array + * + * \param byteArray Bytes to stream + * \param openMode Reading/writing mode for the stream + */ + ByteStream::ByteStream(ByteArray* byteArray, UInt32 openMode) : ByteStream() { SetStream(byteArray, openMode); } + /*! + * \brief Constructs a ByteStream object with a raw memory and a size + * + * \param ptr Pointer to raw memory + * \param size Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + */ + ByteStream::ByteStream(void* ptr, Nz::UInt64 size) : ByteStream() { SetStream(ptr, size); } + /*! + * \brief Constructs a ByteStream object with a raw memory and a size + * + * \param ptr Constant pointer to raw memory + * \param size Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + */ + ByteStream::ByteStream(const void* ptr, Nz::UInt64 size) : ByteStream() { SetStream(ptr, size); } + /*! + * \brief Sets this with a byte array + * + * \param byteArray Bytes to stream + * \param openMode Reading/writing mode for the stream + */ + void ByteStream::SetStream(ByteArray* byteArray, UInt32 openMode) { std::unique_ptr stream(new MemoryStream(byteArray, openMode)); @@ -38,6 +75,15 @@ namespace Nz m_ownedStream = std::move(stream); } + /*! + * \brief Sets this with a raw memory and a size + * + * \param ptr Pointer to raw memory + * \param size Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + */ + void ByteStream::SetStream(void* ptr, Nz::UInt64 size) { std::unique_ptr stream(new MemoryView(ptr, size)); @@ -47,6 +93,15 @@ namespace Nz m_ownedStream = std::move(stream); } + /*! + * \brief Sets this with a raw memory and a size + * + * \param ptr Constant pointer to raw memory + * \param size Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + */ + void ByteStream::SetStream(const void* ptr, Nz::UInt64 size) { std::unique_ptr stream(new MemoryView(ptr, size)); @@ -56,6 +111,12 @@ namespace Nz m_ownedStream = std::move(stream); } + /*! + * \brief Signal function (meant to be virtual) + * + * \remark Produces a NazaraError + */ + void ByteStream::OnEmptyStream() { NazaraError("No stream");