Skip to content

File notation_att.c

File List > note-algebraic_tangle_tree > src > notation_att.c

Go to the documentation of this file

#include "notation_att.h"
#include "stdio.h"
#include "stdlib.h"

/******************************************************************************/
/************************** Defines *******************************************/
/******************************************************************************/

/******************************************************************************/
/************************** Local Variables ***********************************/
/******************************************************************************/

static size_t note_att_str_idx = 0u;

static size_t note_att_tv_idx = 0u;
/******************************************************************************/
/************************** Private Function Declarations *********************/
/******************************************************************************/

STATIC_INLINE_UINT8 note_att_traverse(note_att_node_t *node,
                                      char *str,
                                      size_t buffer_size);
STATIC_INLINE_UINT8 note_att_add_tv(const note_tv_t *tv,
                                    char *str,
                                    size_t buffer_size);
STATIC_INLINE_UINT8 note_att_traverse_string(note_att_t *att,
                                             note_att_node_t *node,
                                             char *str,
                                             size_t att_node_idx);
STATIC_INLINE_UINT8 note_att_process_tv(const char *str, note_att_t *att);

/******************************************************************************/
/************************** Public Function Definitions ***********************/
/******************************************************************************/

/*
 *  Documentation in header
 */
uint8_t note_att_decode(char *str, note_att_t *att)
{
    uint8_t retval = NOTE_DEFS_DECODE_SUCCESS;

    if ((str == NULL) || (att == NULL))
    {
        retval = NOTE_DEFS_DECODE_FAIL;
    }
    else if ((att->node_buffer == NULL) || (att->tv_buffer == NULL) ||
             (att->tv_buffer_len == 0) || (att->node_buffer_len == 0))
    {
        retval = NOTE_DEFS_DECODE_FAIL;
    }
    else
    {
        att->root        = &(att->node_buffer[0]);
        note_att_str_idx = 0u;
        note_att_tv_idx  = 0u;
        if (str[0] == '+')
        {
            NOTE_ATT_SET_OP(att->root->operation, NOTE_ATT_OP_PLUS);
        }
        else if (str[0] == 'v')
        {
            NOTE_ATT_SET_OP(att->root->operation, NOTE_ATT_OP_VEE);
        }
        else
        {
            retval = NOTE_DEFS_DECODE_FAIL;
        }
        note_att_str_idx++;
        retval = note_att_traverse_string(att, att->root, str, 0x0u);
    }
    return retval;
}

/*
 *  Documentation in header
 */
uint8_t note_att_encode(note_att_t att, char *str, size_t buffer_size)
{
    uint8_t retval = NOTE_DEFS_ENCODE_FAIL;

    if (str == NULL)
    {
        retval = NOTE_DEFS_ENCODE_FAIL;
    }
    else if ((att.root) == NULL)
    {
        retval = NOTE_DEFS_ENCODE_FAIL;
    }
    else
    {
        uint8_t result = NOTE_ATT_TRAVERSE_FAIL;
        result = note_att_traverse(att.root, str, buffer_size);
        if (result == NOTE_ATT_TRAVERSE_SUCCESS)
        {
            retval = NOTE_DEFS_ENCODE_SUCCESS;
        }
    }
    return retval;
}

/******************************************************************************/
/************************** Private Function Definitions **********************/
/******************************************************************************/

STATIC_INLINE_UINT8 note_att_traverse(note_att_node_t *node,
                                      char *str,
                                      size_t buffer_size)
{
    uint8_t retval = NOTE_ATT_TRAVERSE_SUCCESS;

    if (NOTE_ATT_CHK_OP(node->operation, NOTE_ATT_OP_PLUS) == true)
    {
        strcpy(str, "+");
    }
    else if (NOTE_ATT_CHK_OP(node->operation, NOTE_ATT_OP_VEE) == true)
    {
        strcpy(str, "v");
    }
    else
    {
        retval = NOTE_ATT_TRAVERSE_FAIL;
    }

    buffer_size -= strlen(str);
    str         += strlen(str);

    if (retval != NOTE_ATT_TRAVERSE_FAIL)
    {
        if (node->L_child != NULL)
        {
            retval = note_att_traverse(node->L_child, str, buffer_size);
        }
        else if (node->L_tv != NULL)
        {
            retval = note_att_add_tv(node->L_tv, str, buffer_size);
        }
        else
        {
            retval = NOTE_ATT_TRAVERSE_FAIL;
        }
    }
    str += strlen(str);

    if (retval != NOTE_ATT_TRAVERSE_FAIL)
    {
        if (node->R_child != NULL)
        {
            retval = note_att_traverse(node->R_child, str, buffer_size);
        }
        else if (node->R_tv != NULL)
        {
            retval = note_att_add_tv(node->R_tv, str, buffer_size);
        }
        else
        {
            retval = NOTE_ATT_TRAVERSE_FAIL;
        }
    }

    return retval;
}

