libfstools: fit: improve fit_volume_find string handling
[project/fstools.git] / libblkid-tiny / encode.c
1 /*
2 * encode.c - string conversion routines (mostly for compatibility with
3 * udev/volume_id)
4 *
5 * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org>
6 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
7 *
8 * This file may be redistributed under the terms of the
9 * GNU Lesser General Public License.
10 */
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stdint.h>
14 #include <stddef.h>
15 #include <unistd.h>
16 #include <errno.h>
17 #include <string.h>
18 #include <ctype.h>
19
20 #include "encode.h"
21
22 size_t blkid_encode_to_utf8(int enc, unsigned char *dest, size_t len,
23 const unsigned char *src, size_t count)
24 {
25 size_t i, j;
26 uint16_t c;
27
28 for (j = i = 0; i < count; i++) {
29 if (enc == BLKID_ENC_UTF16LE) {
30 if (i+2 > count)
31 break;
32 c = (src[i+1] << 8) | src[i];
33 i++;
34 } else if (enc == BLKID_ENC_UTF16BE) {
35 if (i+2 > count)
36 break;
37 c = (src[i] << 8) | src[i+1];
38 i++;
39 } else if (enc == BLKID_ENC_LATIN1) {
40 c = src[i];
41 } else {
42 return 0;
43 }
44 if (c == 0) {
45 dest[j] = '\0';
46 break;
47 } else if (c < 0x80) {
48 if (j+1 >= len)
49 break;
50 dest[j++] = (uint8_t) c;
51 } else if (c < 0x800) {
52 if (j+2 >= len)
53 break;
54 dest[j++] = (uint8_t) (0xc0 | (c >> 6));
55 dest[j++] = (uint8_t) (0x80 | (c & 0x3f));
56 } else {
57 if (j+3 >= len)
58 break;
59 dest[j++] = (uint8_t) (0xe0 | (c >> 12));
60 dest[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f));
61 dest[j++] = (uint8_t) (0x80 | (c & 0x3f));
62 }
63 }
64 dest[j] = '\0';
65 return j;
66 }