@@ -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 ( ) ;