STATIC_INLINE_UINT8 note_att_add_tv(const note_tv_t *tv,
                                    char *str,
                                    size_t buffer_size)
{
    uint8_t ret_val = NOTE_ATT_TRAVERSE_FAIL;

    if (tv != NULL)
    {
        uint8_t result = NOTE_DEFS_ENCODE_FAIL;
        result = note_tv_encode(*tv, str, buffer_size);
        if (result == NOTE_DEFS_ENCODE_SUCCESS)
        {
            ret_val = NOTE_ATT_TRAVERSE_SUCCESS;
        }
    }
    return ret_val;
}

STATIC_INLINE_UINT8 note_att_traverse_string(note_att_t *att,
                                             note_att_node_t *node,
                                             char *str,
                                             size_t att_node_idx)
{
    uint8_t ret_val     = NOTE_ATT_TRAVERSE_SUCCESS;
    size_t  new_att_gen = 0x0u;

    node->L_child = NULL;
    node->R_child = NULL;
    node->L_tv    = NULL;
    node->R_tv    = NULL;
    /* +[4 3 3 5 6]v+[3 3 3][2 2 3] */
    if (str[note_att_str_idx] == '[')
    {
        node->L_tv = &(att->tv_buffer[note_att_tv_idx]);
        ret_val    = note_att_process_tv(str, att);
        note_att_tv_idx++;
    }
    else
    {
        new_att_gen++;
        node->L_child = &(att->node_buffer[att_node_idx + new_att_gen]);
        if (str[note_att_str_idx] == '+')
        {
            NOTE_ATT_SET_OP(node->L_child->operation, NOTE_ATT_OP_PLUS);
        }
        else if (str[note_att_str_idx] == 'v')
        {
            NOTE_ATT_SET_OP(node->L_child->operation, NOTE_ATT_OP_VEE);
        }
        else
        {
            ret_val = NOTE_DEFS_DECODE_FAIL;
        }
        note_att_str_idx++;
        ret_val = note_att_traverse_string(
            att, node->L_child, str, att_node_idx + new_att_gen);
    }

    if ((str[note_att_str_idx] == '[') && (ret_val == NOTE_ATT_TRAVERSE_SUCCESS))
    {
        node->R_tv = &(att->tv_buffer[note_att_tv_idx]);
        ret_val    = note_att_process_tv(str, att);
        note_att_tv_idx++;
    }
    else
    {
        new_att_gen++;
        node->R_child = &(att->node_buffer[att_node_idx + new_att_gen]);
        if (str[note_att_str_idx] == '+')
        {
            NOTE_ATT_SET_OP(node->R_child->operation, NOTE_ATT_OP_PLUS);
        }
        else if (str[note_att_str_idx] == 'v')
        {
            NOTE_ATT_SET_OP(node->R_child->operation, NOTE_ATT_OP_VEE);
        }
        else
        {
            ret_val = NOTE_DEFS_DECODE_FAIL;
        }
        note_att_str_idx++;
        ret_val = note_att_traverse_string(
            att, node->R_child, str, att_node_idx + new_att_gen);
    }

    return ret_val;
}

STATIC_INLINE_UINT8 note_att_process_tv(const char *str, note_att_t *att)
{
    uint8_t ret_val = NOTE_ATT_TRAVERSE_FAIL;
    char    string_buffer[UTIL_TANG_DEFS_MAX_CROSSINGNUM * 10];
    size_t  i;

    for (i = 0; i < strlen(str); i++)
    {
        string_buffer[i] = str[note_att_str_idx + i];
        if (str[note_att_str_idx + i] == ']')
        {
            string_buffer[i + 1] = '\0';
            note_tv_decode(string_buffer, &att->tv_buffer[note_att_tv_idx]);
            note_att_str_idx += i + 1;
            ret_val           = NOTE_ATT_TRAVERSE_SUCCESS;
            break;
        }
    }
    return ret_val;
}