usb: gadget: move utf8_to_utf16le to header file
authorLi Jun <jun.li@nxp.com>
Mon, 25 Jan 2021 13:43:47 +0000 (21:43 +0800)
committerMarek Vasut <marex@denx.de>
Sun, 31 Jan 2021 13:08:56 +0000 (14:08 +0100)
As other users may use utf8_to_utf16le() to convert the utf8
to utf16 for usb, so move it to head file.

Signed-off-by: Li Jun <jun.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
drivers/usb/gadget/usbstring.c
include/linux/utf.h [new file with mode: 0644]

index 83cdd8a2595e1c92aafbd5df6e404845abcf64f3..e2464ad923f8cffc0cc91ef085920bd017c4e0e8 100644 (file)
 #include <linux/errno.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
-
-#include <asm/unaligned.h>
-
-
-static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len)
-{
-       int     count = 0;
-       u8      c;
-       u16     uchar;
-
-       /*
-        * this insists on correct encodings, though not minimal ones.
-        * BUT it currently rejects legit 4-byte UTF-8 code points,
-        * which need surrogate pairs.  (Unicode 3.1 can use them.)
-        */
-       while (len != 0 && (c = (u8) *s++) != 0) {
-               if ((c & 0x80)) {
-                       /*
-                        * 2-byte sequence:
-                        * 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
-                        */
-                       if ((c & 0xe0) == 0xc0) {
-                               uchar = (c & 0x1f) << 6;
-
-                               c = (u8) *s++;
-                               if ((c & 0xc0) != 0x80)
-                                       goto fail;
-                               c &= 0x3f;
-                               uchar |= c;
-
-                       /*
-                        * 3-byte sequence (most CJKV characters):
-                        * zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
-                        */
-                       } else if ((c & 0xf0) == 0xe0) {
-                               uchar = (c & 0x0f) << 12;
-
-                               c = (u8) *s++;
-                               if ((c & 0xc0) != 0x80)
-                                       goto fail;
-                               c &= 0x3f;
-                               uchar |= c << 6;
-
-                               c = (u8) *s++;
-                               if ((c & 0xc0) != 0x80)
-                                       goto fail;
-                               c &= 0x3f;
-                               uchar |= c;
-
-                               /* no bogus surrogates */
-                               if (0xd800 <= uchar && uchar <= 0xdfff)
-                                       goto fail;
-
-                       /*
-                        * 4-byte sequence (surrogate pairs, currently rare):
-                        * 11101110wwwwzzzzyy + 110111yyyyxxxxxx
-                        *     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-                        * (uuuuu = wwww + 1)
-                        * FIXME accept the surrogate code points (only)
-                        */
-                       } else
-                               goto fail;
-               } else
-                       uchar = c;
-               put_unaligned_le16(uchar, cp++);
-               count++;
-               len--;
-       }
-       return count;
-fail:
-       return -1;
-}
-
+#include <linux/utf.h>
 
 /**
  * usb_gadget_get_string - fill out a string descriptor
diff --git a/include/linux/utf.h b/include/linux/utf.h
new file mode 100644 (file)
index 0000000..e1f7d3b
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef _LINUX_UTF_H
+#define _LINUX_UTF_H
+
+#include <asm/unaligned.h>
+
+static inline int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len)
+{
+       int     count = 0;
+       u8      c;
+       u16     uchar;
+
+       /*
+        * this insists on correct encodings, though not minimal ones.
+        * BUT it currently rejects legit 4-byte UTF-8 code points,
+        * which need surrogate pairs.  (Unicode 3.1 can use them.)
+        */
+       while (len != 0 && (c = (u8) *s++) != 0) {
+               if ((c & 0x80)) {
+                       /*
+                        * 2-byte sequence:
+                        * 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
+                        */
+                       if ((c & 0xe0) == 0xc0) {
+                               uchar = (c & 0x1f) << 6;
+
+                               c = (u8) *s++;
+                               if ((c & 0xc0) != 0x80)
+                                       goto fail;
+                               c &= 0x3f;
+                               uchar |= c;
+
+                       /*
+                        * 3-byte sequence (most CJKV characters):
+                        * zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
+                        */
+                       } else if ((c & 0xf0) == 0xe0) {
+                               uchar = (c & 0x0f) << 12;
+
+                               c = (u8) *s++;
+                               if ((c & 0xc0) != 0x80)
+                                       goto fail;
+                               c &= 0x3f;
+                               uchar |= c << 6;
+
+                               c = (u8) *s++;
+                               if ((c & 0xc0) != 0x80)
+                                       goto fail;
+                               c &= 0x3f;
+                               uchar |= c;
+
+                               /* no bogus surrogates */
+                               if (0xd800 <= uchar && uchar <= 0xdfff)
+                                       goto fail;
+
+                       /*
+                        * 4-byte sequence (surrogate pairs, currently rare):
+                        * 11101110wwwwzzzzyy + 110111yyyyxxxxxx
+                        *     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
+                        * (uuuuu = wwww + 1)
+                        * FIXME accept the surrogate code points (only)
+                        */
+                       } else
+                               goto fail;
+               } else
+                       uchar = c;
+               put_unaligned_le16(uchar, cp++);
+               count++;
+               len--;
+       }
+       return count;
+fail:
+       return -1;
+}
+
+#endif /* _LINUX_UTF_H */