lyb OPTIMIZE for a fixed length plugin types

The length number is not printed/parsed.
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
index f25578b..2756bb7 100644
--- a/src/parser_lyb.c
+++ b/src/parser_lyb.c
@@ -226,6 +226,7 @@
 /**
  * @brief Read the term node.
  *
+ * @param[in] term Compiled term node.
  * @param[out] term_value Set to term node value in dynamically
  * allocated memory. The caller must release it.
  * @param[out] term_value_len Value length in bytes. The zero byte is
@@ -234,14 +235,32 @@
  * @return LY_ERR value.
  */
 static LY_ERR
-lyb_read_term(uint8_t **term_value, uint32_t *term_value_len, struct lylyb_ctx *lybctx)
+lyb_read_term(const struct lysc_node_leaf *term, uint8_t **term_value,
+        uint32_t *term_value_len, struct lylyb_ctx *lybctx)
 {
     uint32_t allocated_size;
+    int32_t lyb_data_len;
+    struct lysc_type_leafref *type_lf;
 
-    assert(term_value && term_value_len && lybctx);
+    assert(term && term_value && term_value_len && lybctx);
 
-    /* Parse value size. */
-    lyb_read_number(term_value_len, sizeof *term_value_len, sizeof *term_value_len, lybctx);
+    /*  Find out the size from @ref howtoDataLYB. */
+    if (term->type->basetype == LY_TYPE_LEAFREF) {
+        /* Leafref itself is ignored, the target is loaded directly. */
+        type_lf = (struct lysc_type_leafref *)term->type;
+        lyb_data_len = type_lf->realtype->plugin->lyb_data_len;
+    } else {
+        lyb_data_len = term->type->plugin->lyb_data_len;
+    }
+
+    if (lyb_data_len < 0) {
+        /* Parse value size. */
+        lyb_read_number(term_value_len, sizeof *term_value_len,
+                sizeof *term_value_len, lybctx);
+    } else {
+        /* Data size is fixed. */
+        *term_value_len = lyb_data_len;
+    }
 
     /* Allocate memory. */
     allocated_size = *term_value_len + 1;
@@ -882,7 +901,8 @@
         }
     } else if (snode->nodetype & LYD_NODE_TERM) {
         /* parse value */
-        ret = lyb_read_term(&term_value, &term_value_len, lybctx->lybctx);
+        ret = lyb_read_term((struct lysc_node_leaf *)snode, &term_value,
+                &term_value_len, lybctx->lybctx);
         LY_CHECK_GOTO(ret, cleanup);
         dynamic = 1;
 
diff --git a/src/plugins_types.h b/src/plugins_types.h
index 1763134..5f592e9 100644
--- a/src/plugins_types.h
+++ b/src/plugins_types.h
@@ -548,6 +548,8 @@
     lyplg_type_print_clb print;         /**< printer callback to get string representing the value */
     lyplg_type_dup_clb duplicate;       /**< data duplication callback */
     lyplg_type_free_clb free;           /**< optional function to free the type-spceific way stored value */
+    int32_t lyb_data_len;               /**< Length of the data in [LYB format](@ref howtoDataLYB).
+                                             For variable-length is set to -1. */
 };
 
 struct lyplg_type_record {
diff --git a/src/plugins_types/binary.c b/src/plugins_types/binary.c
index f8cff94..5da2fc1 100644
--- a/src/plugins_types/binary.c
+++ b/src/plugins_types/binary.c
@@ -408,6 +408,7 @@
         .plugin.print = lyplg_type_print_binary,
         .plugin.duplicate = lyplg_type_dup_binary,
         .plugin.free = lyplg_type_free_binary,
+        .plugin.lyb_data_len = -1,
     },
     {0}
 };
diff --git a/src/plugins_types/bits.c b/src/plugins_types/bits.c
index c0765c4..d065824 100644
--- a/src/plugins_types/bits.c
+++ b/src/plugins_types/bits.c
@@ -503,7 +503,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_bits,
         .plugin.duplicate = lyplg_type_dup_bits,
-        .plugin.free = lyplg_type_free_bits
+        .plugin.free = lyplg_type_free_bits,
+        .plugin.lyb_data_len = -1,
     },
     {0}
 };
diff --git a/src/plugins_types/boolean.c b/src/plugins_types/boolean.c
index 6500f0e..e16db4f 100644
--- a/src/plugins_types/boolean.c
+++ b/src/plugins_types/boolean.c
@@ -158,7 +158,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_boolean,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = 1,
     },
     {0}
 };
