X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=libasn1parser%2Fasn1p_class.c;fp=libasn1parser%2Fasn1p_class.c;h=cbe9480e2baab04f878c4d2dc016ecb8baa39aec;hb=70ee6fc793ec8e828067a3569849b6c216054497;hp=0000000000000000000000000000000000000000;hpb=59f84608ec15c016958a6e0e0ddd813f376c0925;p=com%2Fasn1c.git diff --git a/libasn1parser/asn1p_class.c b/libasn1parser/asn1p_class.c new file mode 100644 index 0000000..cbe9480 --- /dev/null +++ b/libasn1parser/asn1p_class.c @@ -0,0 +1,319 @@ +#include +#include +#include +#include +#include + +#include "asn1parser.h" +#include "asn1p_class.h" + +asn1p_ioc_table_t * +asn1p_ioc_table_new() { + asn1p_ioc_table_t *it = calloc(1, sizeof(*it)); + assert(it); + return it; +} + +void +asn1p_ioc_table_add(asn1p_ioc_table_t *it, asn1p_ioc_row_t *row) { + assert(it); + + asn1p_ioc_row_t **new_rows = + realloc(it->row, (it->rows + 1) * sizeof(it->row[0])); + assert(new_rows); + it->row = new_rows; + it->row[it->rows++] = row; +} + +void +asn1p_ioc_table_append(asn1p_ioc_table_t *it, asn1p_ioc_table_t *src) { + + if(!src || !it) return; + + for(size_t i = 0; i < src->rows; i++) { + asn1p_ioc_table_add(it, asn1p_ioc_row_clone(src->row[i])); + } +} + +void +asn1p_ioc_table_free(asn1p_ioc_table_t *it) { + if(it) { + for(size_t i = 0; i < it->rows; i++) { + asn1p_ioc_row_delete(it->row[i]); + } + free(it->row); + free(it); + } +} + +size_t +asn1p_ioc_table_max_identifier_length(asn1p_ioc_table_t *it) { + size_t max_length = 0; + if(it) { + for(size_t i = 0; i < it->rows; i++) { + size_t len = asn1p_ioc_row_max_identifier_length(it->row[i]); + if(len > max_length) max_length = len; + } + } + return max_length; +} + +size_t +asn1p_ioc_row_max_identifier_length(asn1p_ioc_row_t *row) { + size_t max_length = 0; + if(row) { + for(size_t i = 0; i < row->columns; i++) { + if(row->column[i].value) { + size_t len = strlen(row->column[i].value->Identifier); + if(len > max_length) max_length = len; + } + } + } + return max_length; +} + +asn1p_ioc_row_t * +asn1p_ioc_row_new(asn1p_expr_t *oclass) { + asn1p_ioc_row_t *row; + asn1p_expr_t *field; + int columns = 0; + + assert(oclass->expr_type == A1TC_CLASSDEF); + + row = calloc(1, sizeof *row); + if(!row) return NULL; + + TQ_FOR(field, &oclass->members, next) + columns++; + + row->column = calloc(columns, sizeof *row->column); + if(!row->column) { + free(row); + return NULL; + } + row->columns = columns; + + columns = 0; + TQ_FOR(field, &oclass->members, next) { + row->column[columns].field = field; + row->column[columns].value = NULL; + columns++; + } + + return row; +} + +asn1p_ioc_row_t * +asn1p_ioc_row_clone(asn1p_ioc_row_t *src) { + asn1p_ioc_row_t *row; + + row = calloc(1, sizeof *row); + if(!row) return NULL; + + row->column = calloc(src->columns, sizeof *src->column); + if(!row->column) { + free(row); + return NULL; + } + row->columns = src->columns; + + for(size_t i = 0; i < src->columns; i++) { + row->column[i].field = src->column[i].field; + row->column[i].value = 0; + if(src->column[i].value) { + row->column[i].value = asn1p_expr_clone(src->column[i].value, 0); + } + row->column[i].new_ref = 1; + } + + return row; +} + +void +asn1p_ioc_row_delete(asn1p_ioc_row_t *row) { + if(row) { + if(row->column) { + for(size_t i = 0; i < row->columns; i++) { + if(!row->column[i].new_ref && row->column[i].value) { + /* + * Field 'reference' comes from asn1fix_cws.c : + * TQ_FIRST(&cell->field->members)->reference + * so it should not be freed here. + */ + row->column[i].value->reference = NULL; + } + asn1p_expr_free(row->column[i].value); + } + free(row->column); + } + free(row); + } +} + +int +asn1p_ioc_row_match(const asn1p_ioc_row_t *a, const asn1p_ioc_row_t *b) { + assert(a && b); + + if(a->columns != b->columns) + return -1; /* Bad! */ + + for(size_t i = 0; i < a->columns; i++) { + assert(a->column[i].field); + assert(b->column[i].field); + if(strcmp(a->column[i].field->Identifier, + b->column[i].field->Identifier) + != 0) { + return -1; /* Bad! */ + } + if((a->column[i].value && !b->column[i].value) + || (!a->column[i].value && b->column[i].value)) { + return 1; /* Not match */ + } + if(a->column[i].value && b->column[i].value) { + if(asn1p_expr_compare(a->column[i].value, b->column[i].value) + != 0) { + return 1; /* Not match */ + } + } + } + + return 0; +} + +struct asn1p_ioc_cell_s * +asn1p_ioc_row_cell_fetch(asn1p_ioc_row_t *row, const char *fieldname) { + for(size_t i = 0; i < row->columns; i++) { + if(strcmp(row->column[i].field->Identifier, fieldname) == 0) + return &row->column[i]; + } + errno = ESRCH; + return NULL; +} + +asn1p_wsyntx_chunk_t * +asn1p_wsyntx_chunk_new() { + asn1p_wsyntx_chunk_t *wc; + + wc = calloc(1, sizeof(*wc)); + + return wc; +} + +void +asn1p_wsyntx_chunk_free(asn1p_wsyntx_chunk_t *wc) { + if(wc) { + switch(wc->type) { + case WC_LITERAL: + case WC_WHITESPACE: + case WC_FIELD: + free(wc->content.token); break; + case WC_OPTIONALGROUP: + asn1p_wsyntx_free(wc->content.syntax); + break; + } + free(wc); + } +} + +asn1p_wsyntx_chunk_t * +asn1p_wsyntx_chunk_clone(asn1p_wsyntx_chunk_t *wc) { + asn1p_wsyntx_chunk_t *nc; + + nc = asn1p_wsyntx_chunk_new(); + if(nc) { + nc->type = wc->type; + switch(wc->type) { + case WC_LITERAL: + case WC_WHITESPACE: + case WC_FIELD: + nc->content.token = malloc(strlen(wc->content.token)+1); + strcpy(nc->content.token, wc->content.token); + break; + case WC_OPTIONALGROUP: + nc->content.syntax = asn1p_wsyntx_clone(wc->content.syntax); + break; + } + } + + return nc; +} + +asn1p_wsyntx_t * +asn1p_wsyntx_new() { + asn1p_wsyntx_t *wx; + + wx = calloc(1, sizeof(*wx)); + if(wx) { + TQ_INIT(&(wx->chunks)); + } + + return wx; +} + +void +asn1p_wsyntx_free(asn1p_wsyntx_t *wx) { + if(wx) { + asn1p_wsyntx_chunk_t *wc; + while((wc = TQ_REMOVE(&(wx->chunks), next))) + asn1p_wsyntx_chunk_free(wc); + free(wx); + } +} + +asn1p_wsyntx_t * +asn1p_wsyntx_clone(asn1p_wsyntx_t *wx) { + asn1p_wsyntx_t *nw; + + nw = asn1p_wsyntx_new(); + if(nw) { + asn1p_wsyntx_chunk_t *wc; + asn1p_wsyntx_chunk_t *nc; + TQ_FOR(wc, &(wx->chunks), next) { + nc = asn1p_wsyntx_chunk_clone(wc); + if(nc) { + TQ_ADD(&(nw->chunks), nc, next); + } else { + asn1p_wsyntx_free(nw); + return NULL; + } + } + } + + return nw; +} + +asn1p_wsyntx_chunk_t * +asn1p_wsyntx_chunk_fromstring(char *token, int do_copy) { + asn1p_wsyntx_chunk_t *wc; + + if(do_copy) { + static asn1p_wsyntx_chunk_t tmp; + tmp.type = WC_LITERAL; + tmp.content.token = token; + wc = asn1p_wsyntx_chunk_clone(&tmp); + } else { + wc = asn1p_wsyntx_chunk_new(); + if(wc) { + wc->type = WC_LITERAL; + wc->content.token = token; + } + } + + return wc; +} + + +asn1p_wsyntx_chunk_t * +asn1p_wsyntx_chunk_fromsyntax(asn1p_wsyntx_t *syntax) { + asn1p_wsyntx_chunk_t *wc; + + wc = asn1p_wsyntx_chunk_new(); + if(wc) { + wc->type = WC_OPTIONALGROUP; + wc->content.syntax = syntax; + syntax->parent = wc; + } + + return wc; +} +