2024-08-23 20:29:07 +02:00
# include "IfcEntityInstanceData.h"
# include "IfcBaseClass.h"
2025-02-21 16:12:16 +01:00
# include "IfcFile.h"
2024-08-23 20:29:07 +02:00
// @todo is size() still needed?
class SizeVisitor {
public :
typedef int result_type ;
int operator ( ) ( const Blank & /*i*/ ) const { return - 1 ; }
int operator ( ) ( const Derived & /*i*/ ) const { return - 1 ; }
int operator ( ) ( const int & /*i*/ ) const { return - 1 ; }
int operator ( ) ( const bool & /*i*/ ) const { return - 1 ; }
int operator ( ) ( const boost : : logic : : tribool & /*i*/ ) const { return - 1 ; }
int operator ( ) ( const double & /*i*/ ) const { return - 1 ; }
int operator ( ) ( const std : : string & /*i*/ ) const { return - 1 ; }
int operator ( ) ( const boost : : dynamic_bitset < > & /*i*/ ) const { return - 1 ; }
int operator ( ) ( const empty_aggregate_t & /*unused*/ ) const { return 0 ; }
int operator ( ) ( const empty_aggregate_of_aggregate_t & /*unused*/ ) const { return 0 ; }
int operator ( ) ( const std : : vector < int > & i ) const { return ( int ) i . size ( ) ; }
int operator ( ) ( const std : : vector < double > & i ) const { return ( int ) i . size ( ) ; }
int operator ( ) ( const std : : vector < std : : vector < int > > & i ) const { return ( int ) i . size ( ) ; }
int operator ( ) ( const std : : vector < std : : vector < double > > & i ) const { return ( int ) i . size ( ) ; }
int operator ( ) ( const std : : vector < std : : string > & i ) const { return ( int ) i . size ( ) ; }
int operator ( ) ( const std : : vector < boost : : dynamic_bitset < > > & i ) const { return ( int ) i . size ( ) ; }
int operator ( ) ( const EnumerationReference & /*i*/ ) const { return - 1 ; }
int operator ( ) ( const IfcUtil : : IfcBaseClass * const & /*i*/ ) const { return - 1 ; }
int operator ( ) ( const aggregate_of_instance : : ptr & i ) const { return i - > size ( ) ; }
int operator ( ) ( const aggregate_of_aggregate_of_instance : : ptr & i ) const { return i - > size ( ) ; }
} ;
2025-02-21 16:12:16 +01:00
namespace {
template < typename T >
inline T dispatch_get_ ( AttributeValue : : pointer_type array_ , uint8_t storage_model_ , size_t instance_name_ , uint8_t index_ )
{
if ( storage_model_ = = 0 ) {
return array_ . storage_ptr - > get < T > ( index_ ) ;
} else {
T val ;
if constexpr (
// the following types cannot be directly deserialized from rocksdb, but need to be constructed
! std : : is_same_v < T , EnumerationReference > & &
! std : : is_same_v < std : : remove_cv_t < std : : remove_pointer_t < T > > , IfcUtil : : IfcBaseClass > )
{
std : : string str ;
2025-02-27 22:07:31 +01:00
array_ . db_ptr - > db - > Get ( rocksdb : : ReadOptions { } , " i| " + std : : to_string ( instance_name_ ) + " | " + std : : to_string ( index_ ) , & str ) ;
impl : : deserialize ( array_ . db_ptr , str , val ) ;
2025-02-21 16:12:16 +01:00
}
return val ;
}
}
template < typename T >
inline bool dispatch_has_ ( AttributeValue : : pointer_type array_ , uint8_t storage_model_ , size_t instance_name_ , uint8_t index_ )
{
if ( storage_model_ = = 0 ) {
return array_ . storage_ptr - > has < T > ( index_ ) ;
} else {
std : : string str ;
2025-02-27 22:07:31 +01:00
array_ . db_ptr - > db - > Get ( rocksdb : : ReadOptions { } , " i| " + std : : to_string ( instance_name_ ) + " | " + std : : to_string ( index_ ) , & str ) ;
2025-02-21 16:12:16 +01:00
return str [ 0 ] = = TypeEncoder : : encode_type < T > ( ) ;
}
}
inline size_t dispatch_index_ ( AttributeValue : : pointer_type array_ , uint8_t storage_model_ , size_t instance_name_ , uint8_t index_ )
{
if ( storage_model_ = = 0 ) {
return array_ . storage_ptr - > index ( index_ ) ;
} else {
std : : string str ;
2025-02-27 22:07:31 +01:00
array_ . db_ptr - > db - > Get ( rocksdb : : ReadOptions { } , " i| " + std : : to_string ( instance_name_ ) + " | " + std : : to_string ( index_ ) , & str ) ;
2025-02-21 16:12:16 +01:00
return ( size_t ) str [ 0 ] - ' A ' ;
}
}
}
2024-08-23 20:29:07 +02:00
AttributeValue : : operator int ( ) const
{
2025-02-21 16:12:16 +01:00
return dispatch_get_ < int > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
AttributeValue : : operator bool ( ) const
{
2025-02-21 16:12:16 +01:00
return dispatch_get_ < bool > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
AttributeValue : : operator double ( ) const
{
2025-02-21 16:12:16 +01:00
return dispatch_get_ < double > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
AttributeValue : : operator boost : : logic : : tribool ( ) const
{
2025-02-21 16:12:16 +01:00
if ( dispatch_has_ < bool > ( array_ , storage_model_ , instance_name_ , index_ ) ) {
return dispatch_get_ < bool > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
2025-02-21 16:12:16 +01:00
return dispatch_get_ < boost : : logic : : tribool > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
AttributeValue : : operator std : : string ( ) const
{
2025-02-21 16:12:16 +01:00
if ( dispatch_has_ < EnumerationReference > ( array_ , storage_model_ , instance_name_ , index_ ) ) {
2024-08-23 20:29:07 +02:00
// @todo this is silly, but the way things currently work,
// @todo also we don't really need to store a reference to the enumeration type, when this same type is already stored on the definition of the entity and no other value can be provided.
2025-02-21 16:12:16 +01:00
if ( storage_model_ = = 0 ) {
return dispatch_get_ < EnumerationReference > ( array_ , storage_model_ , instance_name_ , index_ ) . value ( ) ;
} else {
std : : string str ;
2025-02-27 22:07:31 +01:00
array_ . db_ptr - > db - > Get ( rocksdb : : ReadOptions { } , " i| " + std : : to_string ( instance_name_ ) + " | " + std : : to_string ( index_ ) , & str ) ;
2025-02-21 16:12:16 +01:00
size_t v ;
memcpy ( & v , str . data ( ) + 1 , sizeof ( size_t ) ) ;
auto decl = schema_ - > declarations ( ) [ v ] - > as_enumeration_type ( ) ;
2025-02-27 22:07:31 +01:00
memcpy ( & v , str . data ( ) + 1 + sizeof ( size_t ) , sizeof ( size_t ) ) ;
2025-02-21 16:12:16 +01:00
return decl - > lookup_enum_value ( v ) ;
}
}
return dispatch_get_ < std : : string > ( array_ , storage_model_ , instance_name_ , index_ ) ;
}
AttributeValue : : operator EnumerationReference ( ) const
{
if ( storage_model_ = = 0 ) {
return dispatch_get_ < EnumerationReference > ( array_ , storage_model_ , instance_name_ , index_ ) ;
} else {
std : : string str ;
2025-02-27 22:07:31 +01:00
array_ . db_ptr - > db - > Get ( rocksdb : : ReadOptions { } , " i| " + std : : to_string ( instance_name_ ) + " | " + std : : to_string ( index_ ) , & str ) ;
2025-02-21 16:12:16 +01:00
size_t v ;
memcpy ( & v , str . data ( ) + 1 , sizeof ( size_t ) ) ;
auto decl = schema_ - > declarations ( ) [ v ] - > as_enumeration_type ( ) ;
memcpy ( & v , str . data ( ) + 5 , sizeof ( size_t ) ) ;
return EnumerationReference ( decl , v ) ;
2024-08-23 20:29:07 +02:00
}
}
AttributeValue : : operator boost : : dynamic_bitset < > ( ) const
{
2025-02-21 16:12:16 +01:00
return dispatch_get_ < boost : : dynamic_bitset < > > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
AttributeValue : : operator IfcUtil : : IfcBaseClass * ( ) const
{
2025-02-21 16:12:16 +01:00
if ( storage_model_ = = 0 ) {
return dispatch_get_ < IfcUtil : : IfcBaseClass * > ( array_ , storage_model_ , instance_name_ , index_ ) ;
} else {
std : : string str ;
2025-02-27 22:07:31 +01:00
array_ . db_ptr - > db - > Get ( rocksdb : : ReadOptions { } , " i| " + std : : to_string ( instance_name_ ) + " | " + std : : to_string ( index_ ) , & str ) ;
2025-02-21 16:12:16 +01:00
size_t v ;
2025-02-27 22:07:31 +01:00
memcpy ( & v , str . data ( ) + 2 , sizeof ( size_t ) ) ;
if ( str [ 1 ] = = ' e ' ) {
// entity reference, by #Name
return array_ . db_ptr - > assert_existance ( v , IfcParse : : impl : : rocks_db_file_storage : : by_name ) ;
} else if ( str [ 1 ] = = ' t ' ) {
// type reference by Identity
return array_ . db_ptr - > assert_existance ( v , IfcParse : : impl : : rocks_db_file_storage : : by_identity ) ;
}
2025-02-21 16:12:16 +01:00
}
2024-08-23 20:29:07 +02:00
}
AttributeValue : : operator std : : vector < int > ( ) const
{
2025-02-21 16:12:16 +01:00
return dispatch_get_ < std : : vector < int > > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
AttributeValue : : operator std : : vector < double > ( ) const
{
2025-02-21 16:12:16 +01:00
return dispatch_get_ < std : : vector < double > > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
AttributeValue : : operator std : : vector < std : : string > ( ) const
{
2025-02-21 16:12:16 +01:00
return dispatch_get_ < std : : vector < std : : string > > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
AttributeValue : : operator std : : vector < boost : : dynamic_bitset < > > ( ) const
{
2025-02-21 16:12:16 +01:00
return dispatch_get_ < std : : vector < boost : : dynamic_bitset < > > > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
AttributeValue : : operator boost : : shared_ptr < aggregate_of_instance > ( ) const
{
2025-02-21 16:12:16 +01:00
return dispatch_get_ < boost : : shared_ptr < aggregate_of_instance > > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
AttributeValue : : operator std : : vector < std : : vector < int > > ( ) const
{
2025-02-21 16:12:16 +01:00
return dispatch_get_ < std : : vector < std : : vector < int > > > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
AttributeValue : : operator std : : vector < std : : vector < double > > ( ) const
{
2025-02-21 16:12:16 +01:00
return dispatch_get_ < std : : vector < std : : vector < double > > > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
AttributeValue : : operator boost : : shared_ptr < aggregate_of_aggregate_of_instance > ( ) const
{
2025-02-21 16:12:16 +01:00
return dispatch_get_ < boost : : shared_ptr < aggregate_of_aggregate_of_instance > > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
bool AttributeValue : : isNull ( ) const
{
2025-02-21 16:12:16 +01:00
return dispatch_has_ < Blank > ( array_ , storage_model_ , instance_name_ , index_ ) ;
2024-08-23 20:29:07 +02:00
}
unsigned int AttributeValue : : size ( ) const
{
2025-02-21 16:12:16 +01:00
// @todo
return array_ . storage_ptr - > apply_visitor ( SizeVisitor { } , index_ ) ;
2024-08-23 20:29:07 +02:00
}
IfcUtil : : ArgumentType AttributeValue : : type ( ) const
{
2025-02-21 16:12:16 +01:00
return static_cast < IfcUtil : : ArgumentType > ( dispatch_index_ ( array_ , storage_model_ , instance_name_ , index_ ) ) ;
2024-08-23 20:29:07 +02:00
}
2025-02-25 21:29:54 +01:00
bool impl : : serialize ( std : : string & val , const IfcUtil : : IfcBaseClass * t )
{
auto s = sizeof ( size_t ) ;
val . resize ( s + 2 ) ;
val [ 0 ] = TypeEncoder : : encode_type < IfcUtil : : IfcBaseClass * > ( ) ;
// 1 = entity - stored by id (entity name)
// 2 = type - stored by identity (internal counter in class)
2025-02-27 22:07:31 +01:00
val [ 1 ] = t - > declaration ( ) . as_entity ( ) ? ' e ' : ' t ' ;
2025-02-25 21:29:54 +01:00
size_t iden = t - > declaration ( ) . as_entity ( ) ? t - > id ( ) : t - > identity ( ) ;
memcpy ( val . data ( ) + 2 , & iden , s ) ;
return true ;
}
bool impl : : serialize ( std : : string & val , const EnumerationReference & v )
{
auto s = sizeof ( size_t ) ;
val . resize ( s * 2 + 1 ) ;
val [ 0 ] = TypeEncoder : : encode_type < EnumerationReference > ( ) ;
size_t vv = v . enumeration ( ) - > index_in_schema ( ) ;
memcpy ( val . data ( ) + 1 , & vv , sizeof ( size_t ) ) ;
vv = v . index ( ) ;
2025-02-27 22:07:31 +01:00
memcpy ( val . data ( ) + 1 + sizeof ( size_t ) , & vv , sizeof ( size_t ) ) ;
2025-02-25 21:29:54 +01:00
return true ;
}
bool impl : : serialize ( std : : string & val , const aggregate_of_instance : : ptr & t )
{
2025-02-27 22:07:31 +01:00
// no attempt at alignment
val . resize ( t - > size ( ) * ( sizeof ( size_t ) + 1 ) + 1 ) ;
val [ 0 ] = TypeEncoder : : encode_type < EnumerationReference > ( ) ;
char * ptr = val . data ( ) + 1 ;
for ( auto it = t - > begin ( ) ; it ! = t - > end ( ) ; + + it ) {
* ptr = ( * it ) - > declaration ( ) . as_entity ( ) ? ' e ' : ' t ' ;
ptr + + ;
size_t iden = ( * it ) - > declaration ( ) . as_entity ( ) ? ( * it ) - > id ( ) : ( * it ) - > identity ( ) ;
memcpy ( ptr , & iden , sizeof ( size_t ) ) ;
ptr + = sizeof ( size_t ) ;
}
return true ;
2025-02-25 21:29:54 +01:00
}
bool impl : : serialize ( std : : string & val , const aggregate_of_aggregate_of_instance : : ptr & t )
{
return false ;
}
bool impl : : serialize ( std : : string & val , const Blank & t )
{
return true ;
}
bool impl : : serialize ( std : : string & val , const Derived & t )
{
return true ;
}
bool impl : : serialize ( std : : string & val , const empty_aggregate_t & t )
{
return false ;
}
bool impl : : serialize ( std : : string & val , const empty_aggregate_of_aggregate_t & t )
{
return false ;
}
bool impl : : serialize ( std : : string & val , const boost : : logic : : tribool & t )
{
using T = char ;
T tt = t = = boost : : logic : : indeterminate ? 2 : t ? 1 : 0 ;
val . resize ( sizeof ( T ) + 1 ) ;
val [ 0 ] = TypeEncoder : : encode_type < T > ( ) ;
memcpy ( val . data ( ) + 1 , & tt , sizeof ( T ) ) ;
return true ;
}
bool impl : : serialize ( std : : string & val , const boost : : dynamic_bitset < > & t )
{
return false ;
}
2025-02-27 22:07:31 +01:00
bool impl : : deserialize ( IfcParse : : impl : : rocks_db_file_storage * , const std : : string & val , boost : : logic : : tribool & t ) {
2025-02-25 21:29:54 +01:00
if ( val [ 0 ] ! = TypeEncoder : : encode_type < boost : : logic : : tribool > ( ) ) {
return false ;
}
if ( val [ 1 ] = = 0 ) {
t = false ;
} else if ( val [ 1 ] = = 1 ) {
t = true ;
} else if ( val [ 1 ] = = 2 ) {
t = boost : : logic : : indeterminate ;
} else {
return false ;
}
}
2025-02-27 22:07:31 +01:00
bool impl : : deserialize ( IfcParse : : impl : : rocks_db_file_storage * , const std : : string & val , boost : : dynamic_bitset < > & t ) {
2025-02-25 21:29:54 +01:00
if ( val [ 0 ] ! = TypeEncoder : : encode_type < boost : : dynamic_bitset < > > ( ) ) {
return false ;
}
t = boost : : dynamic_bitset < > ( val . substr ( 1 ) ) ;
return true ;
}
2025-02-27 22:07:31 +01:00
bool impl : : deserialize ( IfcParse : : impl : : rocks_db_file_storage * storage , const std : : string & val , aggregate_of_instance : : ptr & t ) {
t . reset ( new aggregate_of_instance ) ;
// val[0] = TypeEncoder::encode_type<EnumerationReference>();
auto n = ( val . size ( ) - 1 ) / ( sizeof ( size_t ) + 1 ) ;
for ( int i = 0 ; i < n ; + + i ) {
auto ptr = val . data ( ) + 1 + ( sizeof ( size_t ) + 1 ) * i ;
auto tt = * ptr ;
ptr + + ;
size_t v ;
memcpy ( & v , ptr , sizeof ( size_t ) ) ;
if ( tt = = ' e ' ) {
t - > push ( storage - > assert_existance ( v , IfcParse : : impl : : rocks_db_file_storage : : by_name ) ) ;
} else if ( tt = = ' t ' ) {
t - > push ( storage - > assert_existance ( v , IfcParse : : impl : : rocks_db_file_storage : : by_identity ) ) ;
} else {
throw std : : runtime_error ( " " ) ;
}
}
return true ;
2025-02-25 21:29:54 +01:00
}
2025-02-27 22:07:31 +01:00
bool impl : : deserialize ( IfcParse : : impl : : rocks_db_file_storage * , const std : : string & val , aggregate_of_aggregate_of_instance : : ptr & t ) {
2025-02-25 21:29:54 +01:00
return false ;
}
template < typename T >
2025-02-27 22:07:31 +01:00
void rocks_db_attribute_storage : : set ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , std : : size_t index , const T & value )
2025-02-25 21:29:54 +01:00
{
2025-02-27 22:07:31 +01:00
const bool is_header = decl - > schema ( ) = = & Header_section_schema : : get_schema ( ) ;
IfcParse : : impl : : rocks_db_file_storage * rdb_storage = ( IfcParse : : impl : : rocks_db_file_storage * ) storage ;
2025-02-25 21:29:54 +01:00
std : : string v ;
impl : : serialize ( v , value ) ;
2025-02-27 22:07:31 +01:00
rdb_storage - > db - > Put (
rocksdb : : WriteOptions { } ,
( is_header ? " h| " : " i| " ) +
( is_header ? decl - > name ( ) : std : : to_string ( identity ) ) + " | " +
std : : to_string ( index ) , v ) ;
}
template void rocks_db_attribute_storage : : set < Blank > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const Blank & value ) ;
template void rocks_db_attribute_storage : : set < int > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const int & value ) ;
template void rocks_db_attribute_storage : : set < bool > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const bool & value ) ;
template void rocks_db_attribute_storage : : set < boost : : logic : : tribool > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const boost : : logic : : tribool & value ) ;
template void rocks_db_attribute_storage : : set < double > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const double & value ) ;
template void rocks_db_attribute_storage : : set < std : : string > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const std : : string & value ) ;
template void rocks_db_attribute_storage : : set < boost : : dynamic_bitset < > > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const boost : : dynamic_bitset < > & value ) ;
template void rocks_db_attribute_storage : : set < EnumerationReference > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const EnumerationReference & value ) ;
template void rocks_db_attribute_storage : : set < IfcUtil : : IfcBaseClass * > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , IfcUtil : : IfcBaseClass * const & value ) ;
template void rocks_db_attribute_storage : : set < std : : vector < int > > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const std : : vector < int > & value ) ;
template void rocks_db_attribute_storage : : set < std : : vector < double > > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const std : : vector < double > & value ) ;
template void rocks_db_attribute_storage : : set < std : : vector < std : : string > > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const std : : vector < std : : string > & value ) ;
template void rocks_db_attribute_storage : : set < std : : vector < boost : : dynamic_bitset < > > > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const std : : vector < boost : : dynamic_bitset < > > & value ) ;
template void rocks_db_attribute_storage : : set < aggregate_of_instance : : ptr > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const aggregate_of_instance : : ptr & value ) ;
template void rocks_db_attribute_storage : : set < std : : vector < std : : vector < int > > > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const std : : vector < std : : vector < int > > & value ) ;
template void rocks_db_attribute_storage : : set < std : : vector < std : : vector < double > > > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const std : : vector < std : : vector < double > > & value ) ;
template void rocks_db_attribute_storage : : set < aggregate_of_aggregate_of_instance : : ptr > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const aggregate_of_aggregate_of_instance : : ptr & value ) ;
2025-02-25 21:29:54 +01:00
// @todo why do these need to be included, but are not in BaseEntity::set()?
2025-02-27 22:07:31 +01:00
template void rocks_db_attribute_storage : : set < Derived > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const Derived & value ) ;
template void rocks_db_attribute_storage : : set < empty_aggregate_t > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const empty_aggregate_t & value ) ;
template void rocks_db_attribute_storage : : set < empty_aggregate_of_aggregate_t > ( void * storage , const IfcParse : : declaration * decl , std : : size_t identity , size_t index , const empty_aggregate_of_aggregate_t & value ) ;