pattern.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include "pbc.h"
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <stdint.h>
  5. #include <stddef.h>
  6. #include "readfile.h"
  7. static void
  8. dump(uint8_t *buffer, int sz) {
  9. int i , j;
  10. for (i=0;i<sz;i++) {
  11. printf("%02X ",buffer[i]);
  12. if (i % 16 == 15) {
  13. for (j = 0 ;j <16 ;j++) {
  14. char c = buffer[i/16 * 16+j];
  15. if (c>=32 && c<127) {
  16. printf("%c",c);
  17. } else {
  18. printf(".");
  19. }
  20. }
  21. printf("\n");
  22. }
  23. }
  24. printf("\n");
  25. }
  26. static struct pbc_pattern *pat;
  27. static struct pbc_pattern *pat_phone;
  28. struct person_phone {
  29. struct pbc_slice number;
  30. int32_t type;
  31. };
  32. struct person {
  33. struct pbc_slice name;
  34. int32_t id;
  35. struct pbc_slice email;
  36. pbc_array phone;
  37. pbc_array test;
  38. };
  39. static void
  40. test_pattern_unpack(struct pbc_env *env, struct pbc_slice * slice) {
  41. struct person p;
  42. int r = pbc_pattern_unpack(pat, slice, &p);
  43. if (r>=0) {
  44. printf("name = %s\n",(const char *)p.name.buffer);
  45. printf("id = %d\n",p.id);
  46. printf("email = %s\n",(const char *)p.email.buffer);
  47. int n = pbc_array_size(p.phone);
  48. int i;
  49. for (i=0;i<n;i++) {
  50. struct pbc_slice * bytes = pbc_array_slice(p.phone, i);
  51. struct person_phone pp;
  52. pbc_pattern_unpack(pat_phone , bytes , &pp);
  53. printf("\tnumber = %s\n" , (const char*)pp.number.buffer);
  54. printf("\ttype = %d\n" , pp.type);
  55. }
  56. n = pbc_array_size(p.test);
  57. for (i=0;i<n;i++) {
  58. printf("test[%d] = %d\n",i, pbc_array_integer(p.test, i , NULL));
  59. }
  60. pbc_pattern_close_arrays(pat,&p);
  61. }
  62. }
  63. static int
  64. test_pattern_pack(struct pbc_env *env , struct pbc_slice *slice) {
  65. struct person p;
  66. /*
  67. If you don't care about default values (you will set all values by yourself) ,
  68. you can also use memset(&p, 0 , sizeof(p)) instead of pbc_pattern_set_default.
  69. */
  70. pbc_pattern_set_default(pat, &p);
  71. p.name.buffer = (void*)"Alice";
  72. p.name.len = -1; // encode '\0'
  73. p.id = 1234;
  74. p.email.buffer = (void*)"alice@unknown";
  75. p.email.len = -1;
  76. struct person_phone phone;
  77. phone.number.buffer = (void *)"1234567";
  78. phone.number.len = -1;
  79. phone.type = 1;
  80. char temp[128];
  81. struct pbc_slice phone_slice = { temp, sizeof(temp) };
  82. int unused = pbc_pattern_pack(pat_phone, &phone , &phone_slice);
  83. if (unused < 0) {
  84. slice->len = 0;
  85. return slice->len;
  86. }
  87. pbc_array_push_slice(p.phone, &phone_slice);
  88. pbc_pattern_set_default(pat_phone, &phone);
  89. phone.number.buffer = (void *)"87654321";
  90. phone.number.len = -1;
  91. char temp2[128];
  92. struct pbc_slice phone_slice2 = { temp2, sizeof(temp2) };
  93. unused = pbc_pattern_pack(pat_phone, &phone , &phone_slice2);
  94. if (unused < 0) {
  95. slice->len = 0;
  96. return slice->len;
  97. }
  98. pbc_array_push_slice(p.phone, &phone_slice2);
  99. int i;
  100. for (i=0;i<3;i++) {
  101. pbc_array_push_integer(p.test, -i*4,0);
  102. }
  103. int r = pbc_pattern_pack(pat, &p, slice);
  104. pbc_pattern_close_arrays(pat,&p);
  105. printf("pack into %d bytes\n", slice->len);
  106. return r;
  107. }
  108. int
  109. main()
  110. {
  111. struct pbc_slice slice;
  112. read_file("addressbook.pb", &slice);
  113. if (slice.buffer == NULL)
  114. return 1;
  115. struct pbc_env * env = pbc_new();
  116. pbc_register(env, &slice);
  117. free(slice.buffer);
  118. pat = pbc_pattern_new(env, "tutorial.Person" ,
  119. "name %s id %d email %s phone %a test %a",
  120. offsetof(struct person, name) ,
  121. offsetof(struct person, id) ,
  122. offsetof(struct person, email) ,
  123. offsetof(struct person, phone) ,
  124. offsetof(struct person, test));
  125. pat_phone = pbc_pattern_new(env, "tutorial.Person.PhoneNumber",
  126. "number %s type %d",
  127. offsetof(struct person_phone, number),
  128. offsetof(struct person_phone, type));
  129. char buffer[4096];
  130. struct pbc_slice message = { buffer, sizeof(buffer) };
  131. test_pattern_pack(env, &message);
  132. dump(message.buffer, message.len);
  133. test_pattern_unpack(env, &message);
  134. pbc_pattern_delete(pat);
  135. pbc_pattern_delete(pat_phone);
  136. pbc_delete(env);
  137. return 0;
  138. }