diff --git a/src/plugins_types/date_and_time.c b/src/plugins_types/date_and_time.c
index cbc1578..6633622 100644
--- a/src/plugins_types/date_and_time.c
+++ b/src/plugins_types/date_and_time.c
@@ -289,7 +289,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_date_and_time,
         .plugin.duplicate = lyplg_type_dup_date_and_time,
-        .plugin.free = lyplg_type_free_date_and_time
+        .plugin.free = lyplg_type_free_date_and_time,
+        .plugin.lyb_data_len = -1,
     },
     {0}
 };
diff --git a/src/plugins_types/decimal64.c b/src/plugins_types/decimal64.c
index fa8f837..a048198 100644
--- a/src/plugins_types/decimal64.c
+++ b/src/plugins_types/decimal64.c
@@ -212,7 +212,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_decimal64,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = 8,
     },
     {0}
 };
diff --git a/src/plugins_types/empty.c b/src/plugins_types/empty.c
index c45c7c9..f3b1478 100644
--- a/src/plugins_types/empty.c
+++ b/src/plugins_types/empty.c
@@ -96,7 +96,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_simple,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = 0,
     },
     {0}
 };
diff --git a/src/plugins_types/enumeration.c b/src/plugins_types/enumeration.c
index 9964ca2..77c9112 100644
--- a/src/plugins_types/enumeration.c
+++ b/src/plugins_types/enumeration.c
@@ -170,7 +170,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_enum,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = 4,
     },
     {0}
 };
diff --git a/src/plugins_types/identityref.c b/src/plugins_types/identityref.c
index 8647a5a..3a6319c 100644
--- a/src/plugins_types/identityref.c
+++ b/src/plugins_types/identityref.c
@@ -339,7 +339,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_identityref,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = -1,
     },
     {0}
 };
diff --git a/src/plugins_types/instanceid.c b/src/plugins_types/instanceid.c
index 591af8e..733405a 100644
--- a/src/plugins_types/instanceid.c
+++ b/src/plugins_types/instanceid.c
@@ -366,7 +366,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_instanceid,
         .plugin.duplicate = lyplg_type_dup_instanceid,
-        .plugin.free = lyplg_type_free_instanceid
+        .plugin.free = lyplg_type_free_instanceid,
+        .plugin.lyb_data_len = -1,
     },
     {0}
 };
diff --git a/src/plugins_types/integer.c b/src/plugins_types/integer.c
index 9239562..3acd154 100644
--- a/src/plugins_types/integer.c
+++ b/src/plugins_types/integer.c
@@ -449,7 +449,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_uint,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = 1,
     }, {
         .module = "",
         .revision = NULL,
@@ -462,7 +463,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_uint,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = 2,
     }, {
         .module = "",
         .revision = NULL,
@@ -475,7 +477,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_uint,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = 4,
     }, {
         .module = "",
         .revision = NULL,
@@ -488,7 +491,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_uint,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = 8,
     }, {
         .module = "",
         .revision = NULL,
@@ -501,7 +505,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_int,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = 1,
     }, {
         .module = "",
         .revision = NULL,
@@ -514,7 +519,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_int,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = 2,
     }, {
         .module = "",
         .revision = NULL,
@@ -527,7 +533,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_int,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = 4,
     }, {
         .module = "",
         .revision = NULL,
@@ -540,7 +547,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_int,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = 8,
     },
     {0}
 };
diff --git a/src/plugins_types/ipv4_address.c b/src/plugins_types/ipv4_address.c
index 1d3b07c..ee8cffc 100644
--- a/src/plugins_types/ipv4_address.c
+++ b/src/plugins_types/ipv4_address.c
@@ -365,7 +365,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_ipv4_address,
         .plugin.duplicate = lyplg_type_dup_ipv4_address,
-        .plugin.free = lyplg_type_free_ipv4_address
+        .plugin.free = lyplg_type_free_ipv4_address,
+        .plugin.lyb_data_len = -1,
     },
     {0}
 };
diff --git a/src/plugins_types/ipv4_address_no_zone.c b/src/plugins_types/ipv4_address_no_zone.c
index fe403e6..1e30e4f 100644
--- a/src/plugins_types/ipv4_address_no_zone.c
+++ b/src/plugins_types/ipv4_address_no_zone.c
@@ -209,7 +209,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_ipv4_address_no_zone,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = 4,
     },
     {0}
 };
