JSON (JavaScript Object notation) is a data interchange format, a JavaScript based data representation language that defines the basic data description format on the basis of the following two data structures: 1 A set containing name/value pairs; 2 An ordered list. For JSON, the BNF definition of some of its data structures is shown below. In the form of {"name": "Ldxian", "Age": 23} Represents a JSON object with two properties, the values being Ldxian and 23 respectively. The rest of the text, comments, and other programming languages similar to. Let's start by looking at how Facebook thrift to implement the JSON protocol.
First look at the correspondence between the thrift data type and the JSON data type:
(1) All integer types of thrift JSON are represented as numbers;
(2) The double type of thrift is also represented as a number of JSON, with special values expressed in strings, as follows:
A. Nan indicates that it is not a numeric value;
B. Infinity represents positive infinity;
C.–infinity represents negative infinity.
(3) The thrift string is represented as a JSON string and is preceded by some escape characters;
(4) The binary value of the thrift and encoded as a base64 encoding and then as a string of JSON;
(5) The thrift structure is represented as a JSON object, the field ID as key, and the field value represented by a single key-value JSON object. A key is a short string that represents a particular type, followed by a value. The valid type identification is: "TF" stands for bool, "i8" for Byte, "i16" for 16-bit integers, "i32" for 32-bit integers, "i64" for 64-bit integers, "dbl" for double-precision floating-point types, "str" for strings (including binary), "Rec" Represents a struct body ("records"), "Map" represents a map, "LST" represents a list, and "Set" represents set.
(6) Thrift's lists and sets are represented as JSON array (array), where the first element of the array represents the data type of the thrift element, and the second value of the array represents the number of subsequent thrift elements. Then all the elements are behind.
(7) The maps of thrift is represented as a JSON array, where the first two values represent the types of keys and values, followed by the number of key-value pairs, followed by the JSON object that contains the specific key-value pairs. Note that the key to JSON is only a string, which is that the key of the maps type that requires thrift must be numeric and string, and the number needs to be serialized as a string.
(8) The Thrift messages (message) is represented as a JSON array, and the first four elements represent the protocol version, the message name, the message type, and the sequence ID, respectively.
Knowing the correspondence of each data type, and knowing how to transform the corresponding data in special cases, it is very easy to implement JSON encoding for the transmitted data of the thrift, that is, to encode the JSON before writing to the transport layer according to the corresponding relationship. Sent to the other end of the network, and the other end of the data received in accordance with the JSON protocol to decode it, the whole process is probably the case. The following is an analysis of some of the more important code that implements the JSON encoding protocol.
The implementation of the JSON encoding protocol and the Protocol described earlier requires that the same interface be implemented to the upper level. Before actually implementing these functions, it does a lot of preparation, mainly defines some static data and help functions, static data is mainly some special characters or symbols of the representative constants and some escape characters, and so on, the Help function is the data type name and ID of the mutual conversion, The specific data type is obtained based on the short representation string of the type. These types of content are very intuitive and simple, a look at the code to understand, do not specifically analyze the introduction. The following is mainly about the realization process of several key functions. In accordance with the Convention of the previous agreement, the first analysis of the function to start writing the message Writemessagebegin, the code is as follows:
uint32_t result = Writejsonarraystart ()//write JSON array start result
= = Writejsoninteger (kThriftVersion1); Converts the protocol version number to JSON format and writes result
+ = writejsonstring (name);//converts the message name to a JSON string and writes the result
+ = Writejsoninteger ( MessageType)//Empathy: Message type result
+ = Writejsoninteger (seqid);//serial number
The code posted here is not the completion of the function definition, just paste some of the main code, will be followed in this way, the previous main for integrity considerations, the subsequent analysis may need to combine the source code together. Now the purpose is to provide ideas and analysis of the design of ideas, ideas, want to understand the complete implementation must also look at the complete source code.
Based on the relationship between the thrift data type and the JSON data type described earlier, sending a messages data structure is converted to an array for JSON, so the implementation of the Writemessagebegin function first calls the function Writejsonarraystart writes an array to begin the notation ' [', also in the introduction will call the corresponding function writes the array ending symbol, does not have to introduce separately later. Then you write the protocol version, the message name, the message type, and the serial number in a format that is converted to JSON by messages. The message name is a string data type, so the string that is converted to JSON is sent, and the protocol version, the message type, and the serial number are all integers, which translates into JSON's digital transmissions. In fact, this implementation is similar to the protocol described earlier, the difference is that the content in the JSON format to send, so the following main see how to convert these data types to JSON, first look at the Writejsoninteger function, it is to convert integers to numbers, the main code is as follows:
uint32_t result = Context_->write
(*trans_);//default does nothing
std::string val (boost::lexical_cast<std:: String> (num))//Call the Boost library type
conversion function converts the number to a string
bool Escapenum = Context_->escapenum ();//is an escape character, default false
if (escapenum) {//Will not execute, if the escape character is separated by the JSON string delimiter
trans_->write (&kjsonstringdelimiter, 1);
result = 1;
}
Trans_->write ((const uint8_t *) Val.c_str (), val.length ());//write converted string
to transport layer result
+ = Val.length ();// Write length calculation
if (escapenum) {
trans_->write (&kjsonstringdelimiter, 1);
result = 1;
}