split the buffer stream out of ACN::PDU
This commit is contained in:
parent
dcbd735476
commit
099ea5a98a
|
@ -8,9 +8,10 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG")
|
||||
endif()
|
||||
|
||||
add_subdirectory(protocol)
|
||||
add_subdirectory(platform)
|
||||
add_subdirectory(example)
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(platform)
|
||||
add_subdirectory(protocol)
|
||||
add_subdirectory(test)
|
||||
|
||||
#if (CMAKE_BUILD_TYPE MATCHES "^[Rr]elease")
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
add_subdirectory(bufferstream)
|
|
@ -0,0 +1,14 @@
|
|||
project(bufferstream VERSION 0.1.0 LANGUAGES CXX)
|
||||
|
||||
add_library(${PROJECT_NAME} SHARED)
|
||||
add_library(LCP::BufferStream ALIAS ${PROJECT_NAME})
|
||||
|
||||
target_sources(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
bufferstream.h
|
||||
PRIVATE
|
||||
bufferstream.cpp
|
||||
)
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION})
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
bufferstream.cpp
|
||||
|
||||
Copyright (c) 2023 Kevin Matz (kevin.matz@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "bufferstream.h"
|
||||
|
||||
/**
|
||||
* @brief bufferstream::bufferstream
|
||||
* @param p
|
||||
* @param l
|
||||
*/
|
||||
bufferstream::bufferstream(uint8_t * p, std::streamsize l)
|
||||
: std::basic_streambuf<uint8_t>()
|
||||
, std::basic_iostream<uint8_t>(this)
|
||||
{
|
||||
setg(p, p, p + l);
|
||||
setp(p, p + l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::available
|
||||
* @return
|
||||
*/
|
||||
uint32_t bufferstream::available()
|
||||
{
|
||||
return in_avail();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::data
|
||||
* @return
|
||||
*/
|
||||
uint8_t * bufferstream::data()
|
||||
{
|
||||
return gptr();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::size
|
||||
* @return
|
||||
*/
|
||||
uint32_t bufferstream::size()
|
||||
{
|
||||
return pptr() - pbase();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::base
|
||||
* @return
|
||||
*/
|
||||
uint8_t * bufferstream::base()
|
||||
{
|
||||
return pbase();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator >>
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator>> (uint8_t& val)
|
||||
{
|
||||
val = readType<uint8_t>();
|
||||
return *this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator >>
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator>> (uint16_t& val)
|
||||
{
|
||||
val = readType<uint16_t>();
|
||||
return *this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator >>
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator>> (uint32_t& val)
|
||||
{
|
||||
val = readType<uint32_t>();
|
||||
return *this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator >>
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator>> (uint64_t& val)
|
||||
{
|
||||
val = readType<uint64_t>();
|
||||
return *this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator >>
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator>> (int8_t& val)
|
||||
{
|
||||
val = readType<int8_t>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator >>
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator>> (int16_t& val)
|
||||
{
|
||||
val = readType<int16_t>();
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator >>
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator>> (int32_t& val)
|
||||
{
|
||||
val = readType<int32_t>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator >>
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator>> (int64_t& val)
|
||||
{
|
||||
val = readType<int64_t>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator <<
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator<< (const int8_t& val)
|
||||
{
|
||||
put(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator <<
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator<< (const int16_t& val)
|
||||
{
|
||||
writeType<int16_t>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator <<
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator<< (const int32_t& val)
|
||||
{
|
||||
writeType<int32_t>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator <<
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator<< (const int64_t& val)
|
||||
{
|
||||
writeType<int64_t>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator <<
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator<< (const uint8_t& val)
|
||||
{
|
||||
writeType<uint8_t>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator <<
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator<< (const uint16_t& val)
|
||||
{
|
||||
writeType<uint16_t>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator <<
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator<< (const uint32_t& val)
|
||||
{
|
||||
writeType<uint32_t>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator <<
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator<< (const uint64_t& val)
|
||||
{
|
||||
writeType<uint64_t>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator >>
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator>> (streamable& obj)
|
||||
{
|
||||
obj.iStream(shared_from_this());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::operator <<
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
bufferstream& bufferstream::operator<< (const streamable& obj)
|
||||
{
|
||||
obj.oStream(shared_from_this());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::readString
|
||||
* @param str std::string to which the read string will be appended.
|
||||
* @param fixed_length this many bytes will be read from the stream. If 0, all
|
||||
* available bytes on the stream will be used to construct the appended string.
|
||||
*/
|
||||
void bufferstream::readString(std::string &str, const int fixed_length)
|
||||
{
|
||||
// if fixed_length == 0, use all available data on the stream
|
||||
if (!fixed_length)
|
||||
{
|
||||
str += std::string(reinterpret_cast<char*>(data()), available());
|
||||
return setstate(std::ios_base::eofbit);
|
||||
}
|
||||
|
||||
// otherwise, construct a buffer and read into that.
|
||||
uint8_t buffer[fixed_length];
|
||||
read(buffer, fixed_length);
|
||||
if (gcount() != fixed_length)
|
||||
return setstate(std::ios_base::failbit);
|
||||
str += std::string(reinterpret_cast<char*>(buffer));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bufferstream::writeString
|
||||
* @param str
|
||||
* @param fixed_length write this length to the stream, padding with null
|
||||
* if str is shorter than fixed_length. If 0, will write the unrestricted
|
||||
* contents of str.
|
||||
* @param terminated If true, the last byte of fixed_length is guaranteed to
|
||||
* be a 0 (null) byte.
|
||||
*/
|
||||
void bufferstream::writeString(const std::string &str, const size_t fixed_length,
|
||||
const bool terminated)
|
||||
{
|
||||
// fixed_length == 0 means dynamic length.
|
||||
bool fixed = fixed_length > 0 ? true : false;
|
||||
|
||||
// fixed length strings restricted to fixed_lengh characters
|
||||
size_t maxlen = fixed ? fixed_length : str.size();
|
||||
|
||||
// write no more of the string than is available
|
||||
size_t wrtlen = str.size() < maxlen ? str.size() : maxlen;
|
||||
|
||||
// terminated fixed-length strings get a guaranteed padding byte
|
||||
if (fixed && terminated && wrtlen == maxlen)
|
||||
--wrtlen;
|
||||
|
||||
// output the correct ammount of data from the string
|
||||
write(reinterpret_cast<const uint8_t*>(str.data()), wrtlen);
|
||||
|
||||
// output any required padding bytes
|
||||
for (size_t i = wrtlen; i < maxlen; i++)
|
||||
put(0);
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
bufferstream.h
|
||||
|
||||
Copyright (c) 2023 Kevin Matz (kevin.matz@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
struct streamable;
|
||||
|
||||
/**
|
||||
* @brief Input/Output stream for unsigned 8-bit buffers
|
||||
*/
|
||||
class bufferstream
|
||||
: public std::enable_shared_from_this<bufferstream>
|
||||
, private std::basic_streambuf<uint8_t>
|
||||
, public std::basic_iostream<uint8_t>
|
||||
{
|
||||
public:
|
||||
bufferstream(uint8_t * p, std::streamsize l);
|
||||
|
||||
// input sequence
|
||||
uint32_t available();
|
||||
uint8_t * data();
|
||||
|
||||
// output sequence
|
||||
uint32_t size();
|
||||
uint8_t * base();
|
||||
|
||||
// unsigned integer
|
||||
bufferstream& operator>> (uint8_t& val);
|
||||
bufferstream& operator>> (uint16_t& val);
|
||||
bufferstream& operator>> (uint32_t& val);
|
||||
bufferstream& operator>> (uint64_t& val);
|
||||
bufferstream& operator<< (const uint8_t& val);
|
||||
bufferstream& operator<< (const uint16_t& val);
|
||||
bufferstream& operator<< (const uint32_t& val);
|
||||
bufferstream& operator<< (const uint64_t& val);
|
||||
|
||||
// signed integer
|
||||
bufferstream& operator>> (int8_t& val);
|
||||
bufferstream& operator>> (int16_t& val);
|
||||
bufferstream& operator>> (int32_t& val);
|
||||
bufferstream& operator>> (int64_t& val);
|
||||
bufferstream& operator<< (const int8_t& val);
|
||||
bufferstream& operator<< (const int16_t& val);
|
||||
bufferstream& operator<< (const int32_t& val);
|
||||
bufferstream& operator<< (const int64_t& val);
|
||||
|
||||
// stream objects
|
||||
bufferstream& operator>> (streamable& obj);
|
||||
bufferstream& operator<< (const streamable& obj);
|
||||
|
||||
// strings
|
||||
void readString(std::string& str, const int fixed_length = 0);
|
||||
void writeString(const std::string& str, const size_t fixed_length = 0,
|
||||
const bool terminated = true);
|
||||
|
||||
// reinterpreted i/o
|
||||
/**
|
||||
* @brief readType
|
||||
* @return T
|
||||
*/
|
||||
template<typename T>
|
||||
T readType()
|
||||
{
|
||||
if (in_avail() < sizeof(T))
|
||||
setstate(std::ios_base::failbit);
|
||||
if (!good())
|
||||
return 0;
|
||||
T ret = 0;
|
||||
auto data = reinterpret_cast<uint8_t*>(&ret);
|
||||
for (int i = sizeof(T); --i >= 0; )
|
||||
data[i] = get();
|
||||
if (!in_avail())
|
||||
setstate(std::ios_base::eofbit);
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief writeType
|
||||
* @param val
|
||||
*/
|
||||
template<typename T>
|
||||
void writeType (const T& val)
|
||||
{
|
||||
auto data = reinterpret_cast<const uint8_t*>(&val);
|
||||
for (int i = sizeof(T); --i >= 0; )
|
||||
put(data[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The inheritable base of data objects that can be read from and written to a bufferstream.
|
||||
*/
|
||||
struct streamable
|
||||
{
|
||||
virtual ~streamable() {};
|
||||
/**
|
||||
* @brief streamSize
|
||||
* @return length (count of octets) on the wire
|
||||
*/
|
||||
virtual size_t streamSize() const = 0;
|
||||
/**
|
||||
* @brief fill structure data from input stream
|
||||
*/
|
||||
virtual void iStream(std::shared_ptr<bufferstream>) = 0;
|
||||
/**
|
||||
* @brief write structure data to output stream
|
||||
*/
|
||||
virtual void oStream(std::shared_ptr<bufferstream>) const = 0;
|
||||
};
|
Loading…
Reference in New Issue