data FEATURE generic JSON format parser
diff --git a/src/common.c b/src/common.c
index b1ccd65..7a8d83a 100644
--- a/src/common.c
+++ b/src/common.c
@@ -265,6 +265,59 @@
     return LY_SUCCESS;
 }
 
+LY_ERR
+ly_pututf8(char *dst, uint32_t value, size_t *bytes_written)
+{
+    if (value < 0x80) {
+        /* one byte character */
+        if (value < 0x20 &&
+                value != 0x09 &&
+                value != 0x0a &&
+                value != 0x0d) {
+            return LY_EINVAL;
+        }
+
+        dst[0] = value;
+        (*bytes_written) = 1;
+    } else if (value < 0x800) {
+        /* two bytes character */
+        dst[0] = 0xc0 | (value >> 6);
+        dst[1] = 0x80 | (value & 0x3f);
+        (*bytes_written) = 2;
+    } else if (value < 0xfffe) {
+        /* three bytes character */
+        if (((value & 0xf800) == 0xd800) ||
+                (value >= 0xfdd0 && value <= 0xfdef)) {
+            /* exclude surrogate blocks %xD800-DFFF */
+            /* exclude noncharacters %xFDD0-FDEF */
+            return LY_EINVAL;
+        }
+
+        dst[0] = 0xe0 | (value >> 12);
+        dst[1] = 0x80 | ((value >> 6) & 0x3f);
+        dst[2] = 0x80 | (value & 0x3f);
+
+        (*bytes_written) = 3;
+    } else if (value < 0x10fffe) {
+        if ((value & 0xffe) == 0xffe) {
+            /* exclude noncharacters %xFFFE-FFFF, %x1FFFE-1FFFF, %x2FFFE-2FFFF, %x3FFFE-3FFFF, %x4FFFE-4FFFF,
+             * %x5FFFE-5FFFF, %x6FFFE-6FFFF, %x7FFFE-7FFFF, %x8FFFE-8FFFF, %x9FFFE-9FFFF, %xAFFFE-AFFFF,
+             * %xBFFFE-BFFFF, %xCFFFE-CFFFF, %xDFFFE-DFFFF, %xEFFFE-EFFFF, %xFFFFE-FFFFF, %x10FFFE-10FFFF */
+            return LY_EINVAL;
+        }
+        /* four bytes character */
+        dst[0] = 0xf0 | (value >> 18);
+        dst[1] = 0x80 | ((value >> 12) & 0x3f);
+        dst[2] = 0x80 | ((value >> 6) & 0x3f);
+        dst[3] = 0x80 | (value & 0x3f);
+
+        (*bytes_written) = 4;
+    } else {
+        return LY_EINVAL;
+    }
+    return LY_SUCCESS;
+}
+
 /**
  * @brief Static table of the UTF8 characters lengths according to their first byte.
  */