json.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdarg.h>
  5. #include "common.h"
  6. #include "json.h"
  7. /**
  8. * TODO: 1. Redo the json_obj structure to be able to hold several.
  9. * Now only hols several members and pairs. Can hold several.
  10. * 2. Save to file
  11. * 3. Encoding of values; e.g unicode values and special chars.
  12. * 4. json_from_file; parser?
  13. **/
  14. /**
  15. * Structure: json_type
  16. * Typedef: json_type_t
  17. * Author: Joachim M. Giæver
  18. *
  19. * Sections:
  20. * json_types_t type: Type of an JSON-entry.
  21. *
  22. * Description:
  23. * Holds the type of an JSON-entry.
  24. **/
  25. struct json_type {
  26. json_types_t type;
  27. };
  28. /**
  29. * JSON-entry types
  30. **/
  31. /**
  32. * Structure:
  33. * Typedef:
  34. * Author: Joachim M. Giæver
  35. *
  36. * Sections:
  37. * json_types_t type: Entry type (MUST BE FIRST)
  38. * json_mem_t *members: JSON-meners entries.
  39. * print_type_t ptype: Print type, eg Pretty print.
  40. * int code: Status code.
  41. *
  42. * Description:
  43. * Defines an JSON-object.
  44. **/
  45. struct json_obj {
  46. json_types_t type;
  47. json_mem_t *members;
  48. print_type_t ptype;
  49. json_printf_t *pfunc;
  50. FILE *jfile;
  51. int code;
  52. };
  53. /**
  54. * Structure: json_mem
  55. * Typedef: json_mem_t
  56. * Author: Joachim M. Giæver
  57. *
  58. * Sections:
  59. * json_types_t type: Entry type (MUST BE FIRST)
  60. * void *entry: Containing entry. Either pair or new member
  61. * void *next: Simblings; other members or pairs in parent.
  62. *
  63. * Description:
  64. * Defines an JSON-member entry
  65. **/
  66. struct json_mem {
  67. json_types_t type;
  68. void *entry;
  69. void *next;
  70. };
  71. /**
  72. * Structure: json_elem
  73. * Typedef: json_elem_t
  74. * Author: Joachim M. Giæver
  75. *
  76. * Sections:
  77. * json_types_t type: Entry type (MUST BE FIRST).
  78. * void *entry: Containing entry. Either value or new element.
  79. * void *next: Simblings; other elements in parent.
  80. *
  81. * Description:
  82. * Defines an JSON-element entry.
  83. **/
  84. struct json_elem {
  85. json_types_t type;
  86. void *entry;
  87. void *next;
  88. };
  89. /**
  90. * Structure: json_pair
  91. * Typedef: json_pair_t
  92. * Author: Joachim M. Giæver
  93. *
  94. * Sections:
  95. * json_types_t type: Entry type (MUST BE FIRST).
  96. * char *str: String specifier.
  97. * json_val_t *value; Containing entry, only value.
  98. * void *next: Simblings; other members or pairs in parent.
  99. *
  100. * Description:
  101. *
  102. **/
  103. struct json_pair {
  104. json_types_t type;
  105. char *str;
  106. json_val_t *value;
  107. void *next;
  108. };
  109. /**
  110. * Structure: json_arr
  111. * Typedef: json_arr_t
  112. * Author: Joachim M. Giæver
  113. *
  114. * Sections:
  115. * json_types_t type: Entry type (MUST BE FIRST).
  116. * void *entry: Containing entry, only elements.
  117. *
  118. * Description:
  119. * Defines a JSON-array entry.
  120. **/
  121. struct json_arr {
  122. json_types_t type;
  123. json_elem_t *entry;
  124. };
  125. /**
  126. * Structure: json_val
  127. * Typedef: json_val_t
  128. * Author: Joachim M. Giæver
  129. *
  130. * Sections:
  131. * json_types_t type: Entry type (MUST BE FIRST).
  132. * json_types_t sub_type: Type of the sub entry, eg JSON_INT, _CHAR etc
  133. * void *value: The actual entry
  134. *
  135. * Description:
  136. *
  137. **/
  138. struct json_val {
  139. json_types_t type;
  140. json_types_t sub_type;
  141. void *value;
  142. };
  143. /**
  144. * Function: json_ptype
  145. * Author: Joachim M. Giæver
  146. *
  147. * Parameters:
  148. * - print_type_t ptype: Print type
  149. *
  150. * Description:
  151. * Validates and sets the print type, e.g
  152. * Pretty Print, Print etc. (File save not implemented)
  153. *
  154. * Returns: int, the print type value
  155. **/
  156. static int json_ptype( print_type_t ptype );
  157. /**
  158. * Function: json_set_code
  159. * Author: Joachim M. Giæver
  160. *
  161. * Parameters:
  162. * - json_obj_t *jobj: JSON-object to set status for
  163. * - int code: The status code to set
  164. *
  165. * Description:
  166. * Sets the status code of the last event
  167. * of types related to the JSON-object.
  168. *
  169. * Returns: int, the newly set code
  170. **/
  171. static int json_set_code( json_obj_t *jobj, int code );
  172. /**
  173. * Function: json_get_type
  174. * Author: Joachim M. Giæver
  175. *
  176. * Parameters:
  177. * - void *entry: The JSON-entry to read type of
  178. *
  179. * Description:
  180. * Returns the type of the JSON-entry.
  181. *
  182. * Returns: json_types_t, the type
  183. **/
  184. static json_types_t json_get_type( void *entry );
  185. /**
  186. * Function: json_is_type
  187. * Author: Joachim M. Giæver
  188. *
  189. * Parameters:
  190. * - void *entry: The JSON-entry to check
  191. * - json_types_t: The JSON-type compare against
  192. *
  193. * Description:
  194. * Checks the equality of the type of the entry
  195. * agains the given type.
  196. *
  197. * Returns: int, 1 on success, 0 on failure
  198. **/
  199. static int json_is_type( void *entry, json_types_t jtype );
  200. /**
  201. * Function: json_uninit_obj
  202. * Author: Joachim M. Giæver
  203. *
  204. * Parameters:
  205. * - json_obj_t *jobj: The JSON-object (parent of obj)
  206. * - void *obj: Any kind of object within parent
  207. *
  208. * Description:
  209. * Checks if the JSON-object is uninitialized. Checks
  210. * both the root (jobj) and sub obj.
  211. *
  212. * Returns: int, 1 on failure, 0 on success
  213. **/
  214. static int json_uninit_obj( json_obj_t *jobj, void *obj );
  215. /**
  216. * Function: json_val_vtype
  217. * Author: Joachim M. Giæver
  218. *
  219. * Parameters:
  220. * - json_obj_t *jobj: Parent JSON-object
  221. * - json_types_t *vtype: The value type
  222. *
  223. * Description:
  224. * Checks if the given type is valid as a value, for
  225. * the value entry.
  226. *
  227. * Returns: int, 1 on success, 0 on failure
  228. **/
  229. static int json_val_vtype( json_obj_t *jobj, json_types_t vtype );
  230. /**
  231. * Function: json_insert
  232. * Author: Joachim M. Giæver
  233. *
  234. * Parameters:
  235. * - json_obj_t *jobj: Parent JSON-obj
  236. * - void *root: Root-entry, an JSON-entry
  237. * - void *entry: New entry, valid for root-entry
  238. *
  239. * Description:
  240. * Inserts an entry into the root, which is related
  241. * to the parent JSON-obj. Insertion method and possibilities
  242. * depends on the root-entry.
  243. *
  244. * Returns: void *, address to newly inserte entry
  245. **/
  246. static void *json_insert( json_obj_t *jobj, void *root, void *entry );
  247. /** Recursice functions to print the tree **/
  248. static void _json_out( json_obj_t *jobj, int height );
  249. static void _print_( json_obj_t *jobj, ... );
  250. static void _print_mem( json_obj_t *jobj, json_mem_t *jmem, int height );
  251. static void _print_pair( json_obj_t *jobj, json_pair_t *jpair, int height );
  252. static void _print_arr( json_obj_t *jobj, json_arr_t *jarr, int height );
  253. static void _print_elem( json_obj_t *jobj, json_elem_t *jelem, int height );
  254. static void _print_value( json_obj_t *jobj, json_val_t *jval, int height );
  255. static char *_print_set_newline( json_obj_t *jobj );
  256. static void _print_tabs_release( char *tabs );
  257. static char *_print_tabs( json_obj_t *jobj, int height );
  258. /** Silence in comments is like nothing was here */
  259. /**
  260. * Function: json_create
  261. * Author: Joachim M. Giæver
  262. *
  263. * Parameters:
  264. * - char *fname: The filename; on saving
  265. and possible parsing - in the future.
  266. * - print_type_t ptype: Store/print type
  267. *
  268. * Description:
  269. * Creates the main root of the JSON-structure.
  270. *
  271. * Returns: json_obj_t *, the mother root
  272. **/
  273. json_obj_t *json_create( char *fname, print_type_t ptype ) {
  274. json_obj_t *jobj = ( json_obj_t *) malloc( sizeof( json_obj_t ) );
  275. if ( jobj == NULL )
  276. errandend( "Could not allocate memory for JSON object" );
  277. jobj->type = JSON_OBJ;
  278. jobj->members = NULL;
  279. jobj->ptype = json_ptype( ptype );
  280. if ( (jobj->ptype & JSON_SAVE_FILE) == JSON_SAVE_FILE ) {
  281. jobj->jfile = fopen( fname, "w+" );
  282. if ( jobj->jfile == NULL ) {
  283. printf("%s\n", fname );
  284. errandend( "Could not open file for reading/writing." );
  285. }
  286. jobj->pfunc = (json_printf_t *)fprintf;
  287. } else {
  288. jobj->jfile = NULL;
  289. jobj->pfunc = (json_printf_t *)printf;
  290. }
  291. json_set_code( jobj, jobj->ptype );
  292. return jobj;
  293. }
  294. /**
  295. * Function: json_destroy
  296. * Author: Joachim M. Giæver
  297. *
  298. * Parameters:
  299. * - json_obj_t *jobj: JSON-object to destroy
  300. *
  301. * Description:
  302. * Destroys any kind of JSON-objects
  303. *
  304. * Returns: void
  305. **/
  306. void json_destroy( json_obj_t *jobj ) {
  307. if ( jobj == NULL )
  308. return;
  309. if ( jobj->members != NULL )
  310. json_destroy_mem( jobj->members );
  311. if ( jobj->jfile != NULL )
  312. fclose( jobj->jfile );
  313. free( jobj );
  314. }
  315. /**
  316. * Function: json_create_obj
  317. * Author: Joachim M. Giæver
  318. *
  319. * Parameters:
  320. * - json_obj_t *jobj: JSON-object which is the main-root
  321. * - json_val_t *jval: JSON-value to insert to
  322. *
  323. * Description:
  324. * Creates a new JSON-object to insert into the
  325. * JSON-structure (only into JSON-value.).
  326. *
  327. * Works recursivly on children.
  328. *
  329. * Returns: json_obj_t *, JSON-object
  330. **/
  331. json_obj_t *json_create_obj( json_obj_t *jobj, json_val_t *jval ) {
  332. json_obj_t *jcobj;
  333. if ( json_uninit_obj( jobj, jval ) )
  334. return NULL;
  335. jcobj = json_create( "", jobj->ptype );
  336. if ( json_insert( jobj, jval, jobj ) != NULL )
  337. return jcobj;
  338. json_destroy( jcobj );
  339. return NULL;
  340. }
  341. /**
  342. * Function: json_create_mem
  343. * Author: Joachim M. Giæver
  344. *
  345. * Parameters:
  346. * - json_obj_t *jobj: JSON-object to insert to
  347. *
  348. * Description:
  349. * Creates a new JSON-member and inserts it into the
  350. * JSON-object. May be any kind of JSON-object, both
  351. * root or children.
  352. *
  353. * Returns: json_mem_t *, JSON-member
  354. **/
  355. json_mem_t *json_create_mem( json_obj_t *jobj ) {
  356. json_mem_t *jmem;
  357. if ( json_has_err( jobj ) )
  358. return NULL;
  359. jmem = ( json_mem_t *) malloc( sizeof( json_mem_t ) );
  360. if ( jmem == NULL ) {
  361. json_set_code( jobj, JSON_NOMEM );
  362. return NULL;
  363. }
  364. jmem->type = JSON_MEM;
  365. jmem->entry = NULL;
  366. jmem->next = NULL;
  367. if ( json_insert( jobj, jobj, jmem ) != NULL )
  368. return jmem;
  369. json_destroy_mem( jmem );
  370. return NULL;
  371. }
  372. /**
  373. * Function: json_destroy_mem
  374. * Author: Joachim M. Giæver
  375. *
  376. * Parameters:
  377. * - json_mem_t *jmem: JSON-member to destroy
  378. *
  379. * Description:
  380. * Destroy a JSON-member, works recursively on both simblings
  381. * and children.
  382. *
  383. * Returns: void
  384. **/
  385. void json_destroy_mem( json_mem_t *jmem ) {
  386. if ( jmem == NULL )
  387. return;
  388. if ( jmem->entry != NULL ) {
  389. if ( json_is_type( jmem->entry, JSON_PAIR ) )
  390. json_destroy_pair( jmem->entry );
  391. else
  392. json_destroy_mem( jmem->entry );
  393. }
  394. if ( jmem->next != NULL ) {
  395. if ( json_is_type( jmem->next, JSON_PAIR ) )
  396. json_destroy_pair( jmem->next );
  397. else
  398. json_destroy_mem( jmem->next );
  399. }
  400. free( jmem );
  401. }
  402. /**
  403. * Function: json_create_pair
  404. * Author: Joachim M. Giæver
  405. *
  406. * Parameters:
  407. * - json_obj_t *jobj: JSON-object which is the main-root
  408. * - json_mem_t *jmem: JSON-member to insert to
  409. *
  410. * Description:
  411. * Creates a new JSON-pair and inserts it into a JSON-member.
  412. *
  413. * Returns: json_pair_t *, JSON-pair
  414. **/
  415. json_pair_t *json_create_pair( json_obj_t *jobj, json_mem_t *jmem, char *str ) {
  416. json_pair_t *jpair;
  417. if ( json_uninit_obj( jobj, jmem ) )
  418. return NULL;
  419. jpair = ( json_pair_t *) malloc( sizeof( json_pair_t ) );
  420. if ( jpair == NULL ) {
  421. json_set_code( jobj, JSON_NOMEM );
  422. return NULL;
  423. }
  424. jpair->type = JSON_PAIR;
  425. jpair->str = strdup( str );
  426. jpair->value = NULL;
  427. jpair->next = NULL;
  428. if ( json_insert( jobj, jmem, jpair ) != NULL )
  429. return jpair;
  430. json_destroy_pair( jpair );
  431. return NULL;
  432. }
  433. /**
  434. * Function: json_destroy_pair
  435. * Author: Joachim M. Giæver
  436. *
  437. * Parameters:
  438. * - json_pair_t *jpair: JSON-pair to destroy
  439. *
  440. * Description:
  441. * Destroys a JSON-pair. Works recursively on both the simblings
  442. * and children.
  443. *
  444. * Returns: void
  445. **/
  446. void json_destroy_pair( json_pair_t *jpair ) {
  447. if ( jpair == NULL )
  448. return;
  449. if ( jpair->value != NULL )
  450. json_destroy_value( jpair->value );
  451. if ( jpair->next != NULL ) {
  452. if ( json_is_type( jpair->next, JSON_PAIR ) )
  453. json_destroy_pair( jpair->next );
  454. else
  455. json_destroy_mem( jpair->next );
  456. }
  457. free( jpair->str );
  458. free( jpair );
  459. }
  460. /**
  461. * Function: json_create_arr
  462. * Author: Joachim M. Giæver
  463. *
  464. * Parameters:
  465. * - json_obj_t *jobj: JSON-object which is the main-root
  466. * - json_val_t *jval: JSON-value to insert to
  467. *
  468. * Description:
  469. * Creates a new JSON-array and inserts it into JSON-value.
  470. *
  471. * Returns: json_arr_t *, JSON-array
  472. **/
  473. json_arr_t *json_create_arr( json_obj_t *jobj, json_val_t *jval ) {
  474. json_arr_t *jarr;
  475. if ( json_uninit_obj( jobj, jval ) )
  476. return NULL;
  477. jarr = ( json_arr_t *) malloc( sizeof( json_arr_t ) );
  478. if ( jarr == NULL ) {
  479. json_set_code( jobj, JSON_NOMEM );
  480. return NULL;
  481. }
  482. jarr->type = JSON_ARR;
  483. jarr->entry = NULL;
  484. if ( json_insert( jobj, jval, jarr ) != NULL )
  485. return jarr;
  486. json_destroy_arr( jarr );
  487. return NULL;
  488. }
  489. /**
  490. * Function: json_destroy_arr
  491. * Author: Joachim M. Giæver
  492. *
  493. * Parameters:
  494. * - json_arr_t *jarr: JSON-array to destroy
  495. *
  496. * Description:
  497. * Destroys a JSON-array. Works recursively on the children.
  498. *
  499. * Returns: void
  500. **/
  501. void json_destroy_arr( json_arr_t *jarr ) {
  502. if ( jarr == NULL )
  503. return;
  504. if ( jarr->entry != NULL )
  505. json_destroy_elem( jarr->entry );
  506. free( jarr );
  507. }
  508. /**
  509. * Function: json_create_elem
  510. * Author: Joachim M. Giæver
  511. *
  512. * Parameters:
  513. * - json_obj_t *jobj: JSON-object which is the main-root
  514. * - json_arr_t *jarr: JSON-array to insert into
  515. *
  516. * Description:
  517. * Creates a JSON-element and inserts it int an JSON-array.
  518. *
  519. * Returns: json_elem_t *, JSON-element
  520. **/
  521. json_elem_t *json_create_elem( json_obj_t *jobj, json_arr_t *jarr ) {
  522. json_elem_t *jelem;
  523. if ( json_uninit_obj( jobj, jarr ) )
  524. return NULL;
  525. jelem = ( json_elem_t *) malloc( sizeof( json_elem_t ) );
  526. if ( jelem == NULL ) {
  527. json_set_code( jobj, JSON_NOMEM );
  528. return NULL;
  529. }
  530. jelem->type = JSON_ELEM;
  531. jelem->entry = NULL;
  532. jelem->next = NULL;
  533. if ( json_insert( jobj, jarr, jelem ) != NULL )
  534. return jelem;
  535. json_destroy_elem( jelem );
  536. return NULL;
  537. }
  538. /**
  539. * Function: json_destroy_elem
  540. * Author: Joachim M. Giæver
  541. *
  542. * Parameters:
  543. * - json_elem_t *jelem: JSON-element to destroy
  544. *
  545. * Description:
  546. * Destroys a JSON-element. Works recursively on both simblings
  547. * and children.
  548. *
  549. * Returns: void
  550. **/
  551. void json_destroy_elem( json_elem_t *jelem ) {
  552. if ( jelem == NULL )
  553. return;
  554. if ( jelem->entry != NULL )
  555. json_destroy_value( jelem->entry );
  556. if ( jelem->next != NULL )
  557. json_destroy_elem( jelem->next );
  558. free( jelem );
  559. }
  560. /**
  561. * Function: json_insert_value
  562. * Author: Joachim M. Giæver
  563. *
  564. * Parameters:
  565. * - json_obj_t *jobj: JSON-object which is the main-root
  566. * - void *ins_obj: Object or element to insert into
  567. * - json_types_t vtype: Type of the held element in value
  568. * - void *entry: Entry to store in value
  569. *
  570. * Description:
  571. * Creates a new JSON-value and inserts it into a JSON-element or
  572. * a JSON-pair. The value must also be specified. JSON-object and
  573. * JSON-array can be insert upon creation by setting entry as NULL.
  574. *
  575. * Ex:
  576. *
  577. * // Insert this value into a JSON-pair, will contain an JSON-array
  578. * json_val_t *jvalue = json_insert_value( jobj, jpair, JSON_ARR, NULL );
  579. *
  580. * // Create the JSON-array and insert it into the above value
  581. * json_arr_t *jarr = json_create_arr( jobj, jval );
  582. *
  583. * Returns: json_val_t *, JSON-value
  584. **/
  585. json_val_t *json_insert_value( json_obj_t *jobj, void *ins_obj, json_types_t vtype, void *entry ) {
  586. json_val_t *jval;
  587. if ( vtype != JSON_NULL && ( ( vtype != JSON_OBJ && vtype != JSON_ARR && json_uninit_obj( jobj, entry ) ) || json_val_vtype( jobj, vtype ) < 0 ) )
  588. return NULL;
  589. jval = ( json_val_t *) malloc( sizeof( json_val_t ) );
  590. if ( jval == NULL ) {
  591. json_set_code( jobj, JSON_NOMEM );
  592. return NULL;
  593. }
  594. jval->type = JSON_VAL;
  595. jval->sub_type = vtype;
  596. if ( vtype == JSON_OBJ || vtype == JSON_ARR ) {
  597. /* By now; nothing to do */
  598. } else {
  599. switch( vtype ) {
  600. case JSON_CHAR:
  601. jval->value = strdup( (char *)entry );
  602. break;
  603. case JSON_INT:
  604. jval->value = (int *) malloc( sizeof( int ) );
  605. memcpy( jval->value, ((const void *)entry), sizeof( int ) );
  606. break;
  607. case JSON_FLOAT:
  608. jval->value = (float *) malloc( sizeof( int ) );
  609. memcpy( jval->value, ((const void *)entry), sizeof( float ) );
  610. break;
  611. case JSON_BOOL:
  612. jval->value = strdup( *((bool *)entry) == true ? "true" : "false" );
  613. break;
  614. case JSON_NULL:
  615. jval->value = strdup( entry == NULL ? "null" : "" );
  616. break;
  617. default:
  618. json_set_code( jobj, JSON_INVALID_VAL_TYPE );
  619. break;
  620. }
  621. json_set_code( jobj, JSON_INS_VAL_VAL );
  622. }
  623. if ( json_insert( jobj, ins_obj, jval ) != NULL )
  624. return jval;
  625. json_destroy_value( jval );
  626. return NULL;
  627. }
  628. /**
  629. * Function: json_destroy_value
  630. * Author: Joachim M. Giæver
  631. *
  632. * Parameters:
  633. * - json_val_t *jval: JSON-value to destroy
  634. *
  635. * Description:
  636. * Destroys a JSON-value. Works recursively on children.
  637. *
  638. * Returns: void
  639. **/
  640. void json_destroy_value( json_val_t *jval ) {
  641. if ( jval == NULL )
  642. return;
  643. switch( jval->sub_type ) {
  644. case JSON_OBJ:
  645. json_destroy( jval->value );;
  646. break;
  647. case JSON_ARR:
  648. json_destroy_arr( jval->value );
  649. break;
  650. case JSON_CHAR:
  651. case JSON_INT:
  652. case JSON_FLOAT:
  653. case JSON_BOOL:
  654. case JSON_NULL:
  655. free( jval->value );
  656. break;
  657. default:
  658. break;
  659. }
  660. free( jval );
  661. }
  662. /**
  663. * Function: json_has_err
  664. * Author: Joachim M. Giæver
  665. *
  666. * Parameters:
  667. * - json_obj_t *jobj: JSON-object which is the main-root
  668. *
  669. * Description:
  670. * Returns whether or not there was an error present on last event.
  671. *
  672. * Returns: int 0 on non errors 1 on errors
  673. **/
  674. int json_has_err( json_obj_t *jobj ) {
  675. if ( jobj == NULL )
  676. return JSON_UNINITALIZED_OJB;
  677. return ( jobj->code >= 0 ? 0 : 1 );
  678. }
  679. /**
  680. * Function: json_last_err
  681. * Author: Joachim M. Giæver
  682. *
  683. * Parameters:
  684. * - json_obj_t *jobj: JSON-object which is the main-root
  685. *
  686. * Description:
  687. * Returns the last error code present.
  688. *
  689. * Returns: int, >= 0 on non errors <= 0 on errors
  690. **/
  691. int json_last_err( json_obj_t *jobj ) {
  692. if ( jobj == NULL )
  693. return JSON_UNINITALIZED_OJB;
  694. return jobj->code;
  695. }
  696. /**
  697. * Function: json_last_errmsg
  698. * Author: Joachim M. Giæver
  699. *
  700. * Parameters:
  701. * - json_obj_t *jobj: JSON-object which is the main-root
  702. *
  703. * Description:
  704. * Returns the error message related to the error code
  705. * stored in the JSON-object (remember to check for errors; json_has_err).
  706. *
  707. * Returns: char *, error message
  708. **/
  709. const char *json_last_errmsg( json_obj_t *jobj ) {
  710. char *errmsg;
  711. int errcode = json_last_err( jobj );
  712. switch( errcode ) {
  713. case JSON_NO_REPORT:
  714. errmsg = "Not an error";
  715. break;
  716. case JSON_UNKNOWN_PTYPE:
  717. errmsg = "Unknown print type";
  718. break;
  719. case JSON_UNINITALIZED_OJB:
  720. errmsg = "Un-initialized JSON object";
  721. break;
  722. case JSON_NOMEM:
  723. errmsg = "Out of memory";
  724. break;
  725. case JSON_INVALID_VAL_TYPE:
  726. errmsg = "Invalid type to insert within value object";
  727. break;
  728. case JSON_INVALID_ROOT_ENT:
  729. case JSON_INVALID_OBJ_ENT:
  730. case JSON_INVALID_MEM_ENT:
  731. case JSON_INVALID_PAIR_ENT:
  732. case JSON_INVALID_ELE_MENT:
  733. case JSON_INVALID_VAL_ENT:
  734. case JSON_INVALID_ELEM_ENT:
  735. case JSON_INVALID_ARR_ENT:
  736. errmsg = "Invalid object to insert within parent object";
  737. break;
  738. case JSON_MIXED_VAL_AND_TYPE:
  739. errmsg = "Mixed value and type.";
  740. break;
  741. default:
  742. errmsg = "Error code unknown or not implemented";
  743. break;
  744. }
  745. return (const char *)errmsg;
  746. }
  747. /**
  748. * Function: json_out
  749. * Author: Joachim M. Giæver
  750. *
  751. * Parameters:
  752. * - json_obj_t *jobj: JSON-object which is the main-root
  753. *
  754. * Description:
  755. * Recursively prints the JSON-object.
  756. *
  757. * Returns: void
  758. **/
  759. void json_out( json_obj_t *jobj ) {
  760. int height = 1;
  761. _print_( jobj, "[%s", _print_set_newline(jobj) );
  762. _json_out( jobj, height );
  763. _print_( jobj, "]%s", _print_set_newline(jobj) );
  764. }
  765. /**
  766. * Function: json_ptype
  767. * Author: Joachim M. Giæver
  768. *
  769. * Parameters:
  770. * - print_type_t ptype: Print type
  771. *
  772. * Description:
  773. * Validates and sets the print type, e.g
  774. * Pretty Print, Print etc. (File save not implemented)
  775. *
  776. * Returns: int, the print type value
  777. **/
  778. static int json_ptype( print_type_t ptype ) {
  779. return ( ptype > JSON_SAVE_FILE - 1 && ptype < JSON_TYPE ? ptype : JSON_UNKNOWN_PTYPE );
  780. }
  781. /**
  782. * Function: json_set_code
  783. * Author: Joachim M. Giæver
  784. *
  785. * Parameters:
  786. * - json_obj_t *jobj: JSON-object to set status for
  787. * - int code: The status code to set
  788. *
  789. * Description:
  790. * Sets the status code of the last event
  791. * of types related to the JSON-object.
  792. *
  793. * Returns: int, the newly set code
  794. **/
  795. static int json_set_code( json_obj_t *jobj, int code ) {
  796. if ( jobj == NULL )
  797. return jobj->code = JSON_UNINITALIZED_OJB;
  798. return jobj->code = code;
  799. }
  800. /**
  801. * Function: json_get_type
  802. * Author: Joachim M. Giæver
  803. *
  804. * Parameters:
  805. * - void *entry: The JSON-entry to read type of
  806. *
  807. * Description:
  808. * Returns the type of the JSON-entry.
  809. *
  810. * Returns: json_types_t, the type
  811. **/
  812. static json_types_t json_get_type( void *entry ) {
  813. json_type_t *type = (json_type_t *)entry;
  814. return type->type;
  815. }
  816. /**
  817. * Function: json_is_type
  818. * Author: Joachim M. Giæver
  819. *
  820. * Parameters:
  821. * - void *entry: The JSON-entry to check
  822. * - json_types_t: The JSON-type compare against
  823. *
  824. * Description:
  825. * Checks the equality of the type of the entry
  826. * agains the given type.
  827. *
  828. * Returns: int, 1 on success, 0 on failure
  829. **/
  830. static int json_is_type( void *entry, json_types_t jtype ) {
  831. return json_get_type( entry ) == jtype;
  832. }
  833. /**
  834. * Function: json_uninit_obj
  835. * Author: Joachim M. Giæver
  836. *
  837. * Parameters:
  838. * - json_obj_t *jobj: The JSON-object (parent of obj)
  839. * - void *obj: Any kind of object within parent
  840. *
  841. * Description:
  842. * Checks if the JSON-object is uninitialized. Checks
  843. * both the root (jobj) and sub obj.
  844. *
  845. * Returns: int, 1 on failure, 0 on success
  846. **/
  847. static int json_uninit_obj( json_obj_t *jobj, void *obj ) {
  848. if ( json_has_err( jobj ) )
  849. return 0;
  850. if ( obj == NULL ) {
  851. json_set_code( jobj, JSON_UNINITALIZED_OJB );
  852. return 1;
  853. }
  854. return 0;
  855. }
  856. /**
  857. * Function: json_val_vtype
  858. * Author: Joachim M. Giæver
  859. *
  860. * Parameters:
  861. * - json_obj_t *jobj: Parent JSON-object
  862. * - json_types_t *vtype: The value type
  863. *
  864. * Description:
  865. * Checks if the given type is valid as a value, for
  866. * the value entry.
  867. *
  868. * Returns: int, 1 on success, 0 on failure
  869. **/
  870. static int json_val_vtype( json_obj_t *jobj, json_types_t vtype ) {
  871. int i;
  872. json_types_t val_types[7] = {
  873. JSON_OBJ, JSON_ARR, JSON_CHAR, JSON_INT, JSON_FLOAT, JSON_BOOL, JSON_NULL
  874. };
  875. for ( i = 0; i < sizeof( val_types ); i++ ) {
  876. if ( vtype == val_types[ i ] )
  877. return ( jobj == NULL ? JSON_INS_TYPE_VAL : json_set_code( jobj, JSON_INS_TYPE_VAL ) );
  878. }
  879. return ( jobj == NULL ? JSON_INVALID_VAL_TYPE : json_set_code( jobj, JSON_INVALID_VAL_TYPE ) );
  880. }
  881. /**
  882. * Function: json_insert
  883. * Author: Joachim M. Giæver
  884. *
  885. * Parameters:
  886. * - json_obj_t *jobj: Parent JSON-obj
  887. * - void *root: Root-entry, an JSON-entry
  888. * - void *entry: New entry, valid for root-entry
  889. *
  890. * Description:
  891. * Inserts an entry into the root, which is related
  892. * to the parent JSON-obj. Insertion method and possibilities
  893. * depends on the root-entry.
  894. *
  895. * Returns: void *, address to newly inserte entry
  896. **/
  897. static void *json_insert( json_obj_t *jobj, void *root, void *entry ) {
  898. void *tmp;
  899. if ( json_has_err( jobj ) )
  900. return NULL;
  901. switch( json_get_type( root ) ) {
  902. case JSON_OBJ:
  903. if ( !json_is_type( entry, JSON_MEM ) ) {
  904. json_set_code( jobj, JSON_INVALID_OBJ_ENT );
  905. return NULL;
  906. }
  907. tmp = ((json_obj_t *)root)->members;
  908. while( tmp != NULL && ((json_mem_t *)tmp)->next != NULL )
  909. tmp = ((json_mem_t *)tmp)->next;
  910. if ( tmp == NULL )
  911. ((json_obj_t *)root)->members = (json_mem_t *)entry;
  912. else
  913. ((json_mem_t *)tmp)->next = (json_mem_t *)entry;
  914. json_set_code( jobj, JSON_INS_MEM_OBJ );
  915. break;
  916. case JSON_MEM:
  917. switch( json_get_type( entry ) ) {
  918. case JSON_PAIR:
  919. case JSON_MEM:
  920. tmp = ((json_mem_t *)root)->entry;
  921. if ( tmp == NULL )
  922. ((json_mem_t *)root)->entry = entry;
  923. while( tmp != NULL && ( ( json_is_type( entry, JSON_MEM ) && ((json_mem_t *)tmp)->next != NULL ) || ( json_is_type( entry, JSON_PAIR ) && ((json_pair_t *)tmp)->next != NULL ) ) ) {
  924. tmp = ( json_is_type( entry, JSON_MEM ) ? ((json_mem_t *)tmp)->next : ((json_pair_t *)tmp)->next );
  925. }
  926. if ( tmp != NULL ) {
  927. if ( json_is_type( entry, JSON_MEM ) )
  928. ((json_mem_t *)tmp)->next = entry;
  929. else
  930. ((json_pair_t *)tmp)->next = entry;
  931. }
  932. json_set_code( jobj, JSON_INS_PAIR_MEM );
  933. break;
  934. default:
  935. json_set_code( jobj, JSON_INVALID_MEM_ENT );
  936. break;
  937. }
  938. break;
  939. case JSON_PAIR:
  940. if ( !json_is_type( entry, JSON_VAL ) ) {
  941. json_set_code( jobj, JSON_INVALID_PAIR_ENT );
  942. return NULL;
  943. }
  944. ((json_pair_t *)root)->value = entry;
  945. json_set_code( jobj, JSON_INS_VAL_PAIR );
  946. break;
  947. case JSON_ELEM:
  948. if ( !json_is_type( entry, JSON_VAL ) ) {
  949. json_set_code( jobj, JSON_INVALID_ELEM_ENT );
  950. break;
  951. }
  952. tmp = ((json_elem_t *)root)->entry;
  953. if ( tmp != NULL )
  954. json_destroy_value( tmp );
  955. ((json_elem_t *)root)->entry = entry;
  956. json_set_code( jobj, JSON_INS_VAL_ELEM );
  957. break;
  958. case JSON_ARR:
  959. if ( !json_is_type( entry, JSON_ELEM ) ) {
  960. json_set_code( jobj, JSON_INVALID_ARR_ENT );
  961. return NULL;
  962. }
  963. tmp = ((json_arr_t *)root)->entry;
  964. if ( tmp == NULL )
  965. ((json_arr_t *)root)->entry = entry;
  966. else {
  967. while( tmp != NULL && ((json_elem_t *)tmp)->next != NULL )
  968. tmp = ((json_elem_t *)tmp)->next;
  969. ((json_elem_t *)tmp)->next = entry;
  970. }
  971. json_set_code( jobj, JSON_INS_ELEM_ARR );
  972. break;
  973. case JSON_VAL:
  974. switch( json_get_type( entry ) ) {
  975. case JSON_OBJ:
  976. case JSON_ARR:
  977. ((json_val_t *)root)->value = entry;
  978. json_set_code( jobj, JSON_INS_VAL_VAL );
  979. break;
  980. default:
  981. json_set_code( jobj, JSON_INVALID_VAL_ENT );
  982. return NULL;
  983. }
  984. break;
  985. default:
  986. json_set_code( jobj, JSON_INVALID_ROOT_ENT );
  987. return NULL;
  988. }
  989. return entry;
  990. }
  991. /** Recursice functions to print the tree **/
  992. static void _json_out( json_obj_t *jobj, int height ) {
  993. if ( jobj == NULL )
  994. return;
  995. _print_mem( jobj, jobj->members, height );
  996. }
  997. static void _print_( json_obj_t *jobj, ... ) {
  998. va_list vargs;
  999. char *format;
  1000. va_start( vargs, jobj );
  1001. if ( jobj->jfile == NULL || (jobj->ptype & JSON_PRINT) == JSON_PRINT ) {
  1002. format = va_arg( vargs, char * );
  1003. vprintf( format, vargs );
  1004. }
  1005. va_end( vargs );
  1006. }
  1007. static void _print_mem( json_obj_t *jobj, json_mem_t *jmem, int height ) {
  1008. char *tabs;
  1009. if ( jmem == NULL )
  1010. return;
  1011. tabs = _print_tabs( jobj, height );
  1012. _print_( jobj, "%s{%s", tabs, _print_set_newline( jobj ) );
  1013. if ( json_is_type( jmem->entry, JSON_PAIR ) )
  1014. _print_pair( jobj, jmem->entry, height + 1 );
  1015. else
  1016. _print_mem( jobj, jmem->entry, height + 1 );
  1017. _print_( jobj, "%s}%s%s", tabs, ( jmem->next != NULL ? "," : "" ), _print_set_newline( jobj ) );
  1018. _print_tabs_release( tabs );
  1019. _print_mem( jobj, jmem->next, height );
  1020. }
  1021. static void _print_pair( json_obj_t *jobj, json_pair_t *jpair, int height ) {
  1022. char *tabs;
  1023. if ( jpair == NULL )
  1024. return;
  1025. tabs = _print_tabs( jobj, height );
  1026. _print_( jobj, "%s\"%s\":", tabs, jpair->str );
  1027. _print_value( jobj, jpair->value, height + 1 );
  1028. _print_( jobj, "%s%s", ( jpair->next != NULL ? "," : "" ), _print_set_newline( jobj ) );
  1029. _print_tabs_release( tabs );
  1030. if ( jpair->next != NULL ) {
  1031. if ( json_is_type( jpair->next, JSON_PAIR ) )
  1032. _print_pair( jobj, jpair->next, height );
  1033. else if ( json_is_type( jpair->next, JSON_MEM ) )
  1034. _print_mem( jobj, jpair->next, height );
  1035. }
  1036. }
  1037. static void _print_arr( json_obj_t *jobj, json_arr_t *jarr, int height ) {
  1038. char *tabs;
  1039. if ( jarr == NULL )
  1040. return;
  1041. tabs = _print_tabs( jobj, height - 1 );
  1042. _print_( jobj, "[%s", _print_set_newline( jobj ) );
  1043. _print_elem( jobj, jarr->entry, height );
  1044. _print_( jobj, "%s]", tabs );
  1045. _print_tabs_release( tabs );
  1046. }
  1047. static void _print_elem( json_obj_t *jobj, json_elem_t *jelem, int height ) {
  1048. char *tabs;
  1049. if ( jelem == NULL )
  1050. return;
  1051. tabs = _print_tabs( jobj, height );
  1052. _print_( jobj, "%s", tabs );
  1053. _print_value( jobj, jelem->entry, height );
  1054. _print_( jobj, "%s%s", ( jelem->next != NULL ? "," : "" ), _print_set_newline( jobj ) );
  1055. _print_elem( jobj, jelem->next, height );
  1056. _print_tabs_release( tabs );
  1057. }
  1058. static void _print_value( json_obj_t *jobj, json_val_t *jval, int height ) {
  1059. char *tabs;
  1060. if ( jval == NULL ) {
  1061. _print_( jobj, "\"\"" );
  1062. return;
  1063. }
  1064. tabs = _print_tabs( jobj, height + 1 );
  1065. switch( jval->sub_type ) {
  1066. case JSON_OBJ:
  1067. _json_out( jval->value, height );
  1068. break;
  1069. case JSON_ARR:
  1070. _print_arr( jobj, jval->value, height );
  1071. break;
  1072. case JSON_CHAR:
  1073. case JSON_BOOL:
  1074. case JSON_NULL:
  1075. _print_( jobj, "\"%s\"", (char *)jval->value );
  1076. break;
  1077. case JSON_INT:
  1078. _print_( jobj, "%d", *(int *)jval->value );
  1079. break;
  1080. case JSON_FLOAT:
  1081. _print_( jobj, "%f", *(float *)jval->value );
  1082. break;
  1083. default:
  1084. _print_( jobj, "\"\"");
  1085. break;
  1086. }
  1087. _print_tabs_release( tabs );
  1088. }
  1089. static char *_print_set_newline( json_obj_t *jobj ) {
  1090. return (jobj->ptype & JSON_PPRINT) == JSON_PPRINT ? "\n": "";
  1091. }
  1092. static void _print_tabs_release( char *tabs ) {
  1093. if ( tabs == NULL )
  1094. return;
  1095. free( tabs );
  1096. }
  1097. static char *_print_tabs( json_obj_t *jobj, int height ) {
  1098. int i;
  1099. char *tabs;
  1100. if ( (jobj->ptype & JSON_PPRINT) == JSON_PPRINT ) {
  1101. tabs = ( char *) malloc( sizeof( char * ) );
  1102. tabs[0] = 0;
  1103. return tabs;
  1104. }
  1105. tabs = ( char *) malloc( sizeof( char * ) * height );
  1106. for ( i = 0; i < height; i++ )
  1107. tabs[ i ] = '\t';
  1108. tabs[i] = 0;
  1109. return tabs;
  1110. }
  1111. /** Silence in comments is like nothing was here */
  1112. /***
  1113. * THIS IS FOR DEBUGGING OF THE JSON-IMPLEMENTATION;
  1114. * To run this make project as:
  1115. * $ make json-test
  1116. * and run by
  1117. * $ ./json-test
  1118. **/
  1119. #ifdef _DEBUG_JSON
  1120. int main(int argc, char const *argv[]) {
  1121. int i = 18848;
  1122. float f = 154.4848;
  1123. bool b = true;
  1124. json_obj_t *jobj = json_create( "", JSON_PRINT | JSON_PPRINT );
  1125. if ( json_has_err( jobj ) )
  1126. printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
  1127. json_mem_t *jmem = json_create_mem( jobj );
  1128. if ( json_has_err( jobj ) )
  1129. printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
  1130. json_pair_t *jpair = json_create_pair( jobj, jmem, "Test" );
  1131. if ( json_has_err( jobj ) )
  1132. printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
  1133. json_pair_t *jpair2 = json_create_pair( jobj, jmem, "Test" );
  1134. if ( json_has_err( jobj ) )
  1135. printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
  1136. json_pair_t *jpair3 = json_create_pair( jobj, jmem, "Test" );
  1137. if ( json_has_err( jobj ) )
  1138. printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
  1139. json_val_t *jval = json_insert_value( jobj, jpair, JSON_CHAR, "Litt text" );
  1140. jval = json_insert_value( jobj, jpair2, JSON_CHAR, "Litt mer test" );
  1141. jval = json_insert_value( jobj, jpair3, JSON_CHAR, "Litt test" );
  1142. if ( json_has_err( jobj ) )
  1143. printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
  1144. json_mem_t *jmem2 = json_create_mem( jobj );
  1145. if ( json_has_err( jobj ) )
  1146. printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
  1147. jpair2 = json_create_pair( jobj, jmem2, "array" );
  1148. if ( json_has_err( jobj ) )
  1149. printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
  1150. json_val_t *jval2 = json_insert_value( jobj, jpair2, JSON_ARR, NULL );
  1151. if ( json_has_err( jobj ) )
  1152. printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
  1153. json_arr_t *jarr = json_create_arr( jobj, jval2 );
  1154. if ( json_has_err( jobj ) )
  1155. printf("ERR: %s\n\n", json_last_errmsg( jobj ) );
  1156. json_elem_t *elem = json_create_elem( jobj, jarr );
  1157. json_val_t *val = json_insert_value( jobj, elem, JSON_INT, &i );
  1158. elem = json_create_elem( jobj, jarr );
  1159. val = json_insert_value( jobj, elem, JSON_BOOL, &b );
  1160. elem = json_create_elem( jobj, jarr );
  1161. val = json_insert_value( jobj, elem, JSON_CHAR, "FUCK YOU" );
  1162. elem = json_create_elem( jobj, jarr );
  1163. val = json_insert_value( jobj, elem, JSON_FLOAT, &f );
  1164. elem = json_create_elem( jobj, jarr );
  1165. val = json_insert_value( jobj, elem, JSON_NULL, NULL );
  1166. json_out( jobj );
  1167. json_destroy( jobj );
  1168. return EXIT_SUCCESS;
  1169. }
  1170. #endif