X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fovsdb-types.c;h=8fe0d4225710b0403bffd6a6afa8add50385f98f;hb=HEAD;hp=5b7e7d8f68d37793607b53d12c831a123f9f0082;hpb=ae8f13e29057e233712356b3c03f02a7ef4e1e93;p=sliver-openvswitch.git diff --git a/lib/ovsdb-types.c b/lib/ovsdb-types.c index 5b7e7d8f6..8fe0d4225 100644 --- a/lib/ovsdb-types.c +++ b/lib/ovsdb-types.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009, 2010 Nicira Networks +/* Copyright (c) 2009, 2010, 2011, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,8 @@ #include "dynamic-string.h" #include "json.h" +#include "ovs-thread.h" +#include "ovsdb-data.h" #include "ovsdb-error.h" #include "ovsdb-parser.h" @@ -115,6 +117,7 @@ void ovsdb_base_type_init(struct ovsdb_base_type *base, enum ovsdb_atomic_type type) { base->type = type; + base->enum_ = NULL; switch (base->type) { case OVSDB_TYPE_VOID: @@ -134,11 +137,6 @@ ovsdb_base_type_init(struct ovsdb_base_type *base, enum ovsdb_atomic_type type) break; case OVSDB_TYPE_STRING: -#ifdef HAVE_PCRE - base->u.string.re = NULL; -#endif - base->u.string.reMatch = NULL; - base->u.string.reComment = NULL; base->u.string.minLen = 0; base->u.string.maxLen = UINT_MAX; break; @@ -149,19 +147,51 @@ ovsdb_base_type_init(struct ovsdb_base_type *base, enum ovsdb_atomic_type type) break; case OVSDB_N_TYPES: - NOT_REACHED(); + OVS_NOT_REACHED(); default: - NOT_REACHED(); + OVS_NOT_REACHED(); } } +/* Returns the type of the 'enum_' member for an ovsdb_base_type whose 'type' + * is 'atomic_type'. */ +const struct ovsdb_type * +ovsdb_base_type_get_enum_type(enum ovsdb_atomic_type atomic_type) +{ + static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; + static struct ovsdb_type *types[OVSDB_N_TYPES]; + + if (ovsthread_once_start(&once)) { + enum ovsdb_atomic_type i; + + for (i = 0; i < OVSDB_N_TYPES; i++) { + struct ovsdb_type *type; + + types[i] = type = xmalloc(sizeof *type); + ovsdb_base_type_init(&type->key, i); + ovsdb_base_type_init(&type->value, OVSDB_TYPE_VOID); + type->n_min = 1; + type->n_max = UINT_MAX; + } + + ovsthread_once_done(&once); + } + return types[atomic_type]; +} + void ovsdb_base_type_clone(struct ovsdb_base_type *dst, const struct ovsdb_base_type *src) { *dst = *src; + if (src->enum_) { + dst->enum_ = xmalloc(sizeof *dst->enum_); + ovsdb_datum_clone(dst->enum_, src->enum_, + ovsdb_base_type_get_enum_type(dst->type)); + } + switch (dst->type) { case OVSDB_TYPE_VOID: case OVSDB_TYPE_INTEGER: @@ -170,21 +200,8 @@ ovsdb_base_type_clone(struct ovsdb_base_type *dst, break; case OVSDB_TYPE_STRING: -#if HAVE_PCRE - if (dst->u.string.re) { - pcre_refcount(dst->u.string.re, 1); - } -#else - if (dst->u.string.reMatch) { - dst->u.string.reMatch = xstrdup(dst->u.string.reMatch); - } - if (dst->u.string.reComment) { - dst->u.string.reComment = xstrdup(dst->u.string.reComment); - } -#endif break; - case OVSDB_TYPE_UUID: if (dst->u.uuid.refTableName) { dst->u.uuid.refTableName = xstrdup(dst->u.uuid.refTableName); @@ -193,7 +210,7 @@ ovsdb_base_type_clone(struct ovsdb_base_type *dst, case OVSDB_N_TYPES: default: - NOT_REACHED(); + OVS_NOT_REACHED(); } } @@ -201,6 +218,12 @@ void ovsdb_base_type_destroy(struct ovsdb_base_type *base) { if (base) { + if (base->enum_) { + ovsdb_datum_destroy(base->enum_, + ovsdb_base_type_get_enum_type(base->type)); + free(base->enum_); + } + switch (base->type) { case OVSDB_TYPE_VOID: case OVSDB_TYPE_INTEGER: @@ -209,16 +232,6 @@ ovsdb_base_type_destroy(struct ovsdb_base_type *base) break; case OVSDB_TYPE_STRING: -#ifdef HAVE_PCRE - if (base->u.string.re && !pcre_refcount(base->u.string.re, -1)) { - pcre_free(base->u.string.re); - free(base->u.string.reMatch); - free(base->u.string.reComment); - } -#else - free(base->u.string.reMatch); - free(base->u.string.reComment); -#endif break; case OVSDB_TYPE_UUID: @@ -226,10 +239,10 @@ ovsdb_base_type_destroy(struct ovsdb_base_type *base) break; case OVSDB_N_TYPES: - NOT_REACHED(); + OVS_NOT_REACHED(); default: - NOT_REACHED(); + OVS_NOT_REACHED(); } } } @@ -265,9 +278,13 @@ ovsdb_base_type_is_valid(const struct ovsdb_base_type *base) bool ovsdb_base_type_has_constraints(const struct ovsdb_base_type *base) { + if (base->enum_) { + return true; + } + switch (base->type) { case OVSDB_TYPE_VOID: - NOT_REACHED(); + OVS_NOT_REACHED(); case OVSDB_TYPE_INTEGER: return (base->u.integer.min != INT64_MIN @@ -281,18 +298,16 @@ ovsdb_base_type_has_constraints(const struct ovsdb_base_type *base) return false; case OVSDB_TYPE_STRING: - return (base->u.string.reMatch != NULL - || base->u.string.minLen != 0 - || base->u.string.maxLen != UINT_MAX); + return base->u.string.minLen != 0 || base->u.string.maxLen != UINT_MAX; case OVSDB_TYPE_UUID: return base->u.uuid.refTableName != NULL; case OVSDB_N_TYPES: - NOT_REACHED(); + OVS_NOT_REACHED(); default: - NOT_REACHED(); + OVS_NOT_REACHED(); } } @@ -304,44 +319,6 @@ ovsdb_base_type_clear_constraints(struct ovsdb_base_type *base) ovsdb_base_type_init(base, type); } -struct ovsdb_error * -ovsdb_base_type_set_regex(struct ovsdb_base_type *base, - const char *reMatch, const char *reComment) -{ -#ifdef HAVE_PCRE - const char *errorString; - const char *pattern; - int errorOffset; - - /* Compile pattern, anchoring it at both ends. */ - pattern = reMatch; - if (pattern[0] == '\0' || strchr(pattern, '\0')[-1] != '$') { - pattern = xasprintf("%s$", pattern); - } - -#ifndef PCRE_JAVASCRIPT_COMPAT /* Added in PCRE 7.7. */ -#define PCRE_JAVASCRIPT_COMPAT 0 -#endif - base->u.string.re = pcre_compile(pattern, (PCRE_ANCHORED | PCRE_UTF8 - | PCRE_JAVASCRIPT_COMPAT), - &errorString, &errorOffset, NULL); - if (pattern != reMatch) { - free((char *) pattern); - } - if (!base->u.string.re) { - return ovsdb_syntax_error(NULL, "invalid regular expression", - "\"%s\" is not a valid regular " - "expression: %s", reMatch, errorString); - } - pcre_refcount(base->u.string.re, 1); -#endif - - /* Save regular expression. */ - base->u.string.reMatch = xstrdup(reMatch); - base->u.string.reComment = reComment ? xstrdup(reComment) : NULL; - return NULL; -} - static struct ovsdb_error * parse_optional_uint(struct ovsdb_parser *parser, const char *member, unsigned int *uint) @@ -366,7 +343,7 @@ ovsdb_base_type_from_json(struct ovsdb_base_type *base, { struct ovsdb_parser parser; struct ovsdb_error *error; - const struct json *type; + const struct json *type, *enum_; if (json->type == JSON_STRING) { error = ovsdb_atomic_type_from_json(&base->type, json); @@ -390,7 +367,18 @@ ovsdb_base_type_from_json(struct ovsdb_base_type *base, } ovsdb_base_type_init(base, base->type); - if (base->type == OVSDB_TYPE_INTEGER) { + + enum_ = ovsdb_parser_member(&parser, "enum", OP_ANY | OP_OPTIONAL); + if (enum_) { + base->enum_ = xmalloc(sizeof *base->enum_); + error = ovsdb_datum_from_json( + base->enum_, ovsdb_base_type_get_enum_type(base->type), + enum_, NULL); + if (error) { + free(base->enum_); + base->enum_ = NULL; + } + } else if (base->type == OVSDB_TYPE_INTEGER) { const struct json *min, *max; min = ovsdb_parser_member(&parser, "minInteger", @@ -414,20 +402,6 @@ ovsdb_base_type_from_json(struct ovsdb_base_type *base, error = ovsdb_syntax_error(json, NULL, "minReal exceeds maxReal"); } } else if (base->type == OVSDB_TYPE_STRING) { - const struct json *reMatch; - - reMatch = ovsdb_parser_member(&parser, "reMatch", - OP_STRING | OP_OPTIONAL); - if (reMatch) { - const struct json *reComment; - - reComment = ovsdb_parser_member(&parser, "reComment", - OP_STRING | OP_OPTIONAL); - error = ovsdb_base_type_set_regex( - base, json_string(reMatch), - reComment ? json_string(reComment) : NULL); - } - if (!error) { error = parse_optional_uint(&parser, "minLength", &base->u.string.minLen); @@ -446,10 +420,30 @@ ovsdb_base_type_from_json(struct ovsdb_base_type *base, refTable = ovsdb_parser_member(&parser, "refTable", OP_ID | OP_OPTIONAL); if (refTable) { + const struct json *refType; + base->u.uuid.refTableName = xstrdup(refTable->u.string); + /* We can't set base->u.uuid.refTable here because we don't have * enough context (we might not even be running in ovsdb-server). * ovsdb_create() will set refTable later. */ + + refType = ovsdb_parser_member(&parser, "refType", + OP_ID | OP_OPTIONAL); + if (refType) { + const char *refType_s = json_string(refType); + if (!strcmp(refType_s, "strong")) { + base->u.uuid.refType = OVSDB_REF_STRONG; + } else if (!strcmp(refType_s, "weak")) { + base->u.uuid.refType = OVSDB_REF_WEAK; + } else { + error = ovsdb_syntax_error(json, NULL, "refType must be " + "\"strong\" or \"weak\" (not " + "\"%s\")", refType_s); + } + } else { + base->u.uuid.refType = OVSDB_REF_STRONG; + } } } @@ -477,9 +471,17 @@ ovsdb_base_type_to_json(const struct ovsdb_base_type *base) json = json_object_create(); json_object_put_string(json, "type", ovsdb_atomic_type_to_string(base->type)); + + if (base->enum_) { + const struct ovsdb_type *type; + + type = ovsdb_base_type_get_enum_type(base->type); + json_object_put(json, "enum", ovsdb_datum_to_json(base->enum_, type)); + } + switch (base->type) { case OVSDB_TYPE_VOID: - NOT_REACHED(); + OVS_NOT_REACHED(); case OVSDB_TYPE_INTEGER: if (base->u.integer.min != INT64_MIN) { @@ -507,13 +509,6 @@ ovsdb_base_type_to_json(const struct ovsdb_base_type *base) break; case OVSDB_TYPE_STRING: - if (base->u.string.reMatch) { - json_object_put_string(json, "reMatch", base->u.string.reMatch); - if (base->u.string.reComment) { - json_object_put_string(json, "reComment", - base->u.string.reComment); - } - } if (base->u.string.minLen != 0) { json_object_put(json, "minLength", json_integer_create(base->u.string.minLen)); @@ -528,14 +523,17 @@ ovsdb_base_type_to_json(const struct ovsdb_base_type *base) if (base->u.uuid.refTableName) { json_object_put_string(json, "refTable", base->u.uuid.refTableName); + if (base->u.uuid.refType == OVSDB_REF_WEAK) { + json_object_put_string(json, "refType", "weak"); + } } break; case OVSDB_N_TYPES: - NOT_REACHED(); + OVS_NOT_REACHED(); default: - NOT_REACHED(); + OVS_NOT_REACHED(); } return json; @@ -566,7 +564,6 @@ ovsdb_type_is_valid(const struct ovsdb_type *type) && ovsdb_base_type_is_valid(&type->key) && ovsdb_base_type_is_valid(&type->value) && type->n_min <= 1 - && type->n_min <= type->n_max && type->n_max >= 1); } @@ -617,7 +614,7 @@ ovsdb_type_to_english(const struct ovsdb_type *type) struct ovsdb_error * ovsdb_type_from_json(struct ovsdb_type *type, const struct json *json) { - type->value.type = OVSDB_TYPE_VOID; + ovsdb_base_type_init(&type->value, OVSDB_TYPE_VOID); type->n_min = 1; type->n_max = 1;