@@ -72,6 +72,7 @@ enum TType {
7272 T_MAP = 13 ,
7373 T_SET = 14 ,
7474 T_LIST = 15 ,
75+ T_UUID = 16 ,
7576 T_UTF8 = 16 ,
7677 T_UTF16 = 17
7778};
@@ -85,6 +86,61 @@ const int8_t T_EXCEPTION = 3;
8586const int INVALID_DATA = 1 ;
8687const int BAD_VERSION = 4 ;
8788
89+ static inline int uuid_hex_nibble (char c) {
90+ if (c >= ' 0' && c <= ' 9' ) {
91+ return c - ' 0' ;
92+ }
93+ if (c >= ' a' && c <= ' f' ) {
94+ return 10 + (c - ' a' );
95+ }
96+ if (c >= ' A' && c <= ' F' ) {
97+ return 10 + (c - ' A' );
98+ }
99+ return -1 ;
100+ }
101+
102+ static bool parse_uuid_string (const char * value, size_t len, uint8_t (&uuid)[16]) {
103+ size_t nibble_index = 0 ;
104+ int high_nibble = -1 ;
105+
106+ for (size_t i = 0 ; i < len; ++i) {
107+ const char c = value[i];
108+ if (c == ' -' || c == ' {' || c == ' }' ) {
109+ continue ;
110+ }
111+
112+ const int nibble = uuid_hex_nibble (c);
113+ if (nibble < 0 ) {
114+ return false ;
115+ }
116+
117+ if (high_nibble < 0 ) {
118+ high_nibble = nibble;
119+ } else {
120+ if (nibble_index >= sizeof (uuid)) {
121+ return false ;
122+ }
123+ uuid[nibble_index++] = static_cast <uint8_t >((high_nibble << 4 ) | nibble);
124+ high_nibble = -1 ;
125+ }
126+ }
127+
128+ return nibble_index == sizeof (uuid) && high_nibble < 0 ;
129+ }
130+
131+ static void format_uuid_string (const uint8_t (&uuid)[16], char (&buffer)[37]) {
132+ static const char hex[] = " 0123456789abcdef" ;
133+ size_t out = 0 ;
134+ for (size_t i = 0 ; i < sizeof (uuid); ++i) {
135+ if (i == 4 || i == 6 || i == 8 || i == 10 ) {
136+ buffer[out++] = ' -' ;
137+ }
138+ buffer[out++] = hex[(uuid[i] >> 4 ) & 0x0f ];
139+ buffer[out++] = hex[uuid[i] & 0x0f ];
140+ }
141+ buffer[out] = ' \0 ' ;
142+ }
143+
88144zend_module_entry thrift_protocol_module_entry = {
89145 STANDARD_MODULE_HEADER,
90146 " thrift_protocol" ,
@@ -467,8 +523,10 @@ void skip_element(long thrift_typeID, PHPInputTransport& transport) {
467523 case T_DOUBLE:
468524 transport.skip (8 );
469525 return ;
526+ case T_UUID:
527+ transport.skip (16 );
528+ return ;
470529 // case T_UTF7: // aliases T_STRING
471- case T_UTF8:
472530 case T_UTF16:
473531 case T_STRING: {
474532 uint32_t len = transport.readU32 ();
@@ -582,7 +640,6 @@ void binary_deserialize(int8_t thrift_typeID, PHPInputTransport& transport, zval
582640 RETURN_DOUBLE (a.d );
583641 }
584642 // case T_UTF7: // aliases T_STRING
585- case T_UTF8:
586643 case T_UTF16:
587644 case T_STRING: {
588645 uint32_t size = transport.readU32 ();
@@ -596,6 +653,14 @@ void binary_deserialize(int8_t thrift_typeID, PHPInputTransport& transport, zval
596653 }
597654 return ;
598655 }
656+ case T_UUID: {
657+ uint8_t uuid[16 ];
658+ char strbuf[37 ];
659+ transport.readBytes (uuid, sizeof (uuid));
660+ format_uuid_string (uuid, strbuf);
661+ ZVAL_STRINGL (return_value, strbuf, sizeof (strbuf) - 1 );
662+ return ;
663+ }
599664 case T_MAP: { // array of key -> value
600665 uint8_t types[2 ];
601666 transport.readBytes (types, 2 );
@@ -673,7 +738,7 @@ void binary_deserialize(int8_t thrift_typeID, PHPInputTransport& transport, zval
673738
674739static
675740void binary_serialize_hashtable_key (int8_t keytype, PHPOutputTransport& transport, HashTable* ht, HashPosition& ht_pos, HashTable* spec) {
676- bool keytype_is_numeric = (!((keytype == T_STRING) || (keytype == T_UTF8 ) || (keytype == T_UTF16)));
741+ bool keytype_is_numeric = (!((keytype == T_STRING) || (keytype == T_UUID ) || (keytype == T_UTF16)));
677742
678743 zend_string* key;
679744 uint key_len;
@@ -751,7 +816,15 @@ void binary_serialize(int8_t thrift_typeID, PHPOutputTransport& transport, zval*
751816 a.d = Z_DVAL_P (value);
752817 transport.writeI64 (a.c );
753818 } return ;
754- case T_UTF8:
819+ case T_UUID: {
820+ if (Z_TYPE_P (value) != IS_STRING) convert_to_string (value);
821+ uint8_t uuid[16 ];
822+ if (!parse_uuid_string (Z_STRVAL_P (value), Z_STRLEN_P (value), uuid)) {
823+ throw_tprotocolexception (" Attempt to send an invalid UUID string" , INVALID_DATA);
824+ }
825+ transport.write (reinterpret_cast <const char *>(uuid), sizeof (uuid));
826+ return ;
827+ }
755828 case T_UTF16:
756829 case T_STRING:
757830 if (Z_TYPE_P (value) != IS_STRING) convert_to_string (value);
0 commit comments