summaryrefslogtreecommitdiffstats
path: root/src/libknot/yparser/ypschema.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libknot/yparser/ypschema.h')
-rw-r--r--src/libknot/yparser/ypschema.h352
1 files changed, 352 insertions, 0 deletions
diff --git a/src/libknot/yparser/ypschema.h b/src/libknot/yparser/ypschema.h
new file mode 100644
index 0000000..91e5165
--- /dev/null
+++ b/src/libknot/yparser/ypschema.h
@@ -0,0 +1,352 @@
+/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/*!
+ * \file
+ *
+ * \brief Schema layer for Yparser.
+ *
+ * \addtogroup yparser
+ * @{
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "libknot/yparser/yparser.h"
+#include "libknot/lookup.h"
+
+struct wire_ctx;
+
+/*! Maximal length of item name. */
+#define YP_MAX_ITEM_NAME_LEN 64
+/*! Maximal length of binary identifier name (maximal dname length). */
+#define YP_MAX_ID_LEN 255
+/*! Maximal length of binary data (rough limit). */
+#define YP_MAX_DATA_LEN 32768
+/*! Integer item nil definition. */
+#define YP_NIL INT64_MIN
+/*! Maximal number of miscellaneous callbacks/pointers. */
+#define YP_MAX_MISC_COUNT 4
+/*! Maximal node stack depth. */
+#define YP_MAX_NODE_DEPTH 2
+
+#define YP_TXT_BIN_PARAMS struct wire_ctx *in, struct wire_ctx *out, const uint8_t *stop
+#define YP_BIN_TXT_PARAMS struct wire_ctx *in, struct wire_ctx *out
+
+/*! Helper macros for item variables definition. */
+#define YP_VNONE .var.i = { 0 }
+#define YP_VINT .var.i
+#define YP_VBOOL .var.b
+#define YP_VOPT .var.o
+#define YP_VSTR .var.s
+#define YP_VADDR .var.a
+#define YP_VNET .var.d
+#define YP_VDNAME .var.d
+#define YP_VHEX .var.d
+#define YP_VB64 .var.d
+#define YP_VDATA .var.d
+#define YP_VREF .var.r
+#define YP_VGRP .var.g
+
+/*! Schema item name is a char string with a leading byte (string length). */
+typedef char yp_name_t;
+
+/*! Schema item type. */
+typedef enum {
+ YP_TNONE = 0, /*!< Unspecified. */
+ YP_TINT, /*!< Integer. */
+ YP_TBOOL, /*!< Boolean. */
+ YP_TOPT, /*!< Option from the list. */
+ YP_TSTR, /*!< String. */
+ YP_THEX, /*!< String or hexadecimal string if "0x" prefix. */
+ YP_TADDR, /*!< Address (address[\@port] or UNIX socket path). */
+ YP_TNET, /*!< Network address range (address[/mask] or address-address). */
+ YP_TDNAME, /*!< Domain name. */
+ YP_TB64, /*!< Base64 encoded string. */
+ YP_TDATA, /*!< Customized data. */
+ YP_TREF, /*!< Reference to another item. */
+ YP_TGRP, /*!< Group of sub-items. */
+} yp_type_t;
+
+/*! Schema item flags. */
+typedef enum {
+ YP_FNONE = 0, /*!< Unspecified. */
+ YP_FMULTI = 1 << 0, /*!< Multivalued item. */
+ YP_FALLOC = 1 << 1, /*!< Allocated item. */
+ YP_FUSR1 = 1 << 5, /*!< User-defined flag1. */
+ YP_FUSR2 = 1 << 6, /*!< User-defined flag2. */
+ YP_FUSR3 = 1 << 7, /*!< User-defined flag3. */
+ YP_FUSR4 = 1 << 8, /*!< User-defined flag4. */
+ YP_FUSR5 = 1 << 9, /*!< User-defined flag5. */
+ YP_FUSR6 = 1 << 10, /*!< User-defined flag6. */
+ YP_FUSR7 = 1 << 11, /*!< User-defined flag7. */
+ YP_FUSR8 = 1 << 12, /*!< User-defined flag8. */
+ YP_FUSR9 = 1 << 13, /*!< User-defined flag9. */
+ YP_FUSR10 = 1 << 14, /*!< User-defined flag10. */
+ YP_FUSR11 = 1 << 15, /*!< User-defined flag11. */
+ YP_FUSR12 = 1 << 16, /*!< User-defined flag12. */
+ YP_FUSR13 = 1 << 17, /*!< User-defined flag13. */
+ YP_FUSR14 = 1 << 18, /*!< User-defined flag14. */
+ YP_FUSR15 = 1 << 19, /*!< User-defined flag15. */
+ YP_FUSR16 = 1 << 20, /*!< User-defined flag16. */
+} yp_flag_t;
+
+/*! Schema item style. */
+typedef enum {
+ YP_SNONE = 0, /*!< Unspecified. */
+ YP_SSIZE = 1 << 0, /*!< Size unit (B, K, M, G) (in, out). */
+ YP_STIME = 1 << 1, /*!< Time unit (s, m, h, d) (in, out). */
+ YP_SUNIT = YP_SSIZE | YP_STIME, /*!< Unit (in, out). */
+ YP_SNOQUOTE = 1 << 2 /*!< Unquoted value (out). */
+} yp_style_t;
+
+typedef struct yp_item yp_item_t;
+
+/*! Schema item variables (type dependent). */
+typedef union {
+ /*! Integer variables. */
+ struct {
+ /*! Minimal value. */
+ int64_t min;
+ /*! Maximal value. */
+ int64_t max;
+ /*! Default value. */
+ int64_t dflt;
+ /*! Possible unit type. */
+ yp_style_t unit;
+ } i;
+ /*! Boolean variables. */
+ struct {
+ /*! Default value. */
+ bool dflt;
+ } b;
+ /*! Option variables. */
+ struct {
+ /*! List of options (maximal value is 255). */
+ struct knot_lookup const *opts;
+ /*! Default value. */
+ unsigned dflt;
+ } o;
+ /*! String variables. */
+ struct {
+ /*! Default value. */
+ char const *dflt;
+ } s;
+ /*! Address variables. */
+ struct {
+ /*! Default port. */
+ uint16_t dflt_port;
+ /*! Default socket. */
+ char const *dflt_socket;
+ } a;
+ /*! Customized data variables. */
+ struct {
+ /*! Length of default data. */
+ size_t dflt_len;
+ /*! Default data. */
+ uint8_t const *dflt;
+ /*! Text to binary transformation function. */
+ int (*to_bin)(YP_TXT_BIN_PARAMS);
+ /*! Binary to text transformation function. */
+ int (*to_txt)(YP_BIN_TXT_PARAMS);
+ } d;
+ /*! Reference variables. */
+ struct {
+ /*! Referenced section name. */
+ yp_name_t const *ref_name;
+ /*! Referenced group section name (optional). */
+ yp_name_t const *grp_ref_name;
+ /*! Referenced section item (dynamic value). */
+ yp_item_t const *ref;
+ /*! Referenced group section item (dynamic value). */
+ yp_item_t const *grp_ref;
+ } r;
+ /*! Group variables. */
+ struct {
+ /*! List of sub-items. */
+ yp_item_t const *sub_items;
+ /*! ID item of sub-items (dynamic value). */
+ yp_item_t const *id;
+ } g;
+} yp_var_t;
+
+/*! Schema item specification. */
+struct yp_item {
+ /*! Item name. */
+ const yp_name_t *name;
+ /*! Item type. */
+ yp_type_t type;
+ /*! Item parameters. */
+ yp_var_t var;
+ /*! Item flags. */
+ yp_flag_t flags;
+ /*! Arbitrary data/callbacks. */
+ const void *misc[YP_MAX_MISC_COUNT];
+ /*! Parent item. */
+ yp_item_t *parent;
+ /*! Item group subitems (name=NULL terminated array). */
+ yp_item_t *sub_items;
+};
+
+typedef struct yp_node yp_node_t;
+struct yp_node {
+ /*! Parent node. */
+ yp_node_t *parent;
+ /*! Node item descriptor. */
+ const yp_item_t *item;
+ /*! Current binary id length. */
+ size_t id_len;
+ /*! Current binary id. */
+ uint8_t id[YP_MAX_ID_LEN];
+ /*! Current item data length. */
+ size_t data_len;
+ /*! Current item data. */
+ uint8_t data[YP_MAX_DATA_LEN];
+};
+
+/*! Context parameters for check operations. */
+typedef struct {
+ /*! Used schema. */
+ yp_item_t **schema;
+ /*! Index of the current node. */
+ size_t current;
+ /*! Node stack. */
+ yp_node_t nodes[YP_MAX_NODE_DEPTH];
+} yp_check_ctx_t;
+
+/*!
+ * Copies the schema and reinitializes dynamic parameters.
+ *
+ * \param[out] dst New copy of the schema.
+ * \param[in] src Source schema.
+ *
+ * \return Error code, KNOT_EOK if success.
+ */
+int yp_schema_copy(
+ yp_item_t **dst,
+ const yp_item_t *src
+);
+
+/*!
+ * Merges two schemas.
+ *
+ * \param[out] dst Merged schema.
+ * \param[in] src1 Source schema1.
+ * \param[in] src2 Source schema2.
+ *
+ * \return Error code, KNOT_EOK if success.
+ */
+int yp_schema_merge(
+ yp_item_t **dst,
+ const yp_item_t *src1,
+ const yp_item_t *src2
+);
+
+/*!
+ * Purges dynamic items from the schema.
+ *
+ * \param[in] schema Schema to purge.
+ */
+void yp_schema_purge_dynamic(
+ yp_item_t *schema
+);
+
+/*!
+ * Deallocates the schema.
+ *
+ * \param[in] schema A schema returned by #yp_schema_copy().
+ */
+void yp_schema_free(
+ yp_item_t *schema
+);
+
+/*!
+ * Tries to find given parent_name/name in the schema.
+ *
+ * \param[in] name Name of the item.
+ * \param[in] parent_name Name of the parent item (NULL if no parent).
+ * \param[in] schema Schema.
+ *
+ * \return Item, NULL if not found or error.
+ */
+const yp_item_t* yp_schema_find(
+ const yp_name_t *name,
+ const yp_name_t *parent_name,
+ const yp_item_t *schema
+);
+
+/*!
+ * Prepares a context for item check against the schema.
+ *
+ * \param[in] schema Schema.
+ *
+ * \return Context, NULL if error.
+ */
+yp_check_ctx_t* yp_schema_check_init(
+ yp_item_t **schema
+);
+
+/*!
+ * Checks the current parser output against the schema.
+ *
+ * If the item is correct, context also contains binary value of the item.
+ *
+ * \param[in,out] ctx Check context.
+ * \param[in] parser Parser context.
+ *
+ * \return Error code, KNOT_EOK if success.
+ */
+int yp_schema_check_parser(
+ yp_check_ctx_t *ctx,
+ const yp_parser_t *parser
+);
+
+/*!
+ * Checks the string data against the schema.
+ *
+ * Description: key0[id].key1 data
+ *
+ * If the item is correct, context also contains binary value of the item.
+ *
+ * \param[in,out] ctx Check context.
+ * \param[in] key0 Key0 item name.
+ * \param[in] key1 Key1 item name.
+ * \param[in] id Item identifier.
+ * \param[in] data Item data (NULL means no data provided).
+ *
+ * \return Error code, KNOT_EOK if success.
+ */
+int yp_schema_check_str(
+ yp_check_ctx_t *ctx,
+ const char *key0,
+ const char *key1,
+ const char *id,
+ const char *data
+);
+
+/*!
+ * Deallocates the context.
+ *
+ * \param[in,out] ctx Check context.
+ */
+void yp_schema_check_deinit(
+ yp_check_ctx_t *ctx
+);
+
+/*! @} */