plist_xml.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include <inttypes.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "base64.h"
  5. #include "plist.h"
  6. static void plist_append(plist_t *p, const char *str) {
  7. size_t len = strlen(str);
  8. if (p->size + len < p->capacity) {
  9. memcpy(p->buffer + p->size, str, len);
  10. p->size += len;
  11. p->buffer[p->size] = '\0';
  12. }
  13. }
  14. void plist_init(plist_t *p, char *buffer, size_t capacity) {
  15. p->buffer = buffer;
  16. p->size = 0;
  17. p->capacity = capacity;
  18. p->buffer[0] = '\0';
  19. }
  20. void plist_begin(plist_t *p) {
  21. plist_append(p, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
  22. plist_append(p, "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
  23. "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n");
  24. plist_append(p, "<plist version=\"1.0\">\n");
  25. }
  26. void plist_dict_begin(plist_t *p) {
  27. plist_append(p, "<dict>\n");
  28. }
  29. void plist_dict_string(plist_t *p, const char *key, const char *value) {
  30. size_t remaining = p->capacity - p->size;
  31. int len = snprintf(p->buffer + p->size, remaining,
  32. "<key>%s</key>\n<string>%s</string>\n", key, value);
  33. if (len > 0 && (size_t)len < remaining) {
  34. p->size += (size_t)len;
  35. }
  36. }
  37. void plist_dict_int(plist_t *p, const char *key, int64_t value) {
  38. size_t remaining = p->capacity - p->size;
  39. int len =
  40. snprintf(p->buffer + p->size, remaining,
  41. "<key>%s</key>\n<integer>%" PRId64 "</integer>\n", key, value);
  42. if (len > 0 && (size_t)len < remaining) {
  43. p->size += (size_t)len;
  44. }
  45. }
  46. void plist_dict_uint(plist_t *p, const char *key, uint64_t value) {
  47. size_t remaining = p->capacity - p->size;
  48. int len =
  49. snprintf(p->buffer + p->size, remaining,
  50. "<key>%s</key>\n<integer>%" PRIu64 "</integer>\n", key, value);
  51. if (len > 0 && (size_t)len < remaining) {
  52. p->size += (size_t)len;
  53. }
  54. }
  55. void plist_dict_bool(plist_t *p, const char *key, bool value) {
  56. size_t remaining = p->capacity - p->size;
  57. int len = snprintf(p->buffer + p->size, remaining, "<key>%s</key>\n<%s/>\n",
  58. key, value ? "true" : "false");
  59. if (len > 0 && (size_t)len < remaining) {
  60. p->size += (size_t)len;
  61. }
  62. }
  63. void plist_dict_data(plist_t *p, const char *key, const uint8_t *data,
  64. size_t len) {
  65. size_t b64_len = base64_encoded_length(len);
  66. size_t remaining = p->capacity - p->size;
  67. if (remaining < strlen(key) + b64_len + 50) {
  68. return;
  69. }
  70. int written =
  71. snprintf(p->buffer + p->size, remaining, "<key>%s</key>\n<data>", key);
  72. if (written > 0) {
  73. p->size += (size_t)written;
  74. }
  75. int encoded =
  76. base64_encode(data, len, p->buffer + p->size, p->capacity - p->size);
  77. if (encoded < 0) {
  78. return;
  79. }
  80. p->size += (size_t)encoded;
  81. p->buffer[p->size] = '\0';
  82. plist_append(p, "</data>\n");
  83. }
  84. void plist_dict_data_hex(plist_t *p, const char *key, const uint8_t *data,
  85. size_t len) {
  86. plist_dict_data(p, key, data, len);
  87. }
  88. void plist_dict_end(plist_t *p) {
  89. plist_append(p, "</dict>\n");
  90. }
  91. void plist_dict_array_begin(plist_t *p, const char *key) {
  92. size_t remaining = p->capacity - p->size;
  93. int len =
  94. snprintf(p->buffer + p->size, remaining, "<key>%s</key>\n<array>\n", key);
  95. if (len > 0 && (size_t)len < remaining) {
  96. p->size += (size_t)len;
  97. }
  98. }
  99. void plist_array_begin(plist_t *p) {
  100. plist_append(p, "<array>\n");
  101. }
  102. void plist_array_end(plist_t *p) {
  103. plist_append(p, "</array>\n");
  104. }
  105. void plist_array_int(plist_t *p, int64_t value) {
  106. size_t remaining = p->capacity - p->size;
  107. int len = snprintf(p->buffer + p->size, remaining,
  108. "<integer>%" PRId64 "</integer>\n", value);
  109. if (len > 0 && (size_t)len < remaining) {
  110. p->size += (size_t)len;
  111. }
  112. }
  113. size_t plist_end(plist_t *p) {
  114. plist_append(p, "</plist>\n");
  115. return p->size;
  116. }