2
0

yajltest.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #include "perftest.h"
  2. #if TEST_YAJL
  3. extern "C" {
  4. #include "yajl/yajl_gen.h"
  5. #include "yajl/yajl_parse.h"
  6. #include "yajl/yajl_tree.h"
  7. };
  8. class Yajl : public PerfTest {
  9. public:
  10. virtual void SetUp() {
  11. PerfTest::SetUp();
  12. root_ = yajl_tree_parse(json_, NULL, 0);
  13. ASSERT_TRUE(root_ != NULL);
  14. }
  15. virtual void TearDown() {
  16. PerfTest::TearDown();
  17. yajl_tree_free(root_);
  18. }
  19. protected:
  20. yajl_val root_;
  21. };
  22. static int null_null(void *) { return 1; }
  23. static int null_boolean(void *, int) { return 1; }
  24. static int null_integer(void *, long long) { return 1; }
  25. static int null_double(void *, double) { return 1; }
  26. static int null_string(void *, const unsigned char*, size_t) { return 1; }
  27. static int null_start_map(void *) { return 1; }
  28. static int null_map_key(void *, const unsigned char*, size_t) { return 1; }
  29. static int null_end_map(void *) { return 1; }
  30. static int null_start_array(void*) { return 1; }
  31. static int null_end_array(void *) { return 1; }
  32. static yajl_callbacks nullcallbacks = {
  33. null_null,
  34. null_boolean,
  35. null_integer,
  36. null_double,
  37. NULL, // yajl_number(). Here we want to test full-parsing performance.
  38. null_string,
  39. null_start_map,
  40. null_map_key,
  41. null_end_map,
  42. null_start_array,
  43. null_end_array
  44. };
  45. TEST_F(Yajl, yajl_parse_nullcallbacks) {
  46. for (int i = 0; i < kTrialCount; i++) {
  47. yajl_handle hand = yajl_alloc(&nullcallbacks, NULL, NULL);
  48. yajl_status stat = yajl_parse(hand, (unsigned char*)json_, length_);
  49. //ASSERT_EQ(yajl_status_ok, stat);
  50. if (stat != yajl_status_ok) {
  51. unsigned char * str = yajl_get_error(hand, 1, (unsigned char*)json_, length_);
  52. fprintf(stderr, "%s", (const char *) str);
  53. }
  54. stat = yajl_complete_parse(hand);
  55. ASSERT_EQ(yajl_status_ok, stat);
  56. yajl_free(hand);
  57. }
  58. }
  59. TEST_F(Yajl, yajl_tree_parse) {
  60. for (int i = 0; i < kTrialCount; i++) {
  61. yajl_val root = yajl_tree_parse(json_, NULL, 0);
  62. ASSERT_TRUE(root != NULL);
  63. yajl_tree_free(root);
  64. }
  65. }
  66. yajl_gen_status GenVal(yajl_gen g, yajl_val v) {
  67. yajl_gen_status status;
  68. switch (v->type) {
  69. case yajl_t_string: return yajl_gen_string(g, (unsigned char*)v->u.string, strlen(v->u.string));
  70. case yajl_t_number:
  71. {
  72. char buffer[100];
  73. char *num = buffer;
  74. size_t len;
  75. //if (YAJL_IS_INTEGER(v)) // buggy
  76. if (v->u.number.flags & YAJL_NUMBER_INT_VALID)
  77. #if _MSC_VER
  78. len = sprintf(num, "%I64d", YAJL_GET_INTEGER(v));
  79. #else
  80. len = sprintf(num, "%lld", YAJL_GET_INTEGER(v));
  81. #endif
  82. //else if (YAJL_IS_DOUBLE(v)) // buggy
  83. else if (v->u.number.flags & YAJL_NUMBER_DOUBLE_VALID)
  84. len = sprintf(num, "%g", YAJL_GET_DOUBLE(v));
  85. else {
  86. num = YAJL_GET_NUMBER(v);
  87. len = strlen(buffer);
  88. }
  89. return yajl_gen_number(g, num, len);
  90. }
  91. case yajl_t_object:
  92. status = yajl_gen_map_open(g);
  93. if (status != yajl_gen_status_ok)
  94. return status;
  95. for (size_t i = 0; i < v->u.object.len; i++) {
  96. status = yajl_gen_string(g, (unsigned char *)v->u.object.keys[i], strlen(v->u.object.keys[i]));
  97. if (status != yajl_gen_status_ok)
  98. return status;
  99. status = GenVal(g, v->u.object.values[i]);
  100. if (status != yajl_gen_status_ok)
  101. return status;
  102. }
  103. return yajl_gen_map_close(g);
  104. case yajl_t_array:
  105. status = yajl_gen_array_open(g);
  106. if (status != yajl_gen_status_ok)
  107. return status;
  108. for (size_t i = 0; i < v->u.array.len; i++) {
  109. status = GenVal(g, v->u.array.values[i]);
  110. if (status != yajl_gen_status_ok)
  111. return status;
  112. }
  113. return yajl_gen_array_close(g);
  114. case yajl_t_true: return yajl_gen_bool(g, 1);
  115. case yajl_t_false: return yajl_gen_bool(g, 0);
  116. case yajl_t_null: return yajl_gen_null(g);
  117. }
  118. return yajl_gen_in_error_state;
  119. }
  120. TEST_F(Yajl, yajl_gen) {
  121. for (int i = 0; i < kTrialCount; i++) {
  122. yajl_gen g = yajl_gen_alloc(NULL);
  123. yajl_gen_status status = GenVal(g, root_);
  124. if (status != yajl_gen_status_ok) {
  125. std::cout << "gen error: " << status << std::endl;
  126. FAIL();
  127. }
  128. const unsigned char * buf;
  129. size_t len;
  130. status = yajl_gen_get_buf(g, &buf, &len);
  131. ASSERT_EQ(yajl_gen_status_ok, status);
  132. //if (i == 0)
  133. // std::cout << len << std::endl;
  134. yajl_gen_free(g);
  135. }
  136. }
  137. TEST_F(Yajl, yajl_gen_beautify) {
  138. for (int i = 0; i < kTrialCount; i++) {
  139. yajl_gen g = yajl_gen_alloc(NULL);
  140. yajl_gen_config(g, yajl_gen_beautify, 1);
  141. yajl_gen_config(g, yajl_gen_indent_string, " ");
  142. yajl_gen_status status = GenVal(g, root_);
  143. if (status != yajl_gen_status_ok) {
  144. std::cout << "gen error: " << status << std::endl;
  145. FAIL();
  146. }
  147. const unsigned char * buf;
  148. size_t len;
  149. status = yajl_gen_get_buf(g, &buf, &len);
  150. ASSERT_EQ(yajl_gen_status_ok, status);
  151. //if (i == 0)
  152. // std::cout << len << std::endl;
  153. yajl_gen_free(g);
  154. }
  155. }
  156. TEST_F(Yajl, Whitespace) {
  157. for (int i = 0; i < kTrialCount; i++) {
  158. yajl_val root = yajl_tree_parse(whitespace_, NULL, 0);
  159. ASSERT_TRUE(root != NULL);
  160. yajl_tree_free(root);
  161. }
  162. }
  163. #endif // TEST_YAJL