@@ -715,13 +715,13 @@ static int test_paramdict_access()
715715 return -1 ;
716716 }
717717 }
718- if (pd.get (0 , 0 ) != 10 || pd.get (31 , 0 ) != 31 )
718+ if (pd.get (0 , 0 ) != 10 || pd.get (0 , 7 . f ) != 10 . f || pd. get ( 31 , 0 ) != 31 )
719719 {
720720 fprintf (stderr, " ParamDict valid id access failed\n " );
721721 return -1 ;
722722 }
723723
724- if (pd.get (0 , 7 . f ) != 7 . f || pd. get ( 1 , 7 ) != 7
724+ if (pd.get (1 , 7 ) != 7
725725 || pd.get (2 , 7 ) != 7 || pd.get (2 , 7 .f ) != 7 .f
726726 || pd.get (3 , 7 ) != 7 || pd.get (3 , 7 .f ) != 7 .f
727727 || pd.get (0 , array).data != array.data || pd.get (0 , text) != text
@@ -741,8 +741,11 @@ static int test_paramdict_access()
741741 assigned = pd;
742742 const ncnn::ParamDict& alias = assigned;
743743 assigned = alias;
744- if (!copied.get (2 , ncnn::Mat ()).empty () || copied.get (3 , std::string ()) != " "
745- || !assigned.get (2 , ncnn::Mat ()).empty () || assigned.get (3 , std::string ()) != " "
744+ ncnn::Mat fallback_array (1 );
745+ ((int *)fallback_array)[0 ] = 99 ;
746+ const std::string fallback_text = " fallback" ;
747+ if (copied.get (2 , fallback_array).data != fallback_array.data || copied.get (3 , fallback_text) != fallback_text
748+ || assigned.get (2 , fallback_array).data != fallback_array.data || assigned.get (3 , fallback_text) != fallback_text
746749 || copied.get (2 , 0 ) != 22 || assigned.get (3 , 0 ) != 33 )
747750 {
748751 fprintf (stderr, " ParamDict retagged copy access failed\n " );
@@ -759,29 +762,34 @@ static int test_paramdict_access()
759762 return 0 ;
760763}
761764
762- static int test_paramdict_zero_type ()
765+ static int test_paramdict_numeric_conversion ()
763766{
764- const char * text = " 0=0 1=0.0" ;
765- for (int mode = 0 ; mode < 2 ; mode++)
766- {
767- ParamDictTest pd;
768- if (mode == 0 )
767+ const int integers[] = {0 , 6 , -6 , 16777217 , INT_MIN , INT_MAX };
768+ const float expected[] = {0 .f , 6 .f , -6 .f , 16777216 .f , -2147483648 .f , 2147483648 .f };
769+ for (size_t j = 0 ; j < sizeof (integers) / sizeof (integers[0 ]); j++)
770+ for (int mode = 0 ; mode < 2 ; mode++)
769771 {
770- pd.set (0 , 0 );
771- pd.set (1 , 0 .f );
772- }
773- else
774- {
775- if (pd.load_param (text))
772+ ParamDictTest pd;
773+ if (mode == 0 )
774+ {
775+ pd.set (0 , integers[j]);
776+ pd.set (1 , 0 .f );
777+ }
778+ else
779+ {
780+ char text[64 ];
781+ snprintf (text, sizeof (text), " 0=%d 1=0.0" , integers[j]);
782+ if (pd.load_param (text))
783+ return -1 ;
784+ }
785+ if (pd.get (0 , 7 .f ) != expected[j] || pd.type (0 ) != 2 || pd.get (0 , 7 ) != integers[j]
786+ || pd.type (1 ) != 3 || pd.get (1 , 7 .f ) != 0 .f || pd.get (1 , 7 ) != 7
787+ || pd.get (2 , 7 .f ) != 7 .f )
788+ {
789+ fprintf (stderr, " ParamDict numeric conversion failed value=%d mode=%d\n " , integers[j], mode);
776790 return -1 ;
791+ }
777792 }
778- if (pd.type (0 ) != 2 || pd.get (0 , 7 ) != 0 || pd.get (0 , 7 .f ) != 7 .f
779- || pd.type (1 ) != 3 || pd.get (1 , 7 .f ) != 0 .f || pd.get (1 , 7 ) != 7 )
780- {
781- fprintf (stderr, " ParamDict zero type access failed mode=%d\n " , mode);
782- return -1 ;
783- }
784- }
785793 return 0 ;
786794}
787795
@@ -884,6 +892,22 @@ static int test_paramdict_text_boundaries()
884892 }
885893 }
886894
895+ // accept signs, leading zeroes and trailing commas without changing element types
896+ if (pd.load_param (" 0=+7 1=0007 -23302=1,+2 3=1,2, 4=+1.5 5=1.0,2.0," ))
897+ return -1 ;
898+ a = pd.get (2 , ncnn::Mat ());
899+ b = pd.get (3 , ncnn::Mat ());
900+ c = pd.get (5 , ncnn::Mat ());
901+ if (pd.type (0 ) != 2 || pd.get (0 , 0 ) != 7 || pd.type (1 ) != 2 || pd.get (1 , 0 ) != 7
902+ || pd.type (2 ) != 5 || a.w != 1 || ((const int *)a)[0 ] != 2
903+ || pd.type (3 ) != 5 || b.w != 2 || ((const int *)b)[0 ] != 1 || ((const int *)b)[1 ] != 2
904+ || pd.type (4 ) != 3 || pd.get (4 , 0 .f ) != 1 .5f
905+ || pd.type (5 ) != 6 || c.w != 2 || c[0 ] != 1 .f || c[1 ] != 2 .f )
906+ {
907+ fprintf (stderr, " ParamDict numeric spelling failed\n " );
908+ return -1 ;
909+ }
910+
887911 // lines may end at a read-buffer boundary or split a quoted/numeric token across it
888912 const int line_lengths[] = {1022 , 1023 , 1024 , 1035 , 1048 , 2046 , 2047 };
889913 for (size_t j = 0 ; j < sizeof (line_lengths) / sizeof (line_lengths[0 ]); j++)
@@ -981,14 +1005,20 @@ static int check_float_boundary(const char* text, float expected, int count, boo
9811005
9821006static int test_paramdict_float_boundaries ()
9831007{
984- // old array elements retain the full numeric token limit
1008+ // old and modern array elements retain the full numeric token limit
9851009 for (int len = 127 ; len <= 128 ; len++)
9861010 {
9871011 std::string text = " -23300=1,0." ;
9881012 text += make_param_string (len - 2 , ' 0' );
9891013 text += " 1=42\n ReLU next 1 1 in out\n " ;
9901014 if (check_float_boundary (text.c_str (), 0 .f , 1 , len == 127 ))
9911015 return -1 ;
1016+
1017+ text = " 0=0.0,1." ;
1018+ text += make_param_string (len - 2 , ' 0' );
1019+ text += " 1=42\n ReLU next 1 1 in out\n " ;
1020+ if (check_float_boundary (text.c_str (), 0 .f , 2 , len == 127 ))
1021+ return -1 ;
9921022 }
9931023
9941024 const char * numbers[] = {
@@ -999,13 +1029,13 @@ static int test_paramdict_float_boundaries()
9991029 " 340282356779733661637539395458142568447.0" , " 340282356779733661637539395458142568448.0" ,
10001030 " 340282356779733661637539395458142568449.0" ,
10011031 " 0.000340282356779733661637539395458142568447e42" ,
1002- " 000340282356779733661637539395458142568448e0"
1032+ " 000340282356779733661637539395458142568448e0" , " 1e-46 "
10031033 };
10041034 const float expected[] = {
10051035 32768 .015625f , 32768 .015625f , 32768 .01953125f , 32768 .01953125f , 32768 .0234375f , 32768 .0234375f ,
1006- FLT_MAX , FLT_MAX , FLT_MAX , 3 .402823e38f, 0 .f , 0 .f , FLT_MAX , 0 .f , FLT_MAX , 0 .f , 0 .f , FLT_MAX , 0 .f
1036+ FLT_MAX , FLT_MAX , FLT_MAX , 3 .402823e38f, 0 .f , 0 .f , FLT_MAX , 0 .f , FLT_MAX , 0 .f , 0 .f , FLT_MAX , 0 .f , 0 . f
10071037 };
1008- const bool valid[] = {true , true , true , true , true , true , true , true , true , true , false , false , true , false , true , false , false , true , false };
1038+ const bool valid[] = {true , true , true , true , true , true , true , true , true , true , false , false , true , false , true , false , false , true , false , true };
10091039 for (size_t i = 0 ; i < sizeof (numbers) / sizeof (numbers[0 ]); i++)
10101040 for (int negative = 0 ; negative < 2 ; negative++)
10111041 {
@@ -1178,7 +1208,7 @@ static int test_paramdict_reload()
11781208 {
11791209 const bool binary = mode == 2 ;
11801210 const char * input = mode == 0 ? text : old_array_text;
1181- const unsigned char * ptr = binary ? data. data () : (const unsigned char *)input;
1211+ const unsigned char * ptr = binary ? & data[ 0 ] : (const unsigned char *)input;
11821212 ncnn::DataReaderFromMemory dr (ptr);
11831213 const int ret = check_paramdict_reload (dr, binary);
11841214 if (ret != 0 )
@@ -1201,7 +1231,7 @@ static int test_paramdict_binary_bounds()
12011231 append_param_word (data, ids[i]);
12021232 append_param_word (data, lengths[j]);
12031233 append_param_word (data, -233 );
1204- BoundedParamReader reader (data. data () , data.size ());
1234+ BoundedParamReader reader (& data[ 0 ] , data.size ());
12051235 ParamDictTest pd;
12061236 if (pd.load_param_bin (reader) == 0 )
12071237 {
@@ -1216,7 +1246,7 @@ static int test_paramdict_binary_bounds()
12161246 std::vector<unsigned char > data;
12171247 append_param_word (data, invalid_ids[i]);
12181248 append_param_word (data, -233 );
1219- BoundedParamReader reader (data. data () , data.size ());
1249+ BoundedParamReader reader (& data[ 0 ] , data.size ());
12201250 ParamDictTest pd;
12211251 if (pd.load_param_bin (reader) == 0 )
12221252 {
@@ -1231,7 +1261,7 @@ static int test_paramdict_binary_bounds()
12311261 std::vector<unsigned char > data;
12321262 append_param_word (data, -23400 );
12331263 append_param_word (data, invalid_string_lengths[i]);
1234- BoundedParamReader reader (data. data () , data.size ());
1264+ BoundedParamReader reader (& data[ 0 ] , data.size ());
12351265 ParamDictTest pd;
12361266 if (pd.load_param_bin (reader) == 0 )
12371267 {
@@ -1245,7 +1275,7 @@ static int test_paramdict_binary_bounds()
12451275 std::vector<unsigned char > data;
12461276 append_param_word (data, -23300 );
12471277 append_param_word (data, 0x40000000 ); // byte count wraps on 32-bit targets
1248- BoundedParamReader reader (data. data () , data.size ());
1278+ BoundedParamReader reader (& data[ 0 ] , data.size ());
12491279 ParamDictTest pd;
12501280 if (pd.load_param_bin (reader) == 0 || check_text_result (" -23300=1073741824" , false ))
12511281 {
@@ -1285,7 +1315,7 @@ static int test_paramdict_binary_bounds()
12851315 append_param_word (data, 99 );
12861316 append_param_word (data, -233 );
12871317 ParamDictTest pd;
1288- BoundedParamReader reader (data. data () , data.size ());
1318+ BoundedParamReader reader (& data[ 0 ] , data.size ());
12891319 if (pd.load_param_bin (reader) || pd.get (0 , 0 ) != 0x3f800000 || pd.get (0 , 0 .f ) != 1 .f
12901320 || pd.get (1 , ncnn::Mat ()).w != 1 || pd.get (1 , ncnn::Mat ())[0 ] != 1 .f
12911321 || pd.type (2 ) != 4 || !pd.get (2 , ncnn::Mat ()).empty ()
@@ -1308,7 +1338,7 @@ static int test_paramdict_binary_bounds()
13081338 // every truncation, including missing EOP and short scalar/array/string data, fails
13091339 for (size_t size = 0 ; size < data.size (); size++)
13101340 {
1311- BoundedParamReader truncated (data. data () , size);
1341+ BoundedParamReader truncated (& data[ 0 ] , size);
13121342 ParamDictTest partial;
13131343 if (partial.load_param_bin (truncated) == 0 )
13141344 {
@@ -1330,7 +1360,7 @@ int main()
13301360 || test_paramdict_5 ()
13311361 || test_paramdict_6 ()
13321362 || test_paramdict_access ()
1333- || test_paramdict_zero_type ()
1363+ || test_paramdict_numeric_conversion ()
13341364 || test_paramdict_invalid_text ()
13351365 || test_paramdict_text_boundaries ()
13361366 || test_paramdict_float_boundaries ()
0 commit comments