00001 
00010 #ifdef CPLUSPLUS
00011     #undef CPLUSPLUS
00012 #endif
00013 
00014 
00015 #include "llsd_tool.h"
00016 
00017 
00019 
00020 
00021 
00027 Buffer  llsd_bin_get_str(uByte** ptr)
00028 {
00029     Buffer buf = init_Buffer();
00030 
00031     if (ptr==NULL) return buf;
00032 
00033     int size = ntohl(*(int*)(*ptr));
00034     (*ptr) += 4;
00035     
00036     char* str = (char*)malloc(size+1);
00037     if (str!=NULL) {
00038         memcpy(str, *ptr, size);
00039         str[size] = '\0';
00040         buf = make_Buffer_bystr(str);
00041         free(str);
00042     }
00043     (*ptr) += size;
00044 
00045     return buf;
00046 }
00047 
00048 
00054 int  llsd_bin_get_int(uByte** ptr)
00055 {
00056     if (ptr==NULL) return 0;
00057 
00058     int value = ntohl(*(int*)(*ptr));
00059     (*ptr) += 4;
00060 
00061     return value;
00062 }
00063 
00064 
00070 unsigned long long int llsd_bin_get_date(uByte** ptr)
00071 {
00072     if (ptr==NULL) return 0ULL;
00073 
00074     unsigned long long int value = ntohull(*(unsigned long long int*)(*ptr));
00075     (*ptr) += 8;
00076 
00077     return value;
00078 }
00079 
00080 
00086 double  llsd_bin_get_real(uByte** ptr)
00087 {
00088     if (ptr==NULL) return 0.0;
00089 
00090 #ifdef WIN32
00091     long long int tmp;
00092 #else
00093     long long int tmp  __attribute__((may_alias));
00094 #endif
00095 
00096     tmp = ntohull(*(long long int*)(*ptr));
00097 
00098     long long int* ptmp = (long long int*)&tmp;
00099     double* valuep = (double*)ptmp;
00100     double  value  = *valuep;
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108     (*ptr) += 8;
00109 
00110     return value;
00111 }
00112 
00113 
00119 Buffer  llsd_bin_get_uuid(uByte** ptr)
00120 {
00121     Buffer buf = init_Buffer();
00122 
00123     if (ptr==NULL) return buf;
00124 
00125     char* str = (char*)malloc(16);
00126     if (str!=NULL) {
00127         memcpy(str, *ptr, 16);
00128         buf = set_Buffer(str, 16);
00129         free(str);
00130     }
00131     (*ptr) += 16;
00132 
00133     return buf;
00134 }
00135 
00136 
00142 Buffer  llsd_bin_get_bin(uByte** ptr)
00143 {
00144     Buffer buf = init_Buffer();
00145 
00146     if (ptr==NULL) return buf;
00147 
00148     int size = ntohl(*(int*)(*ptr));
00149     (*ptr) += 4;
00150     
00151     uByte* bin = (uByte*)malloc(size);
00152     if (bin!=NULL) {
00153         memcpy(bin, *ptr, size);
00154         buf = set_Buffer(bin, size);
00155         free(bin);
00156     }
00157     (*ptr) += size;
00158 
00159     return buf;
00160 }
00161 
00162 
00163 int  llsd_bin_get_length(uByte* ptr, int sz)
00164 {
00165     if (ptr==NULL) return 0;
00166 
00167     int cc = 0;
00168     Buffer stack = make_Buffer(LSDATA);
00169     uByte* buf   = ptr;
00170 
00171     while (buf<ptr+sz) {
00172         
00173         if      (*buf==LLSD_MAKER_UNDEF) buf++;
00174         else if (*buf==LLSD_MAKER_TRUE)  buf++;
00175         else if (*buf==LLSD_MAKER_FALSE) buf++;
00176         else if (*buf==LLSD_MAKER_INT)   buf += 5;
00177         else if (*buf==LLSD_MAKER_REAL)  buf += 9;
00178         else if (*buf==LLSD_MAKER_UUID)  buf += 17;
00179         else if (*buf==LLSD_MAKER_BIN)   buf += ntohl(*(int*)(buf+1)) + 5;
00180         else if (*buf==LLSD_MAKER_STR)   buf += ntohl(*(int*)(buf+1)) + 5;
00181         else if (*buf==LLSD_MAKER_URI)   buf += ntohl(*(int*)(buf+1)) + 5;
00182         else if (*buf==LLSD_MAKER_KEY)   buf += ntohl(*(int*)(buf+1)) + 5;
00183         else if (*buf==LLSD_MAKER_DATE)  buf += 9;
00184         else if (*buf!=LLSD_MAKER_MAP && *buf!=LLSD_MAKER_ARRAY &&
00185                  *buf!=LLSD_MAKER_MAP_END && *buf!=LLSD_MAKER_ARRAY_END) {
00186             if (ptr==buf) return 0;
00187             PRINT_MESG("WARNING: llsd_bin_get_length: unknown marker %c: %04x\n", *buf, *buf);
00188             break;
00189         }
00190 
00191         if (*buf==LLSD_MAKER_MAP) {
00192             push_char_ringStack(&stack, LLSD_MAKER_MAP_END);
00193             cc++;
00194             buf += 5;
00195         }
00196         else if (*buf==LLSD_MAKER_ARRAY) {
00197             push_char_ringStack(&stack, LLSD_MAKER_ARRAY_END);
00198             cc++;
00199             buf += 5;
00200         }
00201         else if (*buf==LLSD_MAKER_MAP_END || *buf==LLSD_MAKER_ARRAY_END) {
00202             unsigned char marker = (unsigned char)pop_char_ringStack(&stack);
00203             if (marker!=*buf) PRINT_MESG("WARNING: llsd_bin_get_length: missmatch stack data of [ or {\n");
00204             cc--;
00205             buf++;
00206         }
00207 
00208         if (cc==0) break;
00209     }   
00210 
00211     free_Buffer(&stack);
00212 
00213     return (int)(buf - ptr);
00214 }
00215 
00216 
00217 
00219 
00220 
00221 
00232 tXML*  llsd_bin_parse(uByte* ptr, int sz)
00233 {
00234     tXML* xml;
00235     tXML* node;
00236 
00237     xml = new_xml_node();                   
00238     xml->ldat.id = XML_ANCHOR_NODE;
00239 
00240     
00241     node = llsd_bin_main_parse(xml, ptr, sz);
00242     if (node->state<0) return xml;
00243 
00244 
00245     
00246     if (xml==node) {
00247         xml->state = JBXL_XML_PARSED;
00248     }
00249     else {
00250         xml->state = JBXL_XML_NOT_CLOSED;
00251     }
00252 
00253     
00254     if (xml->next!=NULL) {
00255         int n = 0;
00256         node = xml->next;
00257         while(node!=NULL) {
00258             if (node->ldat.id==XML_NAME_NODE) n++;
00259             node = node->ysis;
00260         }
00261         if (n!=1) xml->state = JBXL_XML_MULTI_ROOT;
00262     }
00263     else xml->state = JBXL_XML_DEFAULT_STATE;
00264 
00265     return xml;
00266 }
00267 
00268 
00279 tXML*  llsd_bin_main_parse(tXML* xml, uByte* ptr, int sz)
00280 {
00281     if (ptr==NULL) return xml;
00282     if (xml==NULL) return NULL;
00283 
00284     tXML* snode = xml = add_tTree_node_bystr(xml, XML_NAME_NODE, 0, "llsd", NULL, NULL, 0);
00285 
00286     uByte* end = ptr + sz;
00287     while (ptr<end  && !(xml==snode && *ptr!=LLSD_MAKER_MAP && *ptr!=LLSD_MAKER_ARRAY)) {
00288         
00289         if (*ptr==LLSD_MAKER_MAP) {
00290             ptr++;
00291             int num = llsd_bin_get_map(&ptr);
00292             xml = add_tTree_node_bystr(xml, XML_NAME_NODE, num, "map", NULL, NULL, 0);
00293             xml->state = JBXL_XML_NODE_OPENED;
00294         }
00295         
00296         else if (*ptr==LLSD_MAKER_ARRAY) {
00297             ptr++;
00298             int num = llsd_bin_get_map(&ptr);
00299             xml = add_tTree_node_bystr(xml, XML_NAME_NODE, num, "array", NULL, NULL, 0);
00300             xml->state = JBXL_XML_NODE_OPENED;
00301         }
00302         
00303         else if (*ptr==LLSD_MAKER_MAP_END) {
00304             ptr++;
00305             if (xml->state==JBXL_XML_NODE_OPENED) {
00306                 xml->state = JBXL_XML_NODE_CLOSED;
00307                 xml = xml->prev;
00308             }   
00309         }
00310         
00311         else if (*ptr==LLSD_MAKER_ARRAY_END) {
00312             ptr++;
00313             if (xml->state==JBXL_XML_NODE_OPENED) {
00314                 xml->state = JBXL_XML_NODE_CLOSED;
00315                 xml = xml->prev;
00316             }   
00317         }
00318         
00319         else if (*ptr==LLSD_MAKER_KEY) {
00320             ptr++;
00321             Buffer key = llsd_bin_get_key(&ptr);
00322             xml = add_tTree_node_bystr(xml, XML_NAME_NODE, 1, "key", NULL, NULL, 0);
00323             xml = add_tTree_node_bystr(xml, XML_CONTENT_NODE, 0, (char*)key.buf, NULL, NULL, 0);
00324             xml->state = JBXL_XML_NODE_CLOSED;
00325             xml = xml->prev;
00326             xml->state = JBXL_XML_NODE_CLOSED;
00327             xml = xml->prev;
00328             free_Buffer(&key);
00329         }
00330         
00331         else if (*ptr==LLSD_MAKER_STR) {
00332             ptr++;
00333             Buffer str = llsd_bin_get_str(&ptr);
00334             xml = add_tTree_node_bystr(xml, XML_NAME_NODE, 1, "string", NULL, NULL, 0);
00335             xml = add_tTree_node_bystr(xml, XML_CONTENT_NODE, 0, (char*)str.buf, NULL, NULL, 0);
00336             xml->state = JBXL_XML_NODE_CLOSED;
00337             xml = xml->prev;
00338             xml->state = JBXL_XML_NODE_CLOSED;
00339             xml = xml->prev;
00340             free_Buffer(&str);
00341         }
00342         
00343         else if (*ptr==LLSD_MAKER_UUID) {
00344             ptr++;
00345             Buffer uuid = llsd_bin_get_uri(&ptr);
00346             char*  guid = (char*)uuid2guid(uuid.buf);
00347             xml = add_tTree_node_bystr(xml, XML_NAME_NODE, 1, "uuid", NULL, NULL, 0);
00348             xml = add_tTree_node_bystr(xml, XML_CONTENT_NODE, 0, guid, NULL, NULL, 0);
00349             xml->state = JBXL_XML_NODE_CLOSED;
00350             xml = xml->prev;
00351             xml->state = JBXL_XML_NODE_CLOSED;
00352             xml = xml->prev;
00353             free(guid);
00354             free_Buffer(&uuid);
00355         }
00356         
00357         else if (*ptr==LLSD_MAKER_URI) {
00358             ptr++;
00359             Buffer str = llsd_bin_get_uri(&ptr);
00360             xml = add_tTree_node_bystr(xml, XML_NAME_NODE, 1, "uri", NULL, NULL, 0);
00361             xml = add_tTree_node_bystr(xml, XML_CONTENT_NODE, 0, (char*)str.buf, NULL, NULL, 0);
00362             xml->state = JBXL_XML_NODE_CLOSED;
00363             xml = xml->prev;
00364             xml->state = JBXL_XML_NODE_CLOSED;
00365             xml = xml->prev;
00366             free_Buffer(&str);
00367         }
00368         
00369         else if (*ptr==LLSD_MAKER_INT) {
00370             ptr++;
00371             int val = llsd_bin_get_int(&ptr);
00372             xml = add_tTree_node_bystr(xml, XML_NAME_NODE, 1, "integer", NULL, NULL, 0);
00373             char* str = itostr_ts(val);
00374             xml = add_tTree_node_bystr(xml, XML_CONTENT_NODE, 0, str, NULL, NULL, 0);
00375             freeNull(str);
00376             xml->state = JBXL_XML_NODE_CLOSED;
00377             xml = xml->prev;
00378             xml->state = JBXL_XML_NODE_CLOSED;
00379             xml = xml->prev;
00380         }
00381         
00382         else if (*ptr==LLSD_MAKER_DATE) {
00383             ptr++;
00384             unsigned long long int val = llsd_bin_get_date(&ptr);
00385             xml = add_tTree_node_bystr(xml, XML_NAME_NODE, 1, "date", NULL, NULL, 0);
00386             char* str = ulltostr_ts(val);
00387             xml = add_tTree_node_bystr(xml, XML_CONTENT_NODE, 0, str, NULL, NULL, 0);
00388             freeNull(str);
00389             xml->state = JBXL_XML_NODE_CLOSED;
00390             xml = xml->prev;
00391             xml->state = JBXL_XML_NODE_CLOSED;
00392             xml = xml->prev;
00393         }
00394         
00395         else if (*ptr==LLSD_MAKER_REAL) {
00396             ptr++;
00397             double val = llsd_bin_get_real(&ptr);
00398             xml = add_tTree_node_bystr(xml, XML_NAME_NODE, 1, "real", NULL, NULL, 0);
00399             char* str = dtostr_ts(val);
00400             xml = add_tTree_node_bystr(xml, XML_CONTENT_NODE, 0, str, NULL, NULL, 0);
00401             freeNull(str);
00402             xml->state = JBXL_XML_NODE_CLOSED;
00403             xml = xml->prev;
00404             xml->state = JBXL_XML_NODE_CLOSED;
00405             xml = xml->prev;
00406         }
00407         
00408         else if (*ptr==LLSD_MAKER_BIN) {
00409             ptr++;
00410             Buffer bin = llsd_bin_get_bin(&ptr);
00411             Buffer b64 = encode_base64_Buffer(bin);
00412             xml = add_tTree_node_bystr(xml, XML_NAME_NODE, 1, "binary", NULL, NULL, 0);
00413             xml = add_tTree_node_bystr(xml, XML_CONTENT_NODE, 0, (char*)b64.buf, NULL, NULL, 0);
00414             xml->state = JBXL_XML_NODE_CLOSED;
00415             xml = xml->prev;
00416             xml->state = JBXL_XML_NODE_CLOSED;
00417             xml = xml->prev;
00418             free_Buffer(&bin);
00419             free_Buffer(&b64);
00420         }
00421         
00422         else if (*ptr==LLSD_MAKER_TRUE) {
00423             ptr++;
00424             xml = add_tTree_node_bystr(xml, XML_NAME_NODE, 1, "boolean", NULL, NULL, 0);
00425             xml = add_tTree_node_bystr(xml, XML_CONTENT_NODE, 0, "true", NULL, NULL, 0);
00426             xml->state = JBXL_XML_NODE_CLOSED;
00427             xml = xml->prev;
00428             xml->state = JBXL_XML_NODE_CLOSED;
00429             xml = xml->prev;
00430         }
00431         
00432         else if (*ptr==LLSD_MAKER_FALSE) {
00433             ptr++;
00434             xml = add_tTree_node_bystr(xml, XML_NAME_NODE, 1, "boolean", NULL, NULL, 0);
00435             xml = add_tTree_node_bystr(xml, XML_CONTENT_NODE, 0, "false", NULL, NULL, 0);
00436             xml->state = JBXL_XML_NODE_CLOSED;
00437             xml = xml->prev;
00438             xml->state = JBXL_XML_NODE_CLOSED;
00439             xml = xml->prev;
00440         }
00441         
00442         else if (*ptr==LLSD_MAKER_UNDEF) {
00443             ptr++;
00444             xml = add_tTree_node_bystr(xml, XML_NAME_NODE, 0, "undef", NULL, NULL, 0);
00445             xml->state = JBXL_XML_NODE_CLOSED;
00446             xml = xml->prev;
00447         }
00448         else {
00449             PRINT_MESG("ERROR: llsd_bin_main_parse: unknown marker: %c (%04x)\n", *ptr, *ptr);
00450             ptr++;
00451         }
00452     }
00453 
00454     
00455     if (snode==xml) xml->state = JBXL_XML_NODE_CLOSED;
00456     else           xml->state = JBXL_XML_NOT_CLOSED;
00457 
00458     xml = xml->prev;
00459 
00460     return xml;
00461 }
00462 
00463 
00464 
00466 
00467 
00468 
00469 int  llsd_xml_contain_key(tXML* xml, const char* key)
00470 {
00471     if (xml==NULL || key==NULL) return FALSE;
00472 
00473     Buffer buf = make_Buffer_bystr("<llsd><map><key>");
00474     cat_s2Buffer(key, &buf);
00475     cat_s2Buffer("</key>", &buf);
00476 
00477     tXML* node = get_xml_node_bystr(xml, (char*)buf.buf);
00478     free_Buffer(&buf);
00479 
00480     if (node!=NULL) return TRUE;
00481     return FALSE;
00482 }
00483 
00484 
00487 int  llsd_xml_get_content_int(tXML* xml, const char* key, const char* item)
00488 {
00489     if (xml==NULL || key==NULL || item==NULL) return 0;
00490 
00491     Buffer buf = make_Buffer_bystr("<llsd><map><key>");
00492     cat_s2Buffer(key, &buf);
00493     cat_s2Buffer("</key><map><key>", &buf);
00494     cat_s2Buffer(item, &buf);
00495     cat_s2Buffer("</key><integer>", &buf);
00496 
00497     int ret = get_xml_int_content_bystr(xml, (char*)buf.buf);
00498     free_Buffer(&buf);
00499 
00500     return ret;
00501 }
00502 
00503 
00504 double  llsd_xml_get_content_real(tXML* xml, const char* key, const char* item)
00505 {
00506     if (xml==NULL || key==NULL || item==NULL) return 0.0;
00507 
00508     Buffer buf = make_Buffer_bystr("<llsd><map><key>");
00509     cat_s2Buffer(key, &buf);
00510     cat_s2Buffer("</key><map><key>", &buf);
00511     cat_s2Buffer(item, &buf);
00512     cat_s2Buffer("</key><real>", &buf);
00513 
00514     double ret = get_xml_double_content_bystr(xml, (char*)buf.buf);
00515     free_Buffer(&buf);
00516 
00517     return ret;
00518 }
00519 
00520 
00521 Buffer  llsd_xml_get_content_str(tXML* xml, const char* key, const char* item)
00522 {
00523     Buffer buf = init_Buffer();
00524     if (xml==NULL || key==NULL || item==NULL) return buf;
00525 
00526     buf = make_Buffer_bystr("<llsd><map><key>");
00527     cat_s2Buffer(key, &buf);
00528     cat_s2Buffer("</key><map><key>", &buf);
00529     cat_s2Buffer(item, &buf);
00530     cat_s2Buffer("</key><string>", &buf);
00531 
00532     char* ret = get_xml_char_content_bystr(xml, (char*)buf.buf);
00533     free_Buffer(&buf);
00534     buf = make_Buffer_bystr(ret);
00535 
00536     return buf;
00537 }
00538 
00539 
00540 Buffer  llsd_xml_get_content_bin(tXML* xml, const char* key, const char* item)
00541 {
00542     Buffer buf = init_Buffer();
00543     if (xml==NULL || key==NULL || item==NULL) return buf;
00544 
00545     buf = make_Buffer_bystr("<llsd><map><key>");
00546     cat_s2Buffer(key, &buf);
00547     cat_s2Buffer("</key><map><key>", &buf);
00548     cat_s2Buffer(item, &buf);
00549     cat_s2Buffer("</key><binary>", &buf);
00550 
00551     char* ret = get_xml_char_content_bystr(xml, (char*)buf.buf);
00552     free_Buffer(&buf);
00553     buf = make_Buffer_bystr(ret);
00554     
00555     Buffer bin = decode_base64_Buffer(buf);
00556     free_Buffer(&buf);
00557 
00558     return bin;
00559 }
00560