lyb OPTIMIZE read/write numbers
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
index a664415..862ab06 100644
--- a/src/parser_lyb.c
+++ b/src/parser_lyb.c
@@ -93,15 +93,13 @@
 }
 
 static int
-lyb_read_number(uint64_t *num, uint64_t max_num, const char *data, struct lyb_state *lybs)
+lyb_read_number(uint64_t *num, size_t bytes, const char *data, struct lyb_state *lybs)
 {
-    int max_bits, max_bytes, i, r, ret = 0;
+    int r, ret = 0;
+    size_t i;
     uint8_t byte;
 
-    for (max_bits = 0; max_num; max_num >>= 1, ++max_bits);
-    max_bytes = max_bits / 8 + (max_bits % 8 ? 1 : 0);
-
-    for (i = 0; i < max_bytes; ++i) {
+    for (i = 0; i < bytes; ++i) {
         ret += (r = lyb_read(data, &byte, 1, lybs));
         LYB_HAVE_READ_RETURN(r, data, -1);
 
@@ -112,6 +110,24 @@
 }
 
 static int
+lyb_read_enum(uint64_t *enum_idx, uint32_t count, const char *data, struct lyb_state *lybs)
+{
+    size_t bytes;
+
+    if (count < (2 << 8)) {
+        bytes = 1;
+    } else if (count < (2 << 16)) {
+        bytes = 2;
+    } else if (count < (2 << 24)) {
+        bytes = 3;
+    } else {
+        bytes = 4;
+    }
+
+    return lyb_read_number(enum_idx, bytes, data, lybs);
+}
+
+static int
 lyb_read_string(const char *data, char **str, int with_length, struct lyb_state *lybs)
 {
     int next_chunk = 0, r, ret = 0;
@@ -382,7 +398,7 @@
         for (; !type->info.enums.count; type = &type->der->type);
 
         num = 0;
-        ret = lyb_read_number(&num, type->info.enums.count, data, lybs);
+        ret = lyb_read_enum(&num, type->info.enums.count, data, lybs);
         if (ret > 0) {
             assert(num < type->info.enums.count);
             value->enm = &type->info.enums.enm[num];
@@ -390,20 +406,20 @@
         break;
     case LY_TYPE_INT8:
     case LY_TYPE_UINT8:
-        ret = lyb_read_number((uint64_t *)&value->uint8, UINT8_MAX, data, lybs);
+        ret = lyb_read_number((uint64_t *)&value->uint8, 1, data, lybs);
         break;
     case LY_TYPE_INT16:
     case LY_TYPE_UINT16:
-        ret = lyb_read_number((uint64_t *)&value->uint16, UINT16_MAX, data, lybs);
+        ret = lyb_read_number((uint64_t *)&value->uint16, 2, data, lybs);
         break;
     case LY_TYPE_INT32:
     case LY_TYPE_UINT32:
-        ret = lyb_read_number((uint64_t *)&value->uint32, UINT32_MAX, data, lybs);
+        ret = lyb_read_number((uint64_t *)&value->uint32, 4, data, lybs);
         break;
     case LY_TYPE_DEC64:
     case LY_TYPE_INT64:
     case LY_TYPE_UINT64:
-        ret = lyb_read_number((uint64_t *)&value->uint64, UINT64_MAX, data, lybs);
+        ret = lyb_read_number((uint64_t *)&value->uint64, 8, data, lybs);
         break;
     default:
         return -1;
@@ -959,7 +975,7 @@
 
 #ifdef LY_ENABLED_CACHE
     if (lybs->data_options & LYP_WITHHASH) {
-        ret += (r = lyb_read_number((uint64_t *)&node->hash, UINT32_MAX, data, lybs));
+        ret += (r = lyb_read_number((uint64_t *)&node->hash, 4, data, lybs));
         LYB_HAVE_READ_GOTO(r, data, error);
     }
 #endif