#include #include #include #include "base64.h" #include "plist.h" static void plist_append(plist_t *p, const char *str) { size_t len = strlen(str); if (p->size + len < p->capacity) { memcpy(p->buffer + p->size, str, len); p->size += len; p->buffer[p->size] = '\0'; } } void plist_init(plist_t *p, char *buffer, size_t capacity) { p->buffer = buffer; p->size = 0; p->capacity = capacity; p->buffer[0] = '\0'; } void plist_begin(plist_t *p) { plist_append(p, "\n"); plist_append(p, "\n"); plist_append(p, "\n"); } void plist_dict_begin(plist_t *p) { plist_append(p, "\n"); } void plist_dict_string(plist_t *p, const char *key, const char *value) { size_t remaining = p->capacity - p->size; int len = snprintf(p->buffer + p->size, remaining, "%s\n%s\n", key, value); if (len > 0 && (size_t)len < remaining) { p->size += (size_t)len; } } void plist_dict_int(plist_t *p, const char *key, int64_t value) { size_t remaining = p->capacity - p->size; int len = snprintf(p->buffer + p->size, remaining, "%s\n%" PRId64 "\n", key, value); if (len > 0 && (size_t)len < remaining) { p->size += (size_t)len; } } void plist_dict_uint(plist_t *p, const char *key, uint64_t value) { size_t remaining = p->capacity - p->size; int len = snprintf(p->buffer + p->size, remaining, "%s\n%" PRIu64 "\n", key, value); if (len > 0 && (size_t)len < remaining) { p->size += (size_t)len; } } void plist_dict_bool(plist_t *p, const char *key, bool value) { size_t remaining = p->capacity - p->size; int len = snprintf(p->buffer + p->size, remaining, "%s\n<%s/>\n", key, value ? "true" : "false"); if (len > 0 && (size_t)len < remaining) { p->size += (size_t)len; } } void plist_dict_data(plist_t *p, const char *key, const uint8_t *data, size_t len) { size_t b64_len = base64_encoded_length(len); size_t remaining = p->capacity - p->size; if (remaining < strlen(key) + b64_len + 50) { return; } int written = snprintf(p->buffer + p->size, remaining, "%s\n", key); if (written > 0) { p->size += (size_t)written; } int encoded = base64_encode(data, len, p->buffer + p->size, p->capacity - p->size); if (encoded < 0) { return; } p->size += (size_t)encoded; p->buffer[p->size] = '\0'; plist_append(p, "\n"); } void plist_dict_data_hex(plist_t *p, const char *key, const uint8_t *data, size_t len) { plist_dict_data(p, key, data, len); } void plist_dict_end(plist_t *p) { plist_append(p, "\n"); } void plist_dict_array_begin(plist_t *p, const char *key) { size_t remaining = p->capacity - p->size; int len = snprintf(p->buffer + p->size, remaining, "%s\n\n", key); if (len > 0 && (size_t)len < remaining) { p->size += (size_t)len; } } void plist_array_begin(plist_t *p) { plist_append(p, "\n"); } void plist_array_end(plist_t *p) { plist_append(p, "\n"); } void plist_array_int(plist_t *p, int64_t value) { size_t remaining = p->capacity - p->size; int len = snprintf(p->buffer + p->size, remaining, "%" PRId64 "\n", value); if (len > 0 && (size_t)len < remaining) { p->size += (size_t)len; } } size_t plist_end(plist_t *p) { plist_append(p, "\n"); return p->size; }