diff --git a/src/plugins_types/ipv4_prefix.c b/src/plugins_types/ipv4_prefix.c
index a4738f5..8f38c3e 100644
--- a/src/plugins_types/ipv4_prefix.c
+++ b/src/plugins_types/ipv4_prefix.c
@@ -325,7 +325,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_ipv4_prefix,
         .plugin.duplicate = lyplg_type_dup_ipv4_prefix,
-        .plugin.free = lyplg_type_free_ipv4_prefix
+        .plugin.free = lyplg_type_free_ipv4_prefix,
+        .plugin.lyb_data_len = LYB_VALUE_LEN,
     },
     {0}
 };
diff --git a/src/plugins_types/ipv6_address.c b/src/plugins_types/ipv6_address.c
index 1ed2e8f..944f2f3 100644
--- a/src/plugins_types/ipv6_address.c
+++ b/src/plugins_types/ipv6_address.c
@@ -366,7 +366,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_ipv6_address,
         .plugin.duplicate = lyplg_type_dup_ipv6_address,
-        .plugin.free = lyplg_type_free_ipv6_address
+        .plugin.free = lyplg_type_free_ipv6_address,
+        .plugin.lyb_data_len = -1,
     },
     {0}
 };
diff --git a/src/plugins_types/ipv6_address_no_zone.c b/src/plugins_types/ipv6_address_no_zone.c
index b69da95..8af2581 100644
--- a/src/plugins_types/ipv6_address_no_zone.c
+++ b/src/plugins_types/ipv6_address_no_zone.c
@@ -300,7 +300,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_ipv6_address_no_zone,
         .plugin.duplicate = lyplg_type_dup_ipv6_address_no_zone,
-        .plugin.free = lyplg_type_free_ipv6_address_no_zone
+        .plugin.free = lyplg_type_free_ipv6_address_no_zone,
+        .plugin.lyb_data_len = 16,
     },
     {0}
 };
diff --git a/src/plugins_types/ipv6_prefix.c b/src/plugins_types/ipv6_prefix.c
index e864c74..0027df2 100644
--- a/src/plugins_types/ipv6_prefix.c
+++ b/src/plugins_types/ipv6_prefix.c
@@ -339,7 +339,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_ipv6_prefix,
         .plugin.duplicate = lyplg_type_dup_ipv6_prefix,
-        .plugin.free = lyplg_type_free_ipv6_prefix
+        .plugin.free = lyplg_type_free_ipv6_prefix,
+        .plugin.lyb_data_len = LYB_VALUE_LEN,
     },
     {0}
 };
diff --git a/src/plugins_types/leafref.c b/src/plugins_types/leafref.c
index 9755796..2e2d052 100644
--- a/src/plugins_types/leafref.c
+++ b/src/plugins_types/leafref.c
@@ -131,7 +131,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_leafref,
         .plugin.duplicate = lyplg_type_dup_leafref,
-        .plugin.free = lyplg_type_free_leafref
+        .plugin.free = lyplg_type_free_leafref,
+        .plugin.lyb_data_len = -1,
     },
     {0}
 };
diff --git a/src/plugins_types/node_instanceid.c b/src/plugins_types/node_instanceid.c
index fd0322c..32fb028 100644
--- a/src/plugins_types/node_instanceid.c
+++ b/src/plugins_types/node_instanceid.c
@@ -252,7 +252,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_instanceid,
         .plugin.duplicate = lyplg_type_dup_instanceid,
-        .plugin.free = lyplg_type_free_instanceid
+        .plugin.free = lyplg_type_free_instanceid,
+        .plugin.lyb_data_len = -1,
     },
     {
         .module = "ietf-netconf-acm",
@@ -266,7 +267,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_instanceid,
         .plugin.duplicate = lyplg_type_dup_instanceid,
-        .plugin.free = lyplg_type_free_instanceid
+        .plugin.free = lyplg_type_free_instanceid,
+        .plugin.lyb_data_len = -1,
     },
     {0}
 };
diff --git a/src/plugins_types/string.c b/src/plugins_types/string.c
index c127148..efebf4d 100644
--- a/src/plugins_types/string.c
+++ b/src/plugins_types/string.c
@@ -102,7 +102,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_simple,
         .plugin.duplicate = lyplg_type_dup_simple,
