doc stream

This commit is contained in:
2022-08-01 21:23:21 +03:00
parent 4ea5465637
commit eb91fbfc45
7 changed files with 157 additions and 58 deletions

117
doc/pages/iostream.md Normal file
View File

@@ -0,0 +1,117 @@
\~english \page iostream Input/Output stream
\~russian \page iostream Поток ввода/вывода
\~english
\~russian
%PIBinaryStream представляет собой интерфейс бинарной сериализации.
Не может быть использован в чистом виде, только в виде миксина или
готовых классов: PIByteArray и PIIOBinaryStream.
Используется для сохранения или чтения любых данных. Простые типы читаются/пишутся
как блоки памяти, если не созданы конкретные операторы. Сложные типы
([нетривиальные](https://ru.cppreference.com/w/cpp/types/is_trivially_copyable))
обязаны иметь операторы ввода/вывода, иначе возникнет ошибка компиляции.
Также поддерживаются контейнеры с типами по таким же правилам.
Перечисления интерпретируются как int, логические типы как один байт.
Операторы сохранения добавляют данные в конец потока, а операторы извлечения
берут данные из его начала.
Для облегчения написания операторов есть макросы:
* BINARY_STREAM_FRIEND(T) - объявить операторы с доступом к приватному
содержимому типа T, необязателен;
* BINARY_STREAM_WRITE(T) - запись в поток, "s" - объект потока, "v" - объект типа T;
* BINARY_STREAM_READ(T) - чтение из потока, "s" - объект потока, "v" - объект типа T.
Пример:
\~\code
#include <pibytearray.h>
class MyType {
BINARY_STREAM_FRIEND(MyType);
public:
void setInt(int v) {m_i = v;}
int getInt() const {return m_i;}
void setString(PIString v) {m_s = v;}
PIString getString() const {return m_s;}
private:
int m_i = 0;
PIString m_s;
};
BINARY_STREAM_WRITE(MyType) {s << v.m_i << v.m_s; return s;}
BINARY_STREAM_READ (MyType) {s >> v.m_i >> v.m_s; return s;}
int main(int argc, char * argv[]) {
MyType t_read, t_write;
t_write.setInt(10);
t_write.setString("text");
PIByteArray data;
data << t_write;
piCout << data.toHex();
data >> t_read;
piCout << t_read.getInt() << t_read.getString();
piCout << data.toHex();
}
\endcode
\~english Result:
\~russian Результат:
\~\code
0a000000040000007400650078007400
10 text
\endcode
\~english
For store/restore custom data blocks this is PIMemoryBlock class. Stream
operators of this class simply store/restore data block to/from stream:
\~russian
Для сохранения/извлечения блоков произвольных данных используется класс PIMemoryBlock.
Потоковые операторы для него просто сохраняют/извлекают блоки байтов в/из потока:
\~\code
float a_read[10], a_write[10];
for (int i = 0; i < 10; ++i) {
a_read [i] = 0.f;
a_write[i] = i / 10.f;
}
PIByteArray data;
data << PIMemoryBlock(a_write, 10 * sizeof(float));
piCout << data.toHex();
data >> PIMemoryBlock(a_read, 10 * sizeof(float));
for (int i = 0; i < 10; ++i)
piCout << a_read[i];
\endcode
\~english Result:
\~russian Результат:
\~\code
00000000cdcccc3dcdcc4c3e9a99993ecdcccc3e0000003f9a99193f3333333fcdcc4c3f6666663f
0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
\endcode

View File

@@ -54,8 +54,10 @@
//! bool binaryStreamTakeImp (void * d, size_t s); //! bool binaryStreamTakeImp (void * d, size_t s);
//! ssize_t binaryStreamSizeImp () const; //! ssize_t binaryStreamSizeImp () const;
//! \endcode //! \endcode
//! \~english function binaryStreamSizeImp must return -1 if size unknown //! \~english Function binaryStreamSizeImp should return -1 if size unknown.
//! \~russian функция binaryStreamSizeImp должна возвращать -1 если нет информации о размере //! \~russian Функция binaryStreamSizeImp должна возвращать -1 если нет информации о размере.
//! \~english See details \ref iostream.
//! \~russian Подробнее \ref iostream.
template<typename P> template<typename P>
class PIBinaryStream { class PIBinaryStream {
public: public:
@@ -78,7 +80,7 @@ public:
//! \~russian Узнать оставшийся размер //! \~russian Узнать оставшийся размер
//!\~\details //!\~\details
//!\~russian возвращает -1 если нет информации о размере //!\~russian Возвращает -1 если нет информации о размере
ssize_t binaryStreamSize() const { ssize_t binaryStreamSize() const {
return static_cast<P*>(this)->binaryStreamSizeImp(); return static_cast<P*>(this)->binaryStreamSizeImp();
} }

View File

@@ -28,6 +28,7 @@
//! It can be constructed from any data and size. //! It can be constructed from any data and size.
//! You can use %PIByteArray as binary stream //! You can use %PIByteArray as binary stream
//! to serialize/deserialize any objects and data. //! to serialize/deserialize any objects and data.
//! See details \ref iostream.
//! This class use PIDeque<uchar> and provide some handle function //! This class use PIDeque<uchar> and provide some handle function
//! to manipulate it. //! to manipulate it.
//! \~russian //! \~russian
@@ -35,46 +36,22 @@
//! Он может быть сконструирован из любых даных. //! Он может быть сконструирован из любых даных.
//! Можно использовать %PIByteArray как потоковый объект //! Можно использовать %PIByteArray как потоковый объект
//! для сериализации/десериализации любых типов и данных. //! для сериализации/десериализации любых типов и данных.
//! Подробнее \ref iostream.
//! Этот класс использует PIDeque<uchar> и предоставляет набор //! Этот класс использует PIDeque<uchar> и предоставляет набор
//! удобных методов для работы с байтами. //! удобных методов для работы с байтами.
//! //!
//! \~english \section PIByteArray_sec0 Usage //! \~english \section PIByteArray_sec0 Usage
//! \~russian \section PIByteArray_sec0 Использование //! \~russian \section PIByteArray_sec0 Использование
//! \~english //! \~english
//! %PIByteArray can be used to store custom data and manipulate it. There are many //! %PIByteArray subclass PIBinaryStream and can be used to store custom data and manipulate it.
//! stream operators to store/restore common types to byte array. Store operators //! Store operators places data at the end of array, restore operators takes data from the beginning
//! places data at the end of array, restore operators takes data from the beginning
//! of array. //! of array.
//! In addition there are Hex and Base64 convertions //! In addition there are Hex and Base64 convertions.
//! \~russian //! \~russian
//! %PIByteArray может быть использован для сохранения любых данных и работы с ними. //! %PIByteArray наследован от PIBinaryStream и может быть использован для сохранения любых данных и работы с ними.
//! Он предоставляет множество операторов для сохранения/извлечения общих типов.
//! Операторы сохранения добавляют данные в конец массива, а операторы извлечения //! Операторы сохранения добавляют данные в конец массива, а операторы извлечения
//! берут данные из его начала. //! берут данные из его начала.
//! //! Также есть методы для преобразования в Hex и Base64.
//! \~english
//! One of the major usage of %PIByteArray is stream functions. You can form binary
//! packet from many types (also dynamic types, e.g. PIVector) with one line:
//! \~russian
//! Один из основных сценариев использования %PIByteArray - это потоковый объект.
//! Можно сформировать пакет бинарных данных из многих типов (также и контейнеров,
//! например, PIVector) в одну строку:
//! \~\snippet pibytearray.cpp 0
//!
//! \~english
//! Or you can descibe stream operator of your own type and store/restore vectors of
//! your type:
//! \~russian
//! Также можно описать операторы сохранения/извлечения для собственных типов:
//! \~\snippet pibytearray.cpp 1
//!
//! \~english
//! For store/restore custom data blocks there is PIByteArray::RawData class. Stream
//! operators of this class simply store/restore data block to/from byte array:
//! \~russian
//! Для сохранения/извлечения блоков произвольных данных используется класс PIByteArray::RawData.
//! Потоковые операторы для него просто сохраняют/извлекают блоки байтов:
//! \~\snippet pibytearray.cpp 2
//! //!
//! \~english \section PIByteArray_sec1 Attention //! \~english \section PIByteArray_sec1 Attention
//! \~russian \section PIByteArray_sec1 Внимание //! \~russian \section PIByteArray_sec1 Внимание

View File

@@ -47,8 +47,16 @@ public:
PIMemoryBlock & operator =(const PIMemoryBlock & o) {d = o.d; s = o.s; return *this;} PIMemoryBlock & operator =(const PIMemoryBlock & o) {d = o.d; s = o.s; return *this;}
//! \~english Pointer to data
//! \~russian Указатель на данные
void * data() {return d;} void * data() {return d;}
//! \~english Pointer to data
//! \~russian Указатель на данные
const void * data() const {return d;} const void * data() const {return d;}
//! \~english Size of data in bytes
//! \~russian Размер данных в байтах
int size() const {return s;} int size() const {return s;}
private: private:
@@ -57,6 +65,8 @@ private:
}; };
//! \~english Returns PIMemoryBlock from pointer to variable "ptr" with type "T"
//! \~russian Возвращает PIMemoryBlock из указателя "ptr" типа "T"
template<typename T> template<typename T>
PIMemoryBlock createMemoryBlock(const T * ptr) {return PIMemoryBlock(ptr, sizeof(T));} PIMemoryBlock createMemoryBlock(const T * ptr) {return PIMemoryBlock(ptr, sizeof(T));}

View File

@@ -175,8 +175,8 @@ public:
return readUntil(spaces); return readUntil(spaces);
} }
//! \~english //! \~english Read C-word, skip leading and until non C-identifier
//! \~russian //! \~russian Читает C-слово, пропуская начальные и до следующих символов, не являющихся C-идентификаторами
PIString readCWord() { PIString readCWord() {
static PIConstChars chars(" \t\n\r:;%$&#@!?~/*-+=.,\\\"'`[](){}<>"); static PIConstChars chars(" \t\n\r:;%$&#@!?~/*-+=.,\\\"'`[](){}<>");
return readUntil(chars); return readUntil(chars);

View File

@@ -34,6 +34,8 @@
//! \~\brief //! \~\brief
//! \~english PIBinaryStream functionality for PIIODevice. //! \~english PIBinaryStream functionality for PIIODevice.
//! \~russian Функциональность PIBinaryStream для PIIODevice. //! \~russian Функциональность PIBinaryStream для PIIODevice.
//! \~english See details \ref iostream
//! \~russian Подробнее \ref iostream
class PIP_EXPORT PIIOBinaryStream: public PIBinaryStream<PIIOBinaryStream> { class PIP_EXPORT PIIOBinaryStream: public PIBinaryStream<PIIOBinaryStream> {
public: public:

View File

@@ -1,32 +1,23 @@
#include "pip.h" #include "pip.h"
#include "piiostream.h" #include "piiostream.h"
#include "pibytearray.h"
using namespace PICoutManipulators; using namespace PICoutManipulators;
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
{ float a_read[10], a_write[10];
PIString s("0123456789"); for (int i = 0; i < 10; ++i) {
piCout << s.mid(0, -1); // s = "0123456789" a_read [i] = 0.f;
piCout << s.mid(0, 2); // s = "01" a_write[i] = i / 10.f;
piCout << s.mid(3, -1); // s = "3456789"
piCout << s.mid(3, 4); // s = "3456"
piCout << s.mid(7, 1); // s = "7"
piCout << s.mid(7, 4); // s = "789"
piCout << s.mid(-1); // s = ""
//! \endcode
//! \~\sa \a left(), \a right()
} }
//! \~\details PIByteArray data;
//! \~\code data << PIMemoryBlock(a_write, 10 * sizeof(float));
PIString s("0123456789");
s.cutMid(1, 3); piCout << data.toHex();
piCout << s; // s = "0456789"
s.cutMid(0, 2); data >> PIMemoryBlock(a_read, 10 * sizeof(float));
piCout << s; // s = "56789" for (int i = 0; i < 10; ++i)
s.cutMid(3, -1); piCout << a_read[i];
piCout << s; // s = "567"
s.cutMid(-1, -1);
piCout << s; // s = "567"
} }