File notation_wptt.c
File List > note-wptt > src > notation_wptt.c
Go to the documentation of this file
#include "notation_wptt.h"
#include "stdio.h"
#include "stdlib.h"
#include "stdbool.h"
/******************************************************************************/
/************************** Private Typedef ***********************************/
/******************************************************************************/
typedef uint8_t (*char_handler_funptr_t)(char **str);
typedef struct note_wptt_decode_char_dic_t {
char * char_class;
char_handler_funptr_t funptr;
} note_wptt_decode_char_dic_t;
/******************************************************************************/
/************************** Defines *******************************************/
/******************************************************************************/
#define NOTE_WPTT_V4_LABEL_I_STR ('i')
#define NOTE_WPTT_V4_LABEL_X_STR ('x')
#define NOTE_WPTT_V4_LABEL_Y_STR ('y')
#define NOTE_WPTT_V4_LABEL_Z_STR ('z')
#define NOTE_WPTT_STACK_SIZE (UTIL_TANG_DEFS_MAX_CROSSINGNUM)
#define NOTE_WPTT_DECODE_DICT_SIZE (6u)
#define NOTE_WPTT_INT_BASE (10u)
/******************************************************************************/
/************************** Private Function Declarations *********************/
/******************************************************************************/
/************************** Decode path Function Declarations *****************/
STATIC_INLINE_UINT8 note_wptt_decode_push_node();
STATIC_INLINE note_wptt_V4_label_e note_wptt_decode_get_v4_label(char label);
STATIC_INLINE bool note_wptt_decode_check_charset(const char *valid_chars,
const char str);
STATIC_INLINE_UINT8 note_wptt_decode_add_child();
STATIC_INLINE_UINT8 note_wptt_decode_space_handler(char **str);
STATIC_INLINE_UINT8 note_wptt_decode_opn_p_handler(char **str);
STATIC_INLINE_UINT8 note_wptt_decode_opn_a_handler(char **str);
STATIC_INLINE_UINT8 note_wptt_decode_opn_b_handler(char **str);
STATIC_INLINE_UINT8 note_wptt_decode_cls_handler(char **str);
STATIC_INLINE_UINT8 note_wptt_decode_weight_handler(char **str);
/************************** Encode path Function Declarations *****************/
STATIC_INLINE bool note_wptt_encode_stick_check(note_wptt_node_t *active_node_p);
STATIC_INLINE void note_wptt_encode_normalize_node_order(note_wptt_node_t *active_node_p);
STATIC_INLINE_UINT8 note_wptt_encode_insert_label(note_wptt_V4_label_e label,
char **str_p,
const char *buffer_end_p);
STATIC_INLINE_UINT8 note_wptt_encode_insert_char(char new_char,
char **str_p,
const char *buffer_end_p);
STATIC_INLINE_UINT8 note_wptt_encode_insert_int(int8_t new_int,
char **str_p,
const char *buffer_end_p);
STATIC_INLINE_UINT8 note_wptt_encode_insert_space(char **str_p,
const char *buffer_start_p,
const char *buffer_end_p);
STATIC_INLINE_UINT8 note_wptt_encode_insert_stick(note_wptt_node_t *active_node_p,
char **str_p,
const char *buffer_end_p);
STATIC_INLINE_UINT8 note_wptt_encode_complete_active_node(const note_wptt_node_t *active_node_p,
char **str_p,
size_t ordered_child_idx,
const char *buffer_start_p,
const char *buffer_end_p);
STATIC_INLINE_UINT8 note_wptt_encode_process_active_node(note_wptt_node_t *active_node_p,
char **str_p,
size_t ordered_child_idx,
const char *buffer_start_p,
const char *buffer_end_p);
/******************************************************************************/
/************************** Local Variables ***********************************/
/******************************************************************************/
static note_wptt_node_t *wptt_node_stack[NOTE_WPTT_STACK_SIZE] = { NULL };
static size_t wptt_stack_len = 0;
static note_wptt_node_buffer_t *decode_buffer = NULL;
uint8_t child_idx_stack[UTIL_TANG_DEFS_MAX_CROSSINGNUM];
/******************************************************************************/
/************************** Public Function Definitions ***********************/
/******************************************************************************/
/*
* Documentation in header
*/
uint8_t note_wptt_decode(char *str, note_wptt_t *wptt)
{
uint8_t retval = NOTE_DEFS_DECODE_SUCCESS;
/*Clear the buffer and stack*/
decode_buffer = NULL;
wptt_node_stack[0] = NULL;
wptt_stack_len = 0;
/*Initialize the character checking dictionary*/
const note_wptt_decode_char_dic_t charcheck_dict[] = {
{ "(", ¬e_wptt_decode_opn_p_handler },
{ "<", ¬e_wptt_decode_opn_a_handler },
{ "[", ¬e_wptt_decode_opn_b_handler },
{ ")>", ¬e_wptt_decode_cls_handler },
{ " ", ¬e_wptt_decode_space_handler },
{ "-0123456789", ¬e_wptt_decode_weight_handler }
};
/*Do basic error checking.*/
if (strlen(str) <= 2)
{
retval = NOTE_STATUS_BLDR(NOTE_DEFS_DECODE_FAIL, NOTE_WPTT_DECODE_EMPTY_STR);
}
else if (NULL == wptt)
{
retval = NOTE_STATUS_BLDR(NOTE_DEFS_DECODE_FAIL, NOTE_WPTT_DECODE_NULL_DEST);
}
else if ((NULL == wptt->node_buffer->buffer) || (0 == wptt->node_buffer->size))
{
retval = NOTE_STATUS_BLDR(NOTE_DEFS_DECODE_FAIL, NOTE_WPTT_DECODE_BUFFER_ERROR);
}
else
{
/*Main logic of the decode flow*/
/*Initialize buffer reference to node buffer*/
decode_buffer = wptt->node_buffer;
/*Initialize wptt root from buffer*/
wptt->root = &(decode_buffer->buffer[decode_buffer->idx]);
wptt->root->order = NOTE_WPTT_ORDER_FORWARD;
/*Check if the string has a V_4 label*/
wptt->label = note_wptt_decode_get_v4_label(str[0]);
if (NOTE_WPTT_V4_LABEL_NONE != wptt->label)
{
str++;
}
/*While string still has content and nothing has gone wrong*/
while (str[0] != '\0' && (NOTE_DEFS_DECODE_SUCCESS == retval))
{
size_t i;
/*For each item in the dictionary*/
for (i = 0u; i < NOTE_WPTT_DECODE_DICT_SIZE; i++)
{
if (true == note_wptt_decode_check_charset(charcheck_dict[i].char_class, str[0]))
{
retval |= charcheck_dict[i].funptr(&str);
break;
}
}
/*If current character is not in any set throw error*/
if (i == NOTE_WPTT_DECODE_DICT_SIZE)
{
retval |= NOTE_STATUS_BLDR(NOTE_DEFS_DECODE_FAIL, NOTE_WPTT_DECODE_BAD_STR);
}
}
}
return retval;
}
/*
* Documentation in header
*/
uint8_t note_wptt_encode(note_wptt_t wptt, char *str, size_t buffer_size)
{
uint8_t retval = NOTE_DEFS_ENCODE_SUCCESS;
const char *buffer_end_p;
const char *buffer_start_p;
wptt_node_stack[0] = wptt.root;
wptt_stack_len = 0x1u;
child_idx_stack[0u] = 0;
/*Do basic error checking.*/
if (0 == buffer_size)
{
retval = NOTE_STATUS_BLDR(NOTE_DEFS_ENCODE_FAIL, NOTE_WPTT_ENCODE_STR_BUF);
}
else if (NULL == str)
{
retval = NOTE_STATUS_BLDR(NOTE_DEFS_ENCODE_FAIL, NOTE_WPTT_ENCODE_STR_BUF);
}
else
{
buffer_end_p = str + (buffer_size - 1);
buffer_start_p = str;
retval |= note_wptt_encode_insert_label(wptt.label, &str, buffer_end_p);
/*While stack is not empty and string buffer has space*/
while ((0 < wptt_stack_len) && (str < buffer_end_p) &&
(NOTE_DEFS_ENCODE_SUCCESS == retval))
{
note_wptt_node_t *active_node_p = wptt_node_stack[wptt_stack_len - 1];
/*Do basic error checking.*/
if (NULL == active_node_p)
{
retval |= NOTE_STATUS_BLDR(NOTE_DEFS_ENCODE_FAIL, NOTE_WPTT_ENCODE_MALFORMED);
break;
}
else if (active_node_p->order == NOTE_WPTT_ORDER_UNINIT)
{
retval |= NOTE_STATUS_BLDR(NOTE_DEFS_ENCODE_FAIL, NOTE_WPTT_ENCODE_MALFORMED);
break;
}
else
{
note_wptt_encode_normalize_node_order(active_node_p);
size_t ordered_child_idx = child_idx_stack[wptt_stack_len - 1];
/*Check if active node is complete*/
if (active_node_p->number_of_children <
child_idx_stack[wptt_stack_len - 1])
{
retval |= note_wptt_encode_complete_active_node(active_node_p,
&str,
ordered_child_idx,
buffer_start_p,
buffer_end_p);
/*Pop stack*/
if (0 < wptt_stack_len)
{
wptt_stack_len--;
}
else
{
retval |= NOTE_STATUS_BLDR(
NOTE_DEFS_ENCODE_FAIL,
NOTE_WPTT_ENCODE_OVRUNDR_ERROR);
}
}
else
{
retval |= note_wptt_encode_process_active_node(active_node_p,
&str,
ordered_child_idx,
buffer_start_p,
buffer_end_p);
}
}
}
/*Finish string*/
if (str < buffer_end_p)
{
str[0] = '\0';
}
else
{
retval |= NOTE_STATUS_BLDR(NOTE_DEFS_ENCODE_FAIL, NOTE_WPTT_ENCODE_OVRUNDR_ERROR);
}
}
return retval;
}
/******************************************************************************/
/************************** Private Function Definitions **********************/
/************************** Decode Path Functions *****************************/
STATIC_INLINE note_wptt_V4_label_e note_wptt_decode_get_v4_label(char label)
{
note_wptt_V4_label_e retval = NOTE_WPTT_V4_LABEL_UNINIT;
/*Check if the string has a V_4 label*/
switch (label)
{
case NOTE_WPTT_V4_LABEL_I_STR:
{
retval = NOTE_WPTT_V4_LABEL_I;
break;
}
case NOTE_WPTT_V4_LABEL_X_STR:
{
retval = NOTE_WPTT_V4_LABEL_X;
break;
}
case NOTE_WPTT_V4_LABEL_Y_STR:
{
retval = NOTE_WPTT_V4_LABEL_Y;
break;
}
case NOTE_WPTT_V4_LABEL_Z_STR:
{
retval = NOTE_WPTT_V4_LABEL_Z;
break;
}
default:
{
retval = NOTE_WPTT_V4_LABEL_NONE;
}
}
return retval;
}
STATIC_INLINE bool note_wptt_decode_check_charset(const char *valid_chars,
const char str_char)
{
bool retval = false;
size_t i;
for (i = 0; i < strlen(valid_chars); i++)
{
if (str_char == valid_chars[i])
{
retval = true;
break;
}
}
return retval;
}
/* cppcheck-suppress constParameterPointer*/
STATIC_INLINE_UINT8 note_wptt_decode_space_handler(char **str)
{
/* cppcheck-suppress uselessAssignmentPtrArg*/
/* cppcheck-suppress unreadVariable*/
(*str)++;
return NOTE_DEFS_DECODE_SUCCESS;
}
STATIC_INLINE_UINT8 note_wptt_decode_opn_p_handler(char **str)
{
uint8_t retval = NOTE_DEFS_DECODE_SUCCESS;
retval |= note_wptt_decode_push_node();
retval |= note_wptt_decode_add_child();
(*str)++;
return retval;
}
STATIC_INLINE_UINT8 note_wptt_decode_opn_b_handler(char **str)
{
uint8_t retval = NOTE_DEFS_DECODE_SUCCESS;
int8_t weights[UTIL_TANG_DEFS_MAX_CROSSINGNUM] = { 0 };
size_t num_of_weights = 0;
(*str)++;
while ((']' != (*str)[0]) && ('\0' != (*str)[0]) &&
(NOTE_DEFS_DECODE_SUCCESS == retval))
{
if ((('0' <= (*str)[0]) && ((*str)[0] <= '9')) || ((*str)[0] == '-'))
{
weights[num_of_weights] = strtol(*str, str, NOTE_WPTT_INT_BASE);
num_of_weights++;
if (' ' == (*str)[0])
{
(*str)++;
}
}
else
{
retval |= NOTE_STATUS_BLDR(
NOTE_DEFS_DECODE_FAIL, NOTE_WPTT_DECODE_BAD_STR);
}
}
if ((']' == (*str)[0]) && (NOTE_DEFS_DECODE_SUCCESS == retval))
{
size_t i;
uint8_t pre_stick_stack_len = wptt_stack_len;
(*str)++;
for (i = 1; i < num_of_weights; i++)
{
retval |= note_wptt_decode_push_node();
retval |= note_wptt_decode_add_child();
if (0 == i % 2)
{
weights[num_of_weights - i] *= -1;
}
wptt_node_stack[wptt_stack_len - 1]->weights[1u] =
weights[num_of_weights - i];
}
if (0 == num_of_weights % 2)
{
weights[0] *= -1;
}
retval |= note_wptt_decode_push_node();
retval |= note_wptt_decode_add_child();
wptt_node_stack[wptt_stack_len - 1]->weights[0] = weights[0];
wptt_stack_len = pre_stick_stack_len;
}
else
{
retval |= NOTE_STATUS_BLDR(
NOTE_DEFS_DECODE_FAIL, NOTE_WPTT_DECODE_BAD_STR);
}
return retval;
}
STATIC_INLINE_UINT8 note_wptt_decode_opn_a_handler(char **str)
{
uint8_t retval = NOTE_DEFS_DECODE_SUCCESS;
retval |= note_wptt_decode_push_node();
retval |= note_wptt_decode_add_child();
(*str)++;
if (NOTE_DEFS_ENCODE_SUCCESS == retval)
{
/*Check that the char looks like the start of an integer.*/
if (!(('0' <= ((*str))[0]) && ((*str)[0] <= '9')) && ((*str)[0] != '-'))
{
retval |= NOTE_STATUS_BLDR(NOTE_DEFS_DECODE_FAIL, NOTE_WPTT_DECODE_BAD_STR);
}
else if (0 == wptt_stack_len)
{
retval |= NOTE_STATUS_BLDR(NOTE_DEFS_DECODE_FAIL, NOTE_WPTT_DECODE_OVRUNDR_ERROR);
}
else
{
note_wptt_node_t *active_node_p = wptt_node_stack[wptt_stack_len - 1];
active_node_p->number_of_rings = strtol(*str, str, NOTE_WPTT_INT_BASE);
}
}
return retval;
}
STATIC_INLINE_UINT8 note_wptt_decode_cls_handler(char **str)
{
uint8_t retval = NOTE_DEFS_DECODE_SUCCESS;
wptt_stack_len--;
(*str)++;
return retval;
}
STATIC_INLINE_UINT8 note_wptt_decode_weight_handler(char **str)
{
uint8_t retval = NOTE_DEFS_DECODE_SUCCESS;
note_wptt_node_t *active_node_p = wptt_node_stack[wptt_stack_len - 1];
active_node_p->weights[active_node_p->number_of_children] = strtol(
*str, str, NOTE_WPTT_INT_BASE);
if (' ' == (*str)[0])
{
retval |= NOTE_STATUS_BLDR(NOTE_DEFS_DECODE_FAIL,
NOTE_WPTT_DECODE_OVRUNDR_ERROR | NOTE_WPTT_DECODE_BAD_STR);
}
return retval;
}
STATIC_INLINE_UINT8 note_wptt_decode_push_node()
{
uint8_t retval = NOTE_STATUS_BLDR(NOTE_DEFS_ENCODE_FAIL, NOTE_WPTT_DECODE_OVRUNDR_ERROR);
/* Check that we don't have a buffer overflow*/
if ((decode_buffer->idx) + 1 < (decode_buffer->size) &&
(wptt_stack_len + 1 < NOTE_WPTT_STACK_SIZE))
{
size_t i;
note_wptt_node_t *new_node = &decode_buffer->buffer[decode_buffer->idx];
retval = NOTE_DEFS_DECODE_SUCCESS;
/*Clear out new node*/
for (i = 0; i < NOTE_WPTT_DECODE_MAX_WEIGHTS; i++)
{
new_node->weights[i] = 0;
}
for (i = 0; i < NOTE_WPTT_DECODE_MAX_CHILDREN; i++)
{
new_node->children[i] = NULL;
}
new_node->number_of_children = 0;
new_node->number_of_rings = 0;
new_node->order = NOTE_WPTT_ORDER_FORWARD;
/*Push new node to stack*/
wptt_node_stack[wptt_stack_len] = new_node;
/*Move buffer position to clean block*/
decode_buffer->idx++;
/* Move stack pointer up*/
wptt_stack_len++;
}
return retval;
}
STATIC_INLINE_UINT8 note_wptt_decode_add_child()
{
uint8_t retval = NOTE_STATUS_BLDR(
NOTE_DEFS_ENCODE_FAIL, NOTE_WPTT_DECODE_OVRUNDR_ERROR);
/*Check if there is open space on the stack*/
if ((0 < wptt_stack_len) && (wptt_stack_len < NOTE_WPTT_STACK_SIZE))
{
retval = NOTE_DEFS_DECODE_SUCCESS;
/*Check if the active node is the root*/
if (1 < wptt_stack_len)
{
note_wptt_node_t *active_node_p = wptt_node_stack[wptt_stack_len - 2];
/*Add child to active node*/
active_node_p->children[active_node_p->number_of_children] =
wptt_node_stack[wptt_stack_len - 1];
active_node_p->number_of_children++;
}
}
return retval;
}
/************************** Encode Path Functions **************************/
STATIC_INLINE bool note_wptt_encode_stick_check(note_wptt_node_t *active_node_p)
{
bool retval = false;
note_wptt_node_t *child_node = active_node_p;
while ((child_node->number_of_children < 2) &&
(0 == child_node->number_of_rings) &&
((0 == child_node->weights[0]) ||
(0 == child_node->number_of_children)))
{
if (0 == child_node->number_of_children)
{
retval = true;
break;
}
child_node = child_node->children[0];
}
return retval;
}
STATIC_INLINE void note_wptt_encode_normalize_node_order(
note_wptt_node_t *active_node_p)
{
if (NOTE_WPTT_ORDER_REVERSE == active_node_p->order)
{
size_t i = 0;
for (i = 0; 2 * i < active_node_p->number_of_children; i++)
{
size_t back_child_pos = (active_node_p->number_of_children - 1) - i;
size_t back_weight_pos = active_node_p->number_of_children - i;
note_wptt_node_t *child = active_node_p->children[i];
uint8_t weight = active_node_p->weights[i];
active_node_p->children[i] = active_node_p->children[back_child_pos];
active_node_p->children[back_child_pos] = child;
active_node_p->weights[i] = active_node_p->weights[back_weight_pos];
active_node_p->weights[back_weight_pos] = weight;
}
active_node_p->order = NOTE_WPTT_ORDER_FORWARD;
}
}
STATIC_INLINE_UINT8 note_wptt_encode_insert_stick(note_wptt_node_t *active_node_p,
char **str_p,
const char *buffer_end_p)
{
uint8_t retval = NOTE_DEFS_ENCODE_FAIL;
int8_t weights[UTIL_TANG_DEFS_MAX_CROSSINGNUM] = { 0 };
uint8_t weight_idx = 0;
note_wptt_node_t *child_node = active_node_p;
size_t i = 0;
retval = note_wptt_encode_insert_char('[', str_p, buffer_end_p);
/*Collect interior weights*/
while (0 < child_node->number_of_children)
{
weights[weight_idx] = child_node->weights[1];
if (1 == weight_idx % 2)
{
weights[weight_idx] *= -1;
}
weight_idx++;
child_node = child_node->children[0];
}
/*Collect leaf weight*/
weights[weight_idx] = child_node->weights[0];
if (1 == weight_idx % 2)
{
weights[weight_idx] *= -1;
}
/*Stringify weights*/
for (i = 0; i < weight_idx; i++)
{
retval |= note_wptt_encode_insert_int(weights[weight_idx - i], str_p, buffer_end_p);
retval |= note_wptt_encode_insert_char(' ', str_p, buffer_end_p);
}
retval |= note_wptt_encode_insert_int(weights[0], str_p, buffer_end_p);
retval |= note_wptt_encode_insert_char(']', str_p, buffer_end_p);
return retval;
}
STATIC_INLINE_UINT8 note_wptt_encode_insert_label(note_wptt_V4_label_e label,
char **str_p,
const char *buffer_end_p)
{
uint8_t retval = NOTE_DEFS_ENCODE_SUCCESS;
switch (label)
{
case NOTE_WPTT_V4_LABEL_NONE:
{
break;
}
case NOTE_WPTT_V4_LABEL_I:
{
retval |= note_wptt_encode_insert_char('i', str_p, buffer_end_p);
break;
}
case NOTE_WPTT_V4_LABEL_X:
{
retval |= note_wptt_encode_insert_char('x', str_p, buffer_end_p);
break;
}
case NOTE_WPTT_V4_LABEL_Y:
{
retval |= note_wptt_encode_insert_char('y', str_p, buffer_end_p);
break;
}
case NOTE_WPTT_V4_LABEL_Z:
{
retval |= note_wptt_encode_insert_char('z', str_p, buffer_end_p);
break;
}
default:
{
retval = NOTE_STATUS_BLDR(NOTE_DEFS_ENCODE_FAIL, NOTE_WPTT_ENCODE_MALFORMED);
}
}
return retval;
}
STATIC_INLINE_UINT8 note_wptt_encode_insert_space(char **str_p,
const char *buffer_start_p,
const char *buffer_end_p)
{
uint8_t retval = NOTE_DEFS_ENCODE_FAIL;
/*Check if there is room in string buffer*/
if (((*str_p + 1) < buffer_end_p) && (buffer_start_p < (*str_p)))
{
retval = NOTE_DEFS_ENCODE_SUCCESS;
/*Look backward for an integer*/
if (((*str_p - 1)[0] >= '0') && ((*str_p - 1)[0] <= '9'))
{
(*str_p)[0] = ' ';
(*str_p)++;
}
}
else
{
retval = NOTE_STATUS_BLDR(NOTE_DEFS_ENCODE_FAIL, NOTE_WPTT_ENCODE_STR_BUF);
}
return retval;
}
STATIC_INLINE_UINT8 note_wptt_encode_insert_char(char new_char,
char **str_p,
const char *buffer_end_p)
{
uint8_t retval = NOTE_DEFS_ENCODE_FAIL;
if ((*str_p + 1) < buffer_end_p)
{
(*str_p)[0] = new_char;
(*str_p)++;
retval = NOTE_DEFS_ENCODE_SUCCESS;
}
else
{
retval = NOTE_STATUS_BLDR(NOTE_DEFS_ENCODE_FAIL, NOTE_WPTT_ENCODE_STR_BUF);
}
return retval;
}
STATIC_INLINE_UINT8 note_wptt_encode_insert_int(int8_t new_int,
char **str_p,
const char *buffer_end_p)
{
uint8_t retval = NOTE_DEFS_ENCODE_FAIL;
size_t local_offset = 0;
char local_str[UTIL_TANG_DEFS_MAX_CROSSINGNUM];
sprintf(local_str, "%d", new_int);
local_offset = strlen(local_str);
if ((*str_p + local_offset) < buffer_end_p)
{
strcpy(*str_p, local_str);
(*str_p) += local_offset;
retval = NOTE_DEFS_ENCODE_SUCCESS;
}
else
{
retval = NOTE_STATUS_BLDR(NOTE_DEFS_ENCODE_FAIL, NOTE_WPTT_ENCODE_STR_BUF);
}
return retval;
}
STATIC_INLINE_UINT8 note_wptt_encode_complete_active_node(
const note_wptt_node_t *active_node_p,
char **str_p,
size_t ordered_child_idx,
const char *buffer_start_p,
const char *buffer_end_p)
{
uint8_t retval = NOTE_DEFS_ENCODE_SUCCESS;
/*Insert final weight*/
if (0 != active_node_p->weights[ordered_child_idx])
{
retval |= note_wptt_encode_insert_space(str_p,
buffer_start_p,
buffer_end_p);
retval |= note_wptt_encode_insert_int(active_node_p->weights[ordered_child_idx],
str_p,
buffer_end_p);
}
/*Close node*/
if (0 < active_node_p->number_of_rings)
{
retval |= note_wptt_encode_insert_char('>', str_p, buffer_end_p);
}
else
{
retval |= note_wptt_encode_insert_char(')', str_p, buffer_end_p);
}
return retval;
}
STATIC_INLINE_UINT8 note_wptt_encode_process_active_node(
note_wptt_node_t *active_node,
char **str_p,
size_t ordered_child_idx,
const char *buffer_start_p,
const char *buffer_end_p)
{
uint8_t retval = NOTE_DEFS_ENCODE_SUCCESS;
bool found_stick = note_wptt_encode_stick_check(active_node);
/*Check if node has more children and start new node*/
/* cppcheck-suppress negativeIndex */
if (0 == child_idx_stack[wptt_stack_len - 1])
{
if (0 < active_node->number_of_rings)
{
retval |= note_wptt_encode_insert_char('<', str_p, buffer_end_p);
retval |= note_wptt_encode_insert_int(active_node->number_of_rings, str_p,
buffer_end_p);
}
else if (true == found_stick)
{
retval |= note_wptt_encode_insert_stick(active_node, str_p, buffer_end_p);
/*pop stack*/
if (0 < wptt_stack_len)
{
wptt_stack_len--;
}
else
{
retval |= NOTE_STATUS_BLDR(NOTE_DEFS_ENCODE_FAIL, NOTE_WPTT_ENCODE_OVRUNDR_ERROR);
}
}
else
{
retval |= note_wptt_encode_insert_char('(', str_p, buffer_end_p);
}
}
if (false == found_stick)
{
/*Stringify weight*/
if ((0 != active_node->weights[ordered_child_idx]) &&
(false == found_stick))
{
retval |= note_wptt_encode_insert_space(str_p, buffer_start_p, buffer_end_p);
retval |= note_wptt_encode_insert_int(active_node->weights[ordered_child_idx],
str_p,
buffer_end_p);
}
/*Push child to stack*/
child_idx_stack[wptt_stack_len - 1]++;
if (child_idx_stack[wptt_stack_len - 1] <= active_node->number_of_children)
{
wptt_stack_len++;
wptt_node_stack[wptt_stack_len - 1] = active_node->children[ordered_child_idx];
child_idx_stack[wptt_stack_len - 1] = 0;
}
}
return retval;
}