Changeset 9709d1b in serd


Ignore:
Timestamp:
07/31/17 00:37:57 (3 weeks ago)
Author:
David Robillard <d@…>
Branches:
serd1
Children:
214ffc9
Parents:
af0beac
git-author:
David Robillard <d@…> (03/16/16 17:43:05)
git-committer:
David Robillard <d@…> (07/31/17 00:37:57)
Message:

Use private implementation for dynamic nodes

This avoids a lot of const-correctness violations, by storing a pointer
to the non-const buffer when it is allocated (e.g. by serd_node_new_*
functions). Alone this isn't worth the overhead, but in the future this
is where additional information can go for extensibility and eventual
integration with sord, without losing the efficiency of stack-allocated
nodes for parsing and serialising.

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • NEWS

    ra26622b r9709d1b  
    55  * Fix construction and comparison of URIs with UTF-8 characters 
    66  * Use char* for strings in public API 
     7  * Use private implementation for dynamically allocated nodes 
    78  * Remove useless character counting 
    89  * Report I/O errors with message and return appropriate status code 
  • serd/serd.h

    raf0beac r9709d1b  
    8383 
    8484/** 
     85   Private implementation of a SerdNode. 
     86*/ 
     87typedef struct SerdNodeImpl SerdNodeImpl; 
     88 
     89/** 
    8590   Return status code. 
    8691*/ 
     
    216221*/ 
    217222typedef struct { 
    218     const char*    buf;      /**< Value string */ 
    219     size_t         n_bytes;  /**< Size in bytes (not including null) */ 
    220     SerdNodeFlags  flags;    /**< Node flags (e.g. string properties) */ 
    221     SerdType       type;     /**< Node type */ 
     223    const char*   buf;      /**< Value string */ 
     224    size_t        n_bytes;  /**< Size in bytes (not including null) */ 
     225    SerdNodeFlags flags;    /**< Node flags (e.g. string properties) */ 
     226    SerdType      type;     /**< Node type */ 
     227    SerdNodeImpl* impl;     /**< Private implementation (possibly NULL) */ 
    222228} SerdNode; 
    223229 
     
    444450*/ 
    445451 
    446 static const SerdNode SERD_NODE_NULL = { NULL, 0, 0, SERD_NOTHING }; 
     452static const SerdNode SERD_NODE_NULL = { NULL, 0, 0, SERD_NOTHING, NULL }; 
    447453 
    448454/** 
  • src/env.c

    raf0beac r9709d1b  
    246246        const size_t len = prefix.len + suffix.len; 
    247247        char*        buf = (char*)malloc(len + 1); 
    248         SerdNode     ret = { buf, len, 0, SERD_URI }; 
     248        SerdNode     ret = { buf, len, 0, SERD_URI, serd_new_node_impl(buf) }; 
    249249        snprintf((char*)buf, ret.n_bytes + 1, "%s%s", prefix.buf, suffix.buf); 
    250250        return ret; 
  • src/node.c

    ra26622b r9709d1b  
    4040    } 
    4141 
    42     uint32_t       flags   = 0; 
    43     const size_t   n_bytes = serd_strlen(str, &flags); 
    44     const SerdNode ret     = { str, n_bytes, flags, type }; 
     42    uint32_t     flags   = 0; 
     43    const size_t n_bytes = serd_strlen(str, &flags); 
     44    SerdNode     ret     = { str, n_bytes, flags, type, NULL }; 
    4545    return ret; 
    4646} 
     
    5656    uint32_t       flags   = 0; 
    5757    const size_t   n_bytes = serd_substrlen(str, len, &flags); 
    58     const SerdNode ret     = { str, n_bytes, flags, type }; 
     58    const SerdNode ret     = { str, n_bytes, flags, type, NULL }; 
    5959    return ret; 
    6060} 
     
    6969 
    7070    SerdNode copy = *node; 
    71     char* buf  = (char*)malloc(copy.n_bytes + 1); 
     71    char*    buf  = (char*)malloc(copy.n_bytes + 1); 
    7272    memcpy(buf, node->buf, copy.n_bytes + 1); 
    73     copy.buf = buf; 
     73    copy.buf  = buf; 
     74    copy.impl = serd_new_node_impl(buf); 
    7475    return copy; 
    7576} 
     
    200201    } 
    201202 
    202     return serd_node_from_substring(SERD_URI, buffer.buf, buffer.len); 
     203    SerdNode node = serd_node_from_substring(SERD_URI, buffer.buf, buffer.len); 
     204    node.impl = serd_new_node_impl(buffer.buf); 
     205    return node; 
    203206} 
    204207 
     
    214217    const size_t len        = serd_uri_string_length(&abs_uri); 
    215218    char*        buf        = (char*)malloc(len + 1); 
    216     SerdNode     node       = { buf, len, 0, SERD_URI }; 
     219    SerdNode     node       = { buf, len, 0, SERD_URI, serd_new_node_impl(buf) }; 
    217220    char*        ptr        = buf; 
    218221    const size_t actual_len = serd_uri_serialise(&abs_uri, string_sink, &ptr); 
     
    238241    const size_t base_len   = serd_uri_string_length(base); 
    239242    char*        buf        = (char*)malloc(uri_len + base_len + 1); 
    240     SerdNode     node       = { buf, 0, 0, SERD_URI }; 
     243    SerdNode     node       = { buf, 0, 0, SERD_URI, serd_new_node_impl(buf) }; 
    241244    char*        ptr        = buf; 
    242245    const size_t actual_len = serd_uri_serialise_relative( 
     
    271274    const unsigned int_digits = serd_digits(abs_d); 
    272275    char*          buf        = (char*)calloc(int_digits + frac_digits + 3, 1); 
    273     SerdNode       node       = { buf, 0, 0, SERD_LITERAL }; 
     276    SerdNode       node       = { buf, 0, 0, SERD_LITERAL, serd_new_node_impl(buf) }; 
    274277    const double   int_part   = floor(abs_d); 
    275278 
     
    287290        *t-- = '0' + (dec % 10); 
    288291    } while ((dec /= 10) > 0); 
     292 
    289293 
    290294    *s++ = '.'; 
     
    322326    const unsigned digits = serd_digits(abs_i); 
    323327    char*          buf    = (char*)calloc(digits + 2, 1); 
    324     SerdNode       node   = { (const char*)buf, 0, 0, SERD_LITERAL }; 
     328    SerdNode       node   = { buf, 0, 0, SERD_LITERAL, serd_new_node_impl(buf) }; 
    325329 
    326330    // Point s to the end 
     
    368372    const size_t len  = ((size + 2) / 3) * 4 + (wrap_lines ? (size / 57) : 0); 
    369373    uint8_t*     str  = (uint8_t*)calloc(1, len + 2); 
    370     SerdNode     node = { (const char*)str, len, 0, SERD_LITERAL }; 
     374    SerdNode     node = { (const char*)str, len, 0, SERD_LITERAL, serd_new_node_impl((char*)str) }; 
    371375    for (size_t i = 0, j = 0; i < size; i += 3, j += 4) { 
    372376        uint8_t in[4] = { 0, 0, 0, 0 }; 
     
    388392serd_node_free(SerdNode* node) 
    389393{ 
    390     if (node && node->buf) { 
    391         free((char*)node->buf); 
    392         node->buf = NULL; 
    393     } 
    394 } 
     394    if (node && node->impl) { 
     395        free(node->impl->buf); 
     396        free(node->impl); 
     397 
     398        *node = SERD_NODE_NULL; 
     399    } 
     400} 
  • src/reader.c

    ra26622b r9709d1b  
    10871087    } 
    10881088 
    1089     SerdNode* n = deref(reader, ref); 
    1090     if (n->buf[n->n_bytes - 1] == '.' && read_PN_CHARS(reader, ref)) { 
     1089    SerdNode* n   = deref(reader, ref); 
     1090    char*     buf = (char*)(n + 1); 
     1091    if (buf[n->n_bytes - 1] == '.' && read_PN_CHARS(reader, ref)) { 
    10911092        // Ate trailing dot, pop it from stack/node and inform caller 
    10921093        --n->n_bytes; 
     
    10961097 
    10971098    if (reader->syntax == SERD_TURTLE) { 
    1098         if (is_digit(n->buf[reader->bprefix_len + 1])) { 
    1099             if ((n->buf[reader->bprefix_len]) == 'b') { 
    1100                 ((char*)n->buf)[reader->bprefix_len] = 'B';  // Prevent clash 
     1099        if (is_digit(buf[reader->bprefix_len + 1])) { 
     1100            if ((buf[reader->bprefix_len]) == 'b') { 
     1101                buf[reader->bprefix_len] = 'B';  // Prevent clash 
    11011102                reader->seen_genid = true; 
    11021103            } else if (reader->seen_genid && 
    1103                        n->buf[reader->bprefix_len] == 'B') { 
     1104                       buf[reader->bprefix_len] == 'B') { 
    11041105                r_err(reader, SERD_ERR_ID_CLASH, 
    11051106                      "found both `b' and `B' blank IDs, prefix required\n"); 
     
    11151116{ 
    11161117    SerdNode*   node   = deref(reader, ref); 
     1118    char*       buf    = (char*)(node + 1); 
    11171119    const char* prefix = reader->bprefix ? reader->bprefix : ""; 
    1118     node->n_bytes = snprintf( 
    1119         (char*)node->buf, buf_size, "%sb%u", prefix, reader->next_id++); 
     1120    node->n_bytes = snprintf(buf, buf_size, "%sb%u", prefix, reader->next_id++); 
    11201121} 
    11211122 
  • src/serd_internal.h

    raf0beac r9709d1b  
    3939#endif 
    4040 
     41 
    4142static const uint8_t replacement_char[] = { 0xEF, 0xBF, 0xBD }; 
     43 
     44struct SerdNodeImpl { 
     45    char* buf;  ///< Dynamically allocated buffer 
     46}; 
     47 
     48static inline SerdNodeImpl* 
     49serd_new_node_impl(char* buf) 
     50{ 
     51    SerdNodeImpl* impl = (SerdNodeImpl*)malloc(sizeof(SerdNodeImpl)); 
     52    impl->buf = buf; 
     53    return impl; 
     54} 
    4255 
    4356/* File and Buffer Utilities */ 
  • src/writer.c

    raf0beac r9709d1b  
    3232 
    3333static const WriteContext WRITE_CONTEXT_NULL = { 
    34     { 0, 0, 0, SERD_NOTHING }, 
    35     { 0, 0, 0, SERD_NOTHING }, 
    36     { 0, 0, 0, SERD_NOTHING } 
     34    { 0, 0, 0, SERD_NOTHING, NULL }, 
     35    { 0, 0, 0, SERD_NOTHING, NULL }, 
     36    { 0, 0, 0, SERD_NOTHING, NULL } 
    3737}; 
    3838 
     
    158158{ 
    159159    if (src) { 
    160         dst->buf = (char*)realloc((char*)dst->buf, src->n_bytes + 1); 
    161         dst->n_bytes = src->n_bytes; 
    162         dst->flags   = src->flags; 
    163         dst->type    = src->type; 
    164         memcpy((char*)dst->buf, src->buf, src->n_bytes + 1); 
     160        if (!dst->impl) { 
     161            dst->impl = serd_new_node_impl((char*)malloc(src->n_bytes + 1)); 
     162        } else { 
     163            dst->impl->buf = realloc(dst->impl->buf, src->n_bytes + 1); 
     164        } 
     165        dst->buf       = dst->impl->buf; 
     166        dst->n_bytes   = src->n_bytes; 
     167        dst->flags     = src->flags; 
     168        dst->type      = src->type; 
     169        memcpy(dst->impl->buf, src->buf, src->n_bytes + 1); 
    165170    } else { 
    166171        dst->type = SERD_NOTHING; 
Note: See TracChangeset for help on using the changeset viewer.