Imported Upstream version 0.5.4
[debian/efibootmgr] / src / lib / efichar.c
1 /*
2   efichar.[ch]
3
4   Copyright (C) 2001 Dell Computer Corporation <Matt_Domsch@dell.com>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20   Best as I can tell, efi_char16_t characters are unicode characters,
21   but are encoded in little-endian UCS-2
22         http://www.cl.cam.ac.uk/~mgk25/unicode.html.
23   libunicode expects characters to be encoded in UTF-8, so I can't use that.
24   Therefore, we need a UCS-2 library.
25 */
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include "efi.h"
30 #include "efichar.h"
31
32 int
33 efichar_char_strcmp(const char *s1, const efi_char16_t *s2)
34 {
35         int i, rc;
36         char *buffer;
37         int s2_len = efichar_strlen(s2, -1);
38
39         buffer = malloc(s2_len+1);
40         if (!buffer) return -1;
41         memset(buffer, 0, s2_len+1);
42
43         for (i=0; i<(s2_len); i++) {
44                 buffer[i] = s2[i] & 0xFF;
45         }
46         buffer[i] = '\0';
47         rc = strcmp(s1, buffer);
48         free(buffer);
49         return rc;
50 }
51
52 int
53 efichar_strcmp(const efi_char16_t *s1, const efi_char16_t *s2)
54 {
55         int i;
56         int s1_len = efichar_strlen(s1, -1);
57         int s2_len = efichar_strlen(s2, -1);
58
59
60         for (i=0; i < s1_len && i < s2_len; i++) {
61                 if (s1[i] < s2[i]) return -1;
62                 if (s1[i] > s2[i]) return 1;
63
64         }
65         /* Hit the end of one string */
66         if (i == s1_len && i != s2_len) return -1;
67         if (i != s1_len && i == s2_len) return  1;
68         return 0;
69 }
70
71 unsigned long
72 efichar_from_char(efi_char16_t *dest, const char *src, size_t dest_len)
73 {
74         int i, src_len = strlen(src);
75         for (i=0; i < src_len && i < (dest_len/sizeof(*dest)) - 1; i++) {
76                 dest[i] = src[i];
77         }
78         dest[i] = 0;
79         return i * sizeof(*dest);
80 }
81
82 unsigned long
83 efichar_to_char(char *dest, const efi_char16_t *src, size_t dest_len)
84 {
85         int i, src_len = efichar_strlen(src, -1);
86         for (i=0; i < src_len && i < (dest_len/sizeof(*dest)) - 1; i++) {
87                 dest[i] = src[i];
88         }
89         dest[i] = 0;
90         return i;
91 }
92
93 int
94 efichar_strlen(const efi_char16_t *p, int max)
95 {
96         int len=0;
97         const efi_char16_t *start = p;
98
99         if (!p || !*p)   return 0;
100
101         while ((max < 0 || p - start < max) && *(p+len))
102         {
103                 ++len;
104         }
105         return len;
106 }
107
108 #ifndef MIN
109 #define MIN(a, b)  (((a) < (b)) ? (a) : (b))
110 #endif
111
112 int
113 efichar_strncpy(efi_char16_t *dest, const efi_char16_t *src, int max)
114 {
115         int i;
116         int src_len = efichar_strlen(src, max);
117
118         for (i=0; i < MIN(max,src_len); i++)
119         {
120                 dest[i] = src[i];
121         }
122         dest[i] = 0;
123         return i;
124 }
125
126 int
127 efichar_strsize(const efi_char16_t *p)
128 {
129         return (efichar_strlen(p, -1) + 1) * sizeof(efi_char16_t);
130 }