version 3.14.0
PIBinaryStream::wasReadError() method, remove incomplete read asserts
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user