version 3.14.0

PIBinaryStream::wasReadError() method, remove incomplete read asserts
This commit is contained in:
2023-08-30 12:18:04 +03:00
parent c86ec0ae82
commit 0907a3eb13
5 changed files with 118 additions and 48 deletions

View File

@@ -65,6 +65,7 @@
template<typename P>
class PIBinaryStream {
public:
//! \~english Write data
//! \~russian Записать данные
bool binaryStreamAppend(const void * d, size_t s) {
if (!static_cast<P *>(this)->binaryStreamAppendImp(d, s)) {
@@ -73,32 +74,50 @@ public:
}
return true;
}
//! \~english Read data
//! \~russian Прочитать данные
bool binaryStreamTake(void * d, size_t s) {
if (!static_cast<P *>(this)->binaryStreamTakeImp(d, s)) {
_was_read_error_ = true;
return false;
printf("[PIBinaryStream] binaryStreamTake() error\n");
}
return true;
}
//! \~russian Узнать оставшийся размер
//!\~\details
//!\~russian Возвращает -1 если нет информации о размере
//! \~english Returns remain size
//! \~russian Возвращает оставшийся размер
//! \~\details
//! \~english Returns -1 if no information about size
//! \~russian Возвращает -1 если нет информации о размере
ssize_t binaryStreamSize() const { return static_cast<const P *>(this)->binaryStreamSizeImp(); }
//! \~english Write data
//! \~russian Записать данные
template<typename T>
void binaryStreamAppend(T v) {
binaryStreamAppend(&v, sizeof(v));
}
//! \~english Read int
//! \~russian Прочитать int
int binaryStreamTakeInt() {
int r = 0;
binaryStreamTake(&r, sizeof(r));
return r;
}
//! \~english Returns whether there has been an incomplete read since last \a resetReadError() or after the stream was created
//! \~russian Возвращает было ли неполное чтение с момента последнего вызова \a resetReadError()
bool wasReadError() const { return _was_read_error_; }
//! \~english Reset incomplete read flag
//! \~russian Сбрасывает флаг неполного чтения
void resetReadError() { _was_read_error_ = false; }
private:
bool _was_read_error_ = false;
};
@@ -305,7 +324,6 @@ template<typename P,
inline PIBinaryStreamTrivialRef<P> operator>>(PIBinaryStream<P> & s, T & v) {
if (!s.binaryStreamTake(&v, sizeof(v))) {
printf("error with %s\n", __PIP_TYPENAME__(T));
assert(false);
}
return s;
}
@@ -322,25 +340,41 @@ template<typename P,
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
// piCout << ">> vector trivial default";
int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) {
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
v.clear();
return s;
}
v._resizeRaw(sz);
if (!s.binaryStreamTake(v.data(), sz * sizeof(T))) {
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
assert(false);
v.clear();
}
return s;
}
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
!std::is_same<decltype(std::declval<PIBinaryStream<P> &>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
// piCout << ">> vector trivial custom";
int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) {
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
v.clear();
return s;
}
v._resizeRaw(sz);
for (int i = 0; i < sz; ++i)
for (int i = 0; i < sz; ++i) {
s >> v[i];
if (s.wasReadError()) {
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
v.clear();
return s;
}
}
return s;
}
@@ -348,33 +382,49 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
//! \~english Restore operator for PIDeque of any trivial copyable type
//! \~russian Оператор извлечения для PIDeque тривиальных типов
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
std::is_same<decltype(std::declval<PIBinaryStream<P> &>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
// piCout << ">> deque trivial default";
int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) {
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
v.clear();
return s;
}
v._resizeRaw(sz);
if (!s.binaryStreamTake(v.data(), sz * sizeof(T))) {
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
assert(false);
v.clear();
}
return s;
}
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
!std::is_same<decltype(std::declval<PIBinaryStream<P> &>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
// piCout << ">> deque trivial custom";
int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) {
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
v.clear();
return s;
}
v._resizeRaw(sz);
for (int i = 0; i < sz; ++i)
for (int i = 0; i < sz; ++i) {
s >> v[i];
if (s.wasReadError()) {
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
v.clear();
return s;
}
}
return s;
}
@@ -382,9 +432,9 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
//! \~english Restore operator for PIVector2D of any trivial copyable type
//! \~russian Оператор извлечения для PIVector2D тривиальных типов
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
std::is_same<decltype(std::declval<PIBinaryStream<P> &>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
@@ -392,17 +442,22 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector2D<T> & v)
int r, c;
r = s.binaryStreamTakeInt();
c = s.binaryStreamTakeInt();
if (s.wasReadError()) {
printf("error with PIVector2D<%s>\n", __PIP_TYPENAME__(T));
v.clear();
return s;
}
v._resizeRaw(r, c);
if (!s.binaryStreamTake(v.data(), v.size() * sizeof(T))) {
printf("error with PIVector2D<%s>\n", __PIP_TYPENAME__(T));
assert(false);
v.clear();
}
return s;
}
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
!std::is_same<decltype(std::declval<PIBinaryStream<P> &>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
@@ -481,14 +536,15 @@ inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIVector2D<T>
//! \~russian Оператор извлечения для PIVector сложных типов
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
// piCout << ">> vector complex";
/*if (s.size_s() < 4) {
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
assert(s.size_s() >= 4);
}*/
v.resize(s.binaryStreamTakeInt());
for (size_t i = 0; i < v.size(); ++i)
for (size_t i = 0; i < v.size(); ++i) {
s >> v[i];
if (s.wasReadError()) {
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
v.clear();
return s;
}
}
return s;
}
@@ -497,14 +553,15 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
//! \~russian Оператор извлечения для PIDeque сложных типов
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
// piCout << ">> deque complex";
/*if (s.size_s() < 4) {
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
assert(s.size_s() >= 4);
}*/
v.resize(s.binaryStreamTakeInt());
for (size_t i = 0; i < v.size(); ++i)
for (size_t i = 0; i < v.size(); ++i) {
s >> v[i];
if (s.wasReadError()) {
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
v.clear();
return s;
}
}
return s;
}
@@ -513,11 +570,6 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
//! \~russian Оператор извлечения для PIVector2D сложных типов
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
// piCout << ">> vector2d complex";
/*if (s.size_s() < 8) {
printf("error with PIVecto2Dr<%s>\n", __PIP_TYPENAME__(T));
assert(s.size_s() >= 8);
}*/
int r, c;
PIVector<T> tmp;
r = s.binaryStreamTakeInt();
@@ -549,19 +601,25 @@ inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIMap<Key, T>
//! \~russian Оператор извлечения
template<typename P, typename Key, typename T>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIMap<Key, T> & v) {
/*if (s.size_s() < 4) {
printf("error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
assert(s.size_s() >= 4);
}*/
int sz = s.binaryStreamTakeInt();
v.pim_index.resize(sz);
int ind = 0;
for (int i = 0; i < sz; ++i) {
ind = s.binaryStreamTakeInt();
s >> v.pim_index[i].key;
if (s.wasReadError()) {
printf("error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
v.clear();
return s;
}
v.pim_index[i].index = ind;
}
s >> v.pim_content;
if (s.wasReadError()) {
printf("error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
v.clear();
return s;
}
if (v.pim_content.size_s() != v.pim_index.size_s()) {
piCout << "Warning: loaded invalid PIMap, clear";
v.clear();