Beispiel #1
0
static int __may_fail
query_create_schema_impl (query_result *r, char *name, int strict)
{
  __returns_int;

  // make checks
  __precondition(NULL != r);
  schema *s = datastore_get_schema_by_name(name);
  parser_assert_err(QUERY_ERR_SCHEMA_EEXISTS, !(strict && s), name);

  // handle query
  if (s)
    return 0;

  __checked_call(NULL != (s = schema_create(name)));
  __checked_call(0 == datastore_add_schema(s),
    schema_destroy(s);
  );
Beispiel #2
0
/*
 * schema_create - create and initialize a schema
 *
 * - allocate memory for the schema, application shall later call 
 *   schema_destroy to clean up
 * - parse the definition string;
 * - empty defstring create a stub schema for schema_fromascii
 * - return pointer to a schema if OK, NULL on error
 *
 */
schema_t *schema_create(const char *defstring)
{
    schema_t *schema;
    char *dupstring, *saveptr, *name, *type;
    int offset, fieldind;
    int tempsize, failed;
    field_t *newtable;
    
    /* allocate memory */
    if ((schema = (schema_t *)malloc(sizeof(schema_t))) == NULL) {
        perror("schema_create: malloc");
        return NULL;
    }
    
    /* check whether we should proceed to parse the definition string */
    if (defstring == NULL) {
        return schema;
    } else if ((dupstring = strdup(defstring)) == NULL) {
        /* remember to duplicate the string for strtok_r */
        perror("schema_create: strdup");
        return NULL;
    }
    
    schema->endian = xplatform_testendian();
    schema->fieldnum = 0;
    schema->field = NULL;
        
    /* 
       allocate field table with a tempsize (8);
       we need to further expand the table or shrink as more or less 
       fields are actually parsed 
    */
    tempsize = 8;
    schema->field = (field_t *)malloc(tempsize * sizeof(field_t));
    if (schema->field == NULL) {
        perror("schema_create: malloc field table");
        free(dupstring);
        free(schema);
    }

    /*
      special treatment for the first field's type since the dupstring
      has to be passed in as the first argument 
    */
    fieldind = 0;
    offset = 0;
    type = (char *)strtok_r(dupstring, " ", &saveptr);
    if (type == NULL) {
        fprintf(stderr, "schema_create: illegal syntax \"%s\"\n", defstring);
        free(dupstring);
        free(schema);
        return NULL;
    }
    
    /* 
       install the current field entry in the schema table and 
       parse the next one 
    */
    failed = 0;
    schema->fieldnum = 0;
    while (type != NULL) {

        /* check whether we shall expand the table */
        if (fieldind == tempsize) {
            tempsize *= 2;
            newtable = 
                (field_t *)realloc(schema->field, tempsize * sizeof(field_t));
            if (newtable == NULL) {
                perror("schema_create: reallocate field table");
                failed = 1;
                break;
            } else
                schema->field = newtable;
        }

        /* determine the size of the field */
        if ((strcmp(type, "int8_t") == 0) ||
            (strcmp(type, "uint8_t") == 0) ||
            (strcmp(type, "char") == 0)) 
            schema->field[fieldind].size = 1;

        else if ((strcmp(type, "int16_t") == 0) ||
                 (strcmp(type, "uint16_t") == 0))
            schema->field[fieldind].size = 2;

        else if ((strcmp(type, "int32_t") == 0) ||
                 (strcmp(type, "uint32_t") == 0) ||
                 (strcmp(type, "float32_t") == 0) ||
                 (strcmp(type, "float") == 0))
            schema->field[fieldind].size = 4;

        else if ((strcmp(type, "float64_t") == 0) ||
                 (strcmp(type, "int64_t") == 0) ||
                 (strcmp(type, "uint64_t") == 0) ||
                 (strcmp(type, "double") == 0))
            schema->field[fieldind].size = 8;

        else {
            fprintf(stderr, "schema_create: unknown type \"%s\"\n", type);
            failed = 1;
            break;
        }

        schema->field[fieldind].offset = offset;
        offset +=  schema->field[fieldind].size;  /* for the next field */
        
        /* proceed to read in the variable name */
        name = (char *)strtok_r(NULL, " ;", &saveptr);
        if (name == NULL) {
            fprintf(stderr, "schema_create: variable name missing \"%s\"\n",
                    defstring);
            failed = 1;
            break;
        }


        /* allocate memory for the field name */
        if (!IsValidName(name)) {
            fprintf(stderr, "schema_create: invalid field name %s\n", name);
            failed = 1;
            break;
        }

        schema->field[fieldind].name = NULL;
        schema->field[fieldind].type = NULL;
           
        if ((schema->field[fieldind].name = strdup(name)) == NULL) {
            perror("schema_create: strdup field name");
            failed = 1;
            break;
        }

        /* record the type verbatim */
        if ((schema->field[fieldind].type = strdup(type)) == NULL) {
            perror("schema_create: strdup field type");
            failed = 1;
            break;
        }
           
        /* parse the next field's type */
        fieldind++;
        type = (char *)strtok_r(NULL, " ;", &saveptr);
    }
    
    schema->fieldnum = fieldind; 
    free(dupstring); /* must be released no matter what */

    if (failed ) {
        schema_destroy(schema);
        return NULL;
    }
    
    /* shrink the table if we have over-provisioned */
    if (schema->fieldnum < tempsize) {
        newtable = (field_t *)
            realloc(schema->field, schema->fieldnum * sizeof(field_t));
        if (newtable == NULL) {
            perror("schema_create: reallocate (shrink) field table");
            schema_destroy(schema);
            return NULL;
        }
        schema->field = newtable;
    }
    
    return schema;
}
Beispiel #3
0
/*
 * schema_fromascii - input a converted schema ASCII string into a schema
 *
 * - memory is allocated for the schema, application shall later call 
 *   schema_destroy to clean up
 * - assume the ascii string is produced by schema_toascii
 * - return a  pointer to the initialized schema if OK, NULL on error
 *
 */
schema_t *schema_fromascii(const char *asc_schema)
{
    int fieldind;
    char *buf, *saveptr;
    char *endian, *fieldnum, *name, *size, *offset, *type;
    schema_t *schema;

    if ((schema = schema_create(NULL)) == NULL) {
        fprintf(stderr, "schema_fromascii: cannot create schema stub\n");
        return NULL;
    }
    
    if ((buf = strdup(asc_schema)) == NULL) {
        perror("schema_fromascii: strdup");
        return NULL;
    }

    endian = (char *)strtok_r(buf, " ", &saveptr);
    if (strcmp(endian, "L") == 0) 
        schema->endian = little;
    else if (strcmp(endian, "B") == 0) 
        schema->endian = big;
    else {
        fprintf(stderr, "schema_fromascii: unknown endianness %s\n", endian);
        free(schema);
        return NULL;
    }
    
    fieldnum = (char *)strtok_r(NULL, " ", &saveptr);
    if (fieldnum == NULL) {
        fprintf(stderr, "schema_fromascii: missing fieldnum %s\n", asc_schema);
        free(schema);
        return NULL;
    }

    if (sscanf(fieldnum, "%d", &schema->fieldnum) != 1) {
        fprintf(stderr, "schema_fromascii: unknown fieldnum specifier %s\n",
                fieldnum);
    }
    
    /* allocate the field table */
    schema->field = (field_t *)malloc(schema->fieldnum * sizeof(field_t));
    if (schema->field == NULL) {
        perror("schema_fromascii: malloc field table");
        free(schema);
        return NULL;
    }

    for (fieldind = 0 ; fieldind < schema->fieldnum; fieldind++) {
        name = (char *)strtok_r((char *)NULL, " ", &saveptr);
        type = (char *)strtok_r((char *)NULL, " ", &saveptr); 
        size = (char *)strtok_r((char *)NULL, " ", &saveptr);
        offset = (char *)strtok_r((char *)NULL, " ", &saveptr);
        
        if ((name == NULL) || (type == NULL) ||
            (size == NULL) || (offset == NULL)) {
            fprintf(stderr, "schema_fromascii: incomplete ascii schema %s\n",
                    asc_schema);
            break;
        }
        
        if (sscanf(size, "%d", &schema->field[fieldind].size) != 1) {
            fprintf(stderr, "schema_fromascii: unknown size specifier %s\n",
                    size);
            break;
        }
        
        if (sscanf(offset, "%d", &schema->field[fieldind].offset) != 1) {
            fprintf(stderr, "schema_fromascii: unknown offset specifer %s\n",
                    offset);
            break;
        }
            

        if ((schema->field[fieldind].name = strdup(name)) == NULL) {
            perror("schema_fromascii: strdup field name");
            break;
        }
        
        if ((schema->field[fieldind].type = strdup(type)) == NULL) {
            perror("schema_fromascii: strdup field type");
            break;
        }
        
    }

    free(buf);  /* we need to free the memory */

    if (fieldind < schema->fieldnum) {
        /* 
           break out of the loop because of error 
           here is a trick to guarantee the proper behavior 
           of schema_destroy 
        */
        schema->fieldnum = fieldind; 
        schema_destroy(schema);
        return NULL;
    }


    return schema;
    
}