object庫,提供運行時對象支持,經過引用計數維護全部對象。只要是繼承自tb_object_t的對象類型都是能夠通過擴展實現序列化和反序列化。git
庫內部也已經提供了經常使用的對象類型:github
能夠看到,基本上這些對象已經能夠進行經常使用數據維護了,和apple的CoreFoundation內部的經常使用對象很相似,並且能夠很方便的擴展其餘自定義類型的序列化,這部分等之後再細講吧。。。編程
如今先簡單看下如何快速解析一個json文件到內存:json
// 從文件讀取json數據到內存,json_root爲整個根對象 tb_object_ref_t json_root = tb_object_read_from_url("/home/file/json.txt"); // 從http讀取json數據到內存,json_root爲整個根對象 // tb_object_ref_t json_root = tb_object_read_from_url("http://localhost/file/json.txt"); // 從數據讀取json數據到內存,json_root爲整個根對象 // tb_object_ref_t json_root = tb_object_read_from_data(data, size); // 從stream讀取json數據到內存,json_root爲整個根對象 // tb_object_ref_t json_root = tb_object_read(stream); if (json_root) { // 將json_root的全部數據格式打印到終端,通常調試使用 tb_object_dump(json_root); // 釋放json_root對象,object跟CoreFoundation同樣是有引用計數的 // 這裏json_root沒有被其餘引用,因此會被立馬釋放掉 tb_object_exit(json_root); }
怎麼樣簡單吧,若是要解析plist文件, 也是相似,只需換成plist 文件的url就好了 庫內部回去自動檢測文件格式,進行相應地解析工做,上層都是通用的object對象樹 而且能夠支持xplist(xml格式)、bplist(二進制格式)兩種格式。數組
tb_object_ref_t plist_root = tb_object_read_from_url("/home/file/file.plist");
對於序列化到文件,也很簡單:安全
// 序列化json object到文件, size 爲實際序列化的字節數,若是失敗,返回:-1 // 默認格式存儲,經過 tab 和 換行 進行了格式化,方便查看 tb_long_t size = tb_object_writ_to_url(object, "/home/file/json.txt", TB_OBJECT_FORMAT_JSON); // 序列化json object到文件, size 爲實際序列化的字節數,若是失敗,返回:-1 // 而且壓縮存儲,去掉冗餘的空白字符 tb_long_t size = tb_object_writ_to_url(object, "/home/file/json.txt", TB_OBJECT_FORMAT_JSON | TB_OBJECT_FORMAT_DEFLATE); // 序列化json object到數據buffer,size 爲實際序列化的字節數,若是失敗,返回:-1 tb_byte_t data[8192] = {0}; tb_long_t size = tb_object_writ_to_data(object, data, 8192, TB_OBJECT_FORMAT_JSON);
其餘格式相似,以下是能夠支持的序列化格式:app
object對象的字段解析有兩種模式,一種是一層層迭代遍歷,一種是直接定位到指定字段 迭代遍歷,只有array和dictionay須要,他們一樣是支持tbox容器庫的迭代器模式的,例如:ui
// 遍歷array tb_for_all (tb_object_ref_t, item, tb_object_array_itor(array)) { if (item) { // ... } } // 遍歷dictionary tb_for_all (tb_object_dictionary_item_t*, item, tb_object_dictionary_itor(dictionary)) { // 獲取dictionary的每個鍵值對 if (item) { // 鍵名字符串 tb_char_t const* key = item->key; // 值對象, 能夠繼續迭代下層或直接取值 tb_object_ref_t val = item->val; // ... } }
若是要直接定位某個字段,可使用tbox的seek模式,支持自定義路徑格式:加密
/* 例如對於這個xml的數據解析 <dict> <key>string</key> <string>hello wolrd!</string> <key>com.xxx.xxx</key> <string>hello wolrd!</string> <key>integer</key> <number>31415926</number> <key>array</key> <array> <string>hello wolrd!</string> <number>31415926</number> <number>3.1415926</number> <false/> <true/> <dict> <key>string</key> <string>hello wolrd!</string> </dict> </array> </dict> * 其對應的字段路徑: * 1. ".string" : hello wolrd! * 2. ".array[1]" : 31415926 * 3. ".array[5].string" : hello wolrd! * 4. ".com\\.xxx\\.xxx" : hello wolrd! */ /* seek到指定路徑:.array[5].string ,進行解析字段 * * 這裏傳TB_OBJECT_TYPE_STRING做爲最後一個參數,是爲了內部作一次類型檢測 * 若是這個字段確實string類型的,纔會返回對象,不然返回null,這樣上層解析代碼 * 看上去更加的簡潔,不須要每次解析一個字段,都要外面作一下檢測類型 * * 若是傳TB_OBJECT_TYPE_NONE進去,那麼無論是否是string對象,都會返回成功 * 這個時候上層若是不作類型檢測,只是去字符串,庫內部會有斷言,可是不影響程序邏輯 * 僅僅是提示下,你如今的處理類型有誤。 */ tb_object_ref_t object = tb_object_seek(object, ".array[5].string", TB_OBJECT_TYPE_STRING); if (object) { tb_trace_d("%s", tb_object_string_cstr(object)); }
其餘字段的解析:url
/* 解析string類型字段, 取值前,先作類型判斷是最安全的方式 * 雖然直接轉換也是安全的,類型不對內部直接會返回tb_null * 可是爲了養成良好的編程習慣,在調試模式下,庫內部會有檢測斷言提示類型不匹配 */ if (tb_object_type(object) == TB_OBJECT_TYPE_STRING) { tb_char_t const* string = tb_object_string_cstr(object); } // 解析number類型字段 if (tb_object_type(object) == TB_OBJECT_TYPE_NUMBER) { // 獲取整型值,若是不是會自動強轉,有可能丟失精度 tb_uint32_t value = tb_object_number_uint32(object); // 獲取浮點值,若是不是會自動強轉 // tb_float_t value = tb_object_number_float(object); // 獲取雙精度浮點值,若是不是會自動強轉 // tb_double_t value = tb_object_number_double(object); } // 解析boolean類型字段 if (tb_object_type(object) == TB_OBJECT_TYPE_BOOLEAN) { // 獲取bool值 tb_bool_t value = tb_object_boolean_bool(object); } // 解析data類型字段 if (tb_object_type(object) == TB_OBJECT_TYPE_DATA) { // 獲取數據指針 tb_byte_t* data = tb_object_data_getp(object); // 獲取數據大小 tb_size_t size = tb_object_data_size(object); } // 解析date類型字段 if (tb_object_type(object) == TB_OBJECT_TYPE_DATE) { // 獲取時間戳 tb_time_t time = tb_object_date_time(object); } // 解析array類型字段 if (tb_object_type(object) == TB_OBJECT_TYPE_ARRAY) { // 獲取成員數量 tb_size_t count = tb_object_array_size(object); tb_size_t i = 0; for (i = 0; i < count; i++) { tb_object_ref_t item = tb_object_array_item(object, i); } } // 解析dictionary類型字段 if (tb_object_type(object) == TB_OBJECT_TYPE_DICTIONARY) { // 獲取對象鍵值 tb_object_ref_t value = tb_object_dictionary_val(object, "key_name"); }