Skip to content

Commit

Permalink
externalterm: make serialize to buffer functions accessible
Browse files Browse the repository at this point in the history
Make functions for writing a term using external term format to a buffer
accessible, so there is no need to use a binary.
These functions can be useful when using external term format in NIFs or
port drivers.

Before this change `externalterm_to_binary` was the only available
function.

Signed-off-by: Davide Bettio <[email protected]>
  • Loading branch information
bettio committed Oct 10, 2024
1 parent ff34010 commit 2368e39
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ also non string parameters (e.g. `Enum.join([1, 2], ",")`
[#1100](https://github.com/atomvm/AtomVM/issues/1100)
- Support for mounting/unmounting storage on ESP32 (such as SD or internal flash) using
`esp:mount/4` and `esp:umount/1`
- Make external term serialize functions available without using `externalterm_to_binary` so terms
can be written directly to a buffer.

### Changed

Expand Down
16 changes: 15 additions & 1 deletion src/libAtomVM/externalterm.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include "unicode.h"
#include "utils.h"

#define EXTERNAL_TERM_TAG 131
#define NEW_FLOAT_EXT 70
#define SMALL_INTEGER_EXT 97
#define INTEGER_EXT 98
Expand Down Expand Up @@ -947,3 +946,18 @@ static int calculate_heap_usage(const uint8_t *external_term_buf, size_t remaini
return INVALID_TERM_SIZE;
}
}

enum ExternalTermResult externalterm_compute_external_size_raw(
term t, size_t *size, GlobalContext *glb)
{
*size = compute_external_size(t, glb);

return EXTERNAL_TERM_OK;
}

enum ExternalTermResult externalterm_serialize_term_raw(uint8_t *buf, term t, GlobalContext *glb)
{
serialize_term(buf, t, glb);

return EXTERNAL_TERM_OK;
}
73 changes: 73 additions & 0 deletions src/libAtomVM/externalterm.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

#include "term.h"

#define EXTERNAL_TERM_TAG 131

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -94,6 +96,77 @@ enum ExternalTermResult externalterm_from_binary(Context *ctx, term *dst, term b
*/
term externalterm_to_binary(Context *ctx, term t);

/**
* @brief Computes the size required for a external term (tag excluded)
*
* @details This function should be called in order to calculate the required buffer size to store
* a serialized term in external term format. This function doesn't prepend the external term 1 byte
* tag.
*
* @param t the term for which size is calculated
* @param size the required buffer size (tag excluded)
* @param glb the global context
* @returns EXTERNAL_TERM_OK in case of success
*/
enum ExternalTermResult externalterm_compute_external_size_raw(
term t, size_t *size, GlobalContext *glb);

/**
* @brief Serialize a term (tag excluded)
*
* @details This function serializes in external term format given term, and writes it to the given
* buffer. This function doesn't prepend the external term 1 byte tag.
*
* @param buf the buffer where the external term is written
* @param t the term that will be serialized
* @param glb the global context
* @returns EXTERNAL_TERM_OK in case of success
*/
enum ExternalTermResult externalterm_serialize_term_raw(uint8_t *buf, term t, GlobalContext *glb);

/**
* @brief Computes the size required for a external term
*
* @details This function should be called in order to calculate the required buffer size to store
* a serialized term in external term format.
*
* @param t the term for which size is calculated
* @param size the required buffer size (tag excluded)
* @param glb the global context
* @returns EXTERNAL_TERM_OK in case of success
*/
static inline enum ExternalTermResult externalterm_compute_external_size(
term t, size_t *size, GlobalContext *glb)
{
size_t raw_size;
enum ExternalTermResult result = externalterm_compute_external_size_raw(t, &raw_size, glb);
if (LIKELY(result == EXTERNAL_TERM_OK)) {
*size = raw_size + 1;
}
return result;
}

/**
* @brief Serialize a term
*
* @details This function serializes in external term format given term, and writes it to the given
* buffer.
*
* @param buf the buffer where the external term is written
* @param t the term that will be serialized
* @param glb the global context
* @returns EXTERNAL_TERM_OK in case of success
*/
static inline enum ExternalTermResult externalterm_serialize_term(
uint8_t *buf, term t, GlobalContext *glb)
{
enum ExternalTermResult result = externalterm_serialize_term(buf + 1, t, glb);
if (LIKELY(result == EXTERNAL_TERM_OK)) {
buf[0] = EXTERNAL_TERM_TAG;
}
return result;
}

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit 2368e39

Please sign in to comment.