#ifndef H_UTILITIES_INCLUDED #define H_UTILITIES_INCLUDED #ifdef HAVE_CONFIG_H #include #endif /* HAVE_CONFIG_H */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* Return a base64 encoding of some raw data. */ static SCM wrap_bytevector (size_t length, uint8_t * data); /* Decode a base64 of binary data. */ static uint8_t *get_as_bytevector (SCM data, size_t *size, int throw_if_fail); static inline SCM wrap_bytevector (size_t length, uint8_t * data) { char *head; char tail[BASE64_ENCODE_FINAL_LENGTH]; size_t head_size, tail_size; char *full; struct base64_encode_ctx encoder; SCM ret; base64url_encode_init (&encoder); scm_dynwind_begin (0); head = scm_malloc (BASE64_ENCODE_LENGTH (length)); scm_dynwind_free (head); head_size = base64_encode_update (&encoder, head, length, data); tail_size = base64_encode_final (&encoder, tail); while (tail_size != 0 && tail[tail_size - 1] == '=') { tail_size--; } full = scm_malloc (head_size + tail_size); memcpy (full, head, head_size); memcpy (full + head_size, tail, tail_size); ret = scm_from_utf8_stringn (full, head_size + tail_size); scm_dynwind_end (); return ret; } static inline uint8_t * get_as_bytevector (SCM data, size_t *size, int throw_if_fail) { uint8_t *ret = NULL; size_t data_length; char *data_str = NULL; struct base64_decode_ctx decoder; int ok = 1; if (!scm_is_bytevector (data) && !throw_if_fail) { return NULL; } base64url_decode_init (&decoder); scm_dynwind_begin (0); data_str = scm_to_utf8_stringn (data, &data_length); scm_dynwind_free (data_str); ret = scm_malloc (BASE64_DECODE_LENGTH (data_length)); /* Not protected! Nothing will throw until scm_dynwind_end. */ ok = base64_decode_update (&decoder, size, ret, data_length, data_str); scm_dynwind_end (); if (!ok) { ret = NULL; if (throw_if_fail) { SCM base64_decoding_error = scm_from_utf8_symbol ("base64-decoding-error"); scm_throw (base64_decoding_error, scm_list_1 (data)); } } return ret; } #endif /* not H_UTILITIES_INCLUDED */