-        .plugin.free = lyplg_type_free_simple
+        .plugin.free = lyplg_type_free_simple,
+        .plugin.lyb_data_len = -1,
     },
     {0}
 };
diff --git a/src/plugins_types/union.c b/src/plugins_types/union.c
index f8698b8..6477189 100644
--- a/src/plugins_types/union.c
+++ b/src/plugins_types/union.c
@@ -606,7 +606,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_union,
         .plugin.duplicate = lyplg_type_dup_union,
-        .plugin.free = lyplg_type_free_union
+        .plugin.free = lyplg_type_free_union,
+        .plugin.lyb_data_len = -1,
     },
     {0}
 };
diff --git a/src/plugins_types/xpath1.0.c b/src/plugins_types/xpath1.0.c
index b98c59c..b721691 100644
--- a/src/plugins_types/xpath1.0.c
+++ b/src/plugins_types/xpath1.0.c
@@ -436,7 +436,8 @@
         .plugin.sort = NULL,
         .plugin.print = lyplg_type_print_xpath10,
         .plugin.duplicate = lyplg_type_dup_xpath10,
-        .plugin.free = lyplg_type_free_xpath10
+        .plugin.free = lyplg_type_free_xpath10,
+        .plugin.lyb_data_len = -1,
     },
     {0}
 };
diff --git a/src/printer_lyb.c b/src/printer_lyb.c
index 4023646..dade5de 100644
--- a/src/printer_lyb.c
+++ b/src/printer_lyb.c
@@ -704,30 +704,54 @@
 static LY_ERR
 lyb_print_term(struct lyd_node_term *term, struct ly_out *out, struct lylyb_ctx *lybctx)
 {
-    LY_ERR ret;
+    LY_ERR ret = LY_SUCCESS;
     ly_bool dynamic = 0;
     void *value;
     size_t value_len = 0;
+    int32_t lyb_data_len;
+    lyplg_type_print_clb print;
 
     assert(term->value.realtype && term->value.realtype->plugin && term->value.realtype->plugin->print &&
             term->schema);
 
-    value = (void *)term->value.realtype->plugin->print(term->schema->module->ctx,
-            &term->value, LY_VALUE_LYB, NULL, &dynamic, &value_len);
-    LY_CHECK_RET(!value, LY_EINT);
+    /* Get length of LYB data to print. */
+    lyb_data_len = term->value.realtype->plugin->lyb_data_len;
 
-    if (value_len > UINT32_MAX) {
-        LOGERR(lybctx->ctx, LY_EINT, "The maximum length of the LYB data "
-                "from a term node must not exceed %lu.", UINT32_MAX);
-        return LY_EINT;
+    /* Get value and also print its length only if size is not fixed. */
+    print = term->value.realtype->plugin->print;
+    if (lyb_data_len < 0) {
+        /* Variable-length data. */
+
+        /* Get value and its length from plugin. */
+        value = (void *)print(term->schema->module->ctx, &term->value,
+                LY_VALUE_LYB, NULL, &dynamic, &value_len);
+        LY_CHECK_GOTO(ret, cleanup);
+
+        if (value_len > UINT32_MAX) {
+            LOGERR(lybctx->ctx, LY_EINT, "The maximum length of the LYB data "
+                    "from a term node must not exceed %lu.", UINT32_MAX);
+            ret = LY_EINT;
+            goto cleanup;
+        }
+
+        /* Print the length of the data as 32-bit unsigned integer. */
+        ret = lyb_write_number(value_len, sizeof(uint32_t), out, lybctx);
+        LY_CHECK_GOTO(ret, cleanup);
+    } else {
+        /* Fixed-length data. */
+
+        /* Get value from plugin. */
+        value = (void *)print(term->schema->module->ctx, &term->value,
+                LY_VALUE_LYB, NULL, &dynamic, NULL);
+        LY_CHECK_GOTO(ret, cleanup);
+
+        /* Copy the length from the compiled node. */
+        value_len = lyb_data_len;
     }
 
-    /* Print the length of the data as 32-bit unsigned integer. */
-    ret = lyb_write_number(value_len, sizeof(uint32_t), out, lybctx);
-    LY_CHECK_GOTO(ret, cleanup);
-
+    /* Print value. */
     if (value_len > 0) {
-        /* Print the data simply as it is. */
+        /* Print the value simply as it is. */
         ret = lyb_write(out, value, value_len, lybctx);
         LY_CHECK_GOTO(ret, cleanup);
     }