55
66#include <gmp.h>
77
8+ static constexpr string_t c_null [] = {
9+ [RESP2 ] = CREATE_STRING ("$-1\r\n" , 5 ),
10+ [RESP3 ] = CREATE_STRING ("_\r\n" , 3 )
11+ };
12+
13+ static constexpr string_t c_bool [4 ][2 ] = {
14+ [RESP2 ] = { [false] = CREATE_STRING ("+false\r\n" , 8 ), [true] = CREATE_STRING ("+true\r\n" , 7 ) },
15+ [RESP3 ] = { [false] = CREATE_STRING ("#f\r\n" , 4 ), [true] = CREATE_STRING ("#t\r\n" , 4 ) },
16+ };
17+
818static string_t run (struct CommandEntry * entry ) {
919 PASS_NO_CLIENT (entry -> client );
1020
@@ -29,107 +39,62 @@ static string_t run(struct CommandEntry *entry) {
2939 }
3040
3141 const struct HashTable * table = kv -> value ;
42+ const enum ProtocolVersion protover = entry -> client -> protover ;
43+
3244 char * response = entry -> client -> write_buf ;
3345 uint64_t at ;
3446
35- switch (entry -> client -> protover ) {
36- case RESP2 : {
47+ switch (protover ) {
48+ case RESP2 :
3749 response [0 ] = '*' ;
3850 at = ltoa (table -> size .used * 2 , response + 1 ) + 1 ;
39- response [at ++ ] = '\r' ;
40- response [at ++ ] = '\n' ;
41-
42- for (uint32_t i = 0 ; i < table -> size .capacity ; ++ i ) {
43- struct HashTableField * field = table -> fields [i ];
44-
45- if (field ) {
46- at += create_resp_string (response + at , field -> name );
47-
48- switch (field -> type ) {
49- case TELLY_NULL :
50- memcpy (response + at , "+null\r\n" , 7 );
51- at += 7 ;
52- break ;
53-
54- case TELLY_INT :
55- at += create_resp_integer_mpz (entry -> client -> protover , response + at , * ((mpz_t * ) field -> value ));
56- break ;
57-
58- case TELLY_DOUBLE :
59- at += create_resp_integer_mpf (entry -> client -> protover , response + at , * ((mpf_t * ) field -> value ));
60- break ;
61-
62- case TELLY_STR :
63- at += create_resp_string (response + at , * ((string_t * ) field -> value ));
64- break ;
65-
66- case TELLY_BOOL : {
67- if (* ((bool * ) field -> value )) {
68- memcpy (response + at , "+true\r\n" , 7 );
69- at += 7 ;
70- } else {
71- memcpy (response + at , "+false\r\n" , 8 );
72- at += 8 ;
73- }
74- }
75-
76- default :
77- break ;
78- }
79- }
80- }
81-
8251 break ;
83- }
8452
85- case RESP3 : {
53+ case RESP3 :
8654 response [0 ] = '%' ;
8755 at = ltoa (table -> size .used , response + 1 ) + 1 ;
88- response [at ++ ] = '\r' ;
89- response [at ++ ] = '\n' ;
90-
91- for (uint32_t i = 0 ; i < table -> size .capacity ; ++ i ) {
92- struct HashTableField * field = table -> fields [i ];
93-
94- if (field ) {
95- at += create_resp_string (response + at , field -> name );
96-
97- switch (field -> type ) {
98- case TELLY_NULL :
99- memcpy (response + at , "_\r\n" , 3 );
100- at += 3 ;
101- break ;
102-
103- case TELLY_INT :
104- at += create_resp_integer_mpz (entry -> client -> protover , response + at , * ((mpz_t * ) field -> value ));
105- break ;
106-
107- case TELLY_DOUBLE :
108- at += create_resp_integer_mpf (entry -> client -> protover , response + at , * ((mpf_t * ) field -> value ));
109- break ;
110-
111- case TELLY_STR : {
112- at += create_resp_string (response + at , * ((string_t * ) field -> value ));
113- break ;
114- }
115-
116- case TELLY_BOOL : {
117- if (* ((bool * ) field -> value )) {
118- memcpy (response + at , "#t\r\n" , 4 );
119- } else {
120- memcpy (response + at , "#f\r\n" , 4 );
121- }
122-
123- at += 4 ;
124- }
125-
126- default :
127- break ;
128- }
129- }
56+ break ;
57+ }
58+
59+ response [at ++ ] = '\r' ;
60+ response [at ++ ] = '\n' ;
61+
62+ for (uint32_t i = 0 ; i < table -> size .capacity ; ++ i ) {
63+ struct HashTableField * field = table -> fields [i ];
64+ if (!field ) continue ;
65+
66+ at += create_resp_string (response + at , field -> name );
67+ char * buf = response + at ;
68+
69+ switch (field -> type ) {
70+ case TELLY_NULL : {
71+ const string_t constant = c_null [protover ];
72+ memcpy (buf , constant .value , constant .len );
73+ at += constant .len ;
74+ break ;
13075 }
13176
132- break ;
77+ case TELLY_INT :
78+ at += create_resp_integer_mpz (protover , buf , * ((mpz_t * ) field -> value ));
79+ break ;
80+
81+ case TELLY_DOUBLE :
82+ at += create_resp_integer_mpf (protover , buf , * ((mpf_t * ) field -> value ));
83+ break ;
84+
85+ case TELLY_STR :
86+ at += create_resp_string (buf , * ((string_t * ) field -> value ));
87+ break ;
88+
89+ case TELLY_BOOL : {
90+ string_t constant = c_bool [protover ][* ((bool * ) field -> value )];
91+ memcpy (buf , constant .value , constant .len );
92+ at += constant .len ;
93+ break ;
94+ }
95+
96+ default :
97+ break ;
13398 }
13499 }
135100
0 commit comments