@@ -821,31 +821,47 @@ std::string sai_serialize_number(
821821 return std::to_string (number);
822822}
823823
824- std::string sai_serialize_enum (
825- _In_ const int32_t value,
824+ // internal
825+ static std::string sai_serialize_flags (
826+ _In_ int32_t value,
826827 _In_ const sai_enum_metadata_t * meta)
827828{
828829 SWSS_LOG_ENTER ();
829830
830- if (meta == NULL )
831- {
832- return sai_serialize_number (value);
833- }
831+ if (value == 0 )
832+ return meta->values [0 ] ? " 0x0" : meta->valuesnames [0 ];
833+
834+ std::string s;
835+
836+ s.reserve (1024 );
834837
835838 for (size_t i = 0 ; i < meta->valuescount ; ++i)
836839 {
837- if (meta->values [i] == value )
840+ if (value & meta->values [i])
838841 {
839- return meta->valuesnames [i];
842+ if (s.size ())
843+ s.append (" |" );
844+
845+ s += meta->valuesnames [i];
846+
847+ value &= ~meta->values [i];
840848 }
841849 }
842850
843- SWSS_LOG_WARN (" enum value %d not found in enum %s" , value, meta->name );
851+ if (value)
852+ {
853+ SWSS_LOG_WARN (" unrecognized flags: 0x%x in enum %s" , value, meta->name );
844854
845- return sai_serialize_number (value);
855+ if (s.size ())
856+ s.append (" |" );
857+
858+ s += sai_serialize_number<uint32_t >(value, true );
859+ }
860+
861+ return s;
846862}
847863
848- std::string sai_serialize_flags (
864+ std::string sai_serialize_enum (
849865 _In_ const int32_t value,
850866 _In_ const sai_enum_metadata_t * meta)
851867{
@@ -856,68 +872,22 @@ std::string sai_serialize_flags(
856872 return sai_serialize_number (value);
857873 }
858874
859- if (!meta->containsflags || meta->flagstype != SAI_ENUM_FLAGS_TYPE_STRICT)
860- {
861- return sai_serialize_enum (value, meta);
862- }
863-
864- uint32_t flags = static_cast <uint32_t >(value);
865- std::string s;
866- const size_t n = meta->valuescount ;
867- if (n != 0 )
868- {
869- // The current strict flags longer enum is 50 characters, so setting to 64
870- s.reserve (std::min (n * size_t (64 ), size_t (2048 )));
871-
872- if ( !value)
873- {
874- s += meta->valuesnames [0 ];
875- return s;
876- }
877- }
878-
879- bool first = true ;
880- for (size_t i = 0 ; i < n; ++i)
875+ if (meta->flagstype == SAI_ENUM_FLAGS_TYPE_STRICT)
881876 {
882- const int32_t v = meta->values [i];
883- if (v == 0 )
884- {
885- continue ;
886- }
887-
888- const uint32_t bit = static_cast <uint32_t >(v);
889- if ((flags & bit) != 0 )
890- {
891- if (!first)
892- {
893- s.push_back (' |' );
894- }
895- first = false ;
896- s += meta->valuesnames [i];
897- flags &= ~bit;
898- }
877+ return sai_serialize_flags (value, meta);
899878 }
900879
901- if (flags ! = 0 )
880+ for ( size_t i = 0 ; i < meta-> valuescount ; ++i )
902881 {
903- SWSS_LOG_WARN (" enum %s strict flags value 0x%x has unknown bits 0x%x" ,
904- meta->name ,
905- static_cast <unsigned int >(static_cast <uint32_t >(value)),
906- flags);
907- if (!first)
882+ if (meta->values [i] == value)
908883 {
909- s. push_back ( ' | ' ) ;
884+ return meta-> valuesnames [i] ;
910885 }
911- s += sai_serialize_number (flags, true );
912- return s;
913886 }
914887
915- if (first)
916- {
917- return sai_serialize_number (value);
918- }
888+ SWSS_LOG_WARN (" enum value %d not found in enum %s" , value, meta->name );
919889
920- return s ;
890+ return sai_serialize_number (value) ;
921891}
922892
923893std::string sai_serialize_number (
@@ -2627,7 +2597,7 @@ std::string sai_serialize_port_error_status(
26272597{
26282598 SWSS_LOG_ENTER ();
26292599
2630- return sai_serialize_flags (status, &sai_metadata_enum_sai_port_error_status_t );
2600+ return sai_serialize_enum (status, &sai_metadata_enum_sai_port_error_status_t );
26312601}
26322602
26332603std::string sai_serialize_port_host_tx_ready (
@@ -3741,6 +3711,46 @@ void sai_deserialize_number(
37413711 sai_deserialize_number<uint32_t >(s, number, hex);
37423712}
37433713
3714+
3715+ // internal
3716+ static void sai_deserialize_flags (
3717+ _In_ const std::string& s,
3718+ _In_ const sai_enum_metadata_t *meta,
3719+ _Out_ int32_t & value)
3720+ {
3721+ SWSS_LOG_ENTER ();
3722+
3723+ value = 0 ;
3724+
3725+ const auto tokens = swss::tokenize (s, ' |' );
3726+
3727+ for (auto & v: tokens)
3728+ {
3729+ if (v[0 ] == ' 0' )
3730+ {
3731+ uint32_t val;
3732+ sai_deserialize_number (v, val, true );
3733+
3734+ value |= val;
3735+ continue ;
3736+ }
3737+
3738+ for (size_t i = 0 ; i < meta->valuescount ; ++i)
3739+ {
3740+ if (v == meta->valuesnames [i])
3741+ {
3742+ value |= meta->values [i];
3743+ break ;
3744+ }
3745+ }
3746+ if (i == meta->valuescount )
3747+ {
3748+ // v is empty or doesn't match any enum
3749+ SWSS_LOG_WARN (" %s in %s has invalid enum for %s" , v.c_str (), s.c_str (), meta->name );
3750+ }
3751+ }
3752+ }
3753+
37443754void sai_deserialize_enum (
37453755 _In_ const std::string& s,
37463756 _In_ const sai_enum_metadata_t *meta,
@@ -3753,6 +3763,11 @@ void sai_deserialize_enum(
37533763 return sai_deserialize_number (s, value);
37543764 }
37553765
3766+ if (meta->flagstype == SAI_ENUM_FLAGS_TYPE_STRICT)
3767+ {
3768+ return sai_deserialize_flags (s, meta, value);
3769+ }
3770+
37563771 for (size_t i = 0 ; i < meta->valuescount ; ++i)
37573772 {
37583773 if (strcmp (s.c_str (), meta->valuesnames [i]) == 0 )
@@ -3784,60 +3799,6 @@ void sai_deserialize_enum(
37843799 sai_deserialize_number (s, value);
37853800}
37863801
3787- void sai_deserialize_flags (
3788- _In_ const std::string& s,
3789- _In_ const sai_enum_metadata_t * meta,
3790- _Out_ int32_t & value)
3791- {
3792- SWSS_LOG_ENTER ();
3793-
3794- if (meta == NULL )
3795- {
3796- sai_deserialize_number (s, value);
3797- return ;
3798- }
3799-
3800- if (!meta->containsflags || meta->flagstype != SAI_ENUM_FLAGS_TYPE_STRICT)
3801- {
3802- sai_deserialize_enum (s, meta, value);
3803- return ;
3804- }
3805-
3806- if (s.empty ())
3807- {
3808- SWSS_LOG_THROW (" empty strict flags string" );
3809- }
3810-
3811- const auto tokens = swss::tokenize (s, ' |' );
3812- uint32_t acc = 0 ;
3813-
3814- for (const auto & tok : tokens)
3815- {
3816- if (tok.empty ())
3817- {
3818- SWSS_LOG_THROW (" empty strict flags token in %s" , s.c_str ());
3819- }
3820-
3821- /* This matches how sai_serialize_flags appends raw leftover bits
3822- when some bitmask bits are not represented by any known enum name
3823- */
3824- if (tok.size () >= 2 && tok[0 ] == ' 0' && (tok[1 ] == ' x' || tok[1 ] == ' X' ))
3825- {
3826- uint32_t bits = 0 ;
3827- sai_deserialize_number (tok, bits, true );
3828- acc |= bits;
3829- }
3830- else
3831- {
3832- int32_t v = 0 ;
3833- sai_deserialize_enum (tok, meta, v);
3834- acc |= static_cast <uint32_t >(v);
3835- }
3836- }
3837-
3838- value = static_cast <int32_t >(acc);
3839- }
3840-
38413802void sai_deserialize_mac (
38423803 _In_ const std::string& s,
38433804 _Out_ sai_mac_t & mac)
@@ -5210,7 +5171,7 @@ void sai_deserialize_port_error_status(
52105171{
52115172 SWSS_LOG_ENTER ();
52125173
5213- sai_deserialize_flags (s, &sai_metadata_enum_sai_port_error_status_t , (int32_t &)status);
5174+ sai_deserialize_enum (s, &sai_metadata_enum_sai_port_error_status_t , (int32_t &)status);
52145175}
52155176
52165177void sai_deserialize_port_host_tx_ready_status (
0 commit comments