OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [ntfs/] [util.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * util.c -  Miscellaneous support
3
 *
4
 * Copyright (C) 1997,1999 Martin von Löwis
5
 * Copyright (C) 1997 Régis Duchesne
6
 * Copyright (C) 2001 Anton Altaparmakov (AIA)
7
 *
8
 * The utf8 routines are copied from Python wstrop module.
9
 */
10
 
11
#include "ntfstypes.h"
12
#include "struct.h"
13
#include "util.h"
14
#include <linux/string.h>
15
#include <linux/errno.h>
16
#include <asm/div64.h>          /* For do_div(). */
17
#include "support.h"
18
 
19
/*
20
 * Converts a single wide character to a sequence of utf8 bytes.
21
 * The character is represented in host byte order.
22
 * Returns the number of bytes, or 0 on error.
23
 */
24
static int to_utf8(ntfs_u16 c, unsigned char *buf)
25
{
26
        if (c == 0)
27
                return 0; /* No support for embedded 0 runes. */
28
        if (c < 0x80) {
29
                if (buf)
30
                        buf[0] = (unsigned char)c;
31
                return 1;
32
        }
33
        if (c < 0x800) {
34
                if (buf) {
35
                        buf[0] = 0xc0 | (c >> 6);
36
                        buf[1] = 0x80 | (c & 0x3f);
37
                }
38
                return 2;
39
        }
40
        /* c < 0x10000 */
41
        if (buf) {
42
                buf[0] = 0xe0 | (c >> 12);
43
                buf[1] = 0x80 | ((c >> 6) & 0x3f);
44
                buf[2] = 0x80 | (c & 0x3f);
45
        }
46
        return 3;
47
}
48
 
49
/*
50
 * Decodes a sequence of utf8 bytes into a single wide character.
51
 * The character is returned in host byte order.
52
 * Returns the number of bytes consumed, or 0 on error.
53
 */
54
static int from_utf8(const unsigned char *str, ntfs_u16 *c)
55
{
56
        int l = 0, i;
57
 
58
        if (*str < 0x80) {
59
                *c = *str;
60
                return 1;
61
        }
62
        if (*str < 0xc0)        /* Lead byte must not be 10xxxxxx. */
63
                return 0;        /* Is c0 a possible lead byte? */
64
        if (*str < 0xe0) {              /* 110xxxxx */
65
                *c = *str & 0x1f;
66
                l = 2;
67
        } else if (*str < 0xf0) {       /* 1110xxxx */
68
                *c = *str & 0xf;
69
                l = 3;
70
        } else if (*str < 0xf8) {       /* 11110xxx */
71
                *c = *str & 7;
72
                l = 4;
73
        } else /* We don't support characters above 0xFFFF in NTFS. */
74
                return 0;
75
        for (i = 1; i < l; i++) {
76
                /* All other bytes must be 10xxxxxx. */
77
                if ((str[i] & 0xc0) != 0x80)
78
                        return 0;
79
                *c <<= 6;
80
                *c |= str[i] & 0x3f;
81
        }
82
        return l;
83
}
84
 
85
/*
86
 * Converts wide string to UTF-8. Expects two in- and two out-parameters.
87
 * Returns 0 on success, or error code.
88
 * The caller has to free the result string.
89
 */
90
static int ntfs_dupuni2utf8(ntfs_u16 *in, int in_len, char **out, int *out_len)
91
{
92
        int i, tmp;
93
        int len8;
94
        unsigned char *result;
95
 
96
        ntfs_debug(DEBUG_NAME1, "converting l = %d\n", in_len);
97
        /* Count the length of the resulting UTF-8. */
98
        for (i = len8 = 0; i < in_len; i++) {
99
                tmp = to_utf8(NTFS_GETU16(in + i), 0);
100
                if (!tmp)
101
                        /* Invalid character. */
102
                        return -EILSEQ;
103
                len8 += tmp;
104
        }
105
        *out = result = ntfs_malloc(len8 + 1); /* allow for zero-termination */
106
        if (!result)
107
                return -ENOMEM;
108
        result[len8] = '\0';
109
        *out_len = len8;
110
        for (i = len8 = 0; i < in_len; i++)
111
                len8 += to_utf8(NTFS_GETU16(in + i), result + len8);
112
        ntfs_debug(DEBUG_NAME1, "result %p:%s\n", result, result);
113
        return 0;
114
}
115
 
116
/*
117
 * Converts an UTF-8 sequence to a wide string. Same conventions as the
118
 * previous function.
119
 */
120
static int ntfs_duputf82uni(unsigned char* in, int in_len, ntfs_u16** out,
121
                int *out_len)
122
{
123
        int i, tmp;
124
        int len16;
125
        ntfs_u16* result;
126
        ntfs_u16 wtmp;
127
 
128
        for (i = len16 = 0; i < in_len; i += tmp, len16++) {
129
                tmp = from_utf8(in + i, &wtmp);
130
                if (!tmp)
131
                        return -EILSEQ;
132
        }
133
        *out = result = ntfs_malloc(2 * (len16 + 1));
134
        if (!result)
135
                return -ENOMEM;
136
        result[len16] = 0;
137
        *out_len = len16;
138
        for (i = len16 = 0; i < in_len; i += tmp, len16++) {
139
                tmp = from_utf8(in + i, &wtmp);
140
                NTFS_PUTU16(result + len16, wtmp);
141
        }
142
        return 0;
143
}
144
 
145
/* Encodings dispatchers. */
146
int ntfs_encodeuni(ntfs_volume *vol, ntfs_u16 *in, int in_len, char **out,
147
                int *out_len)
148
{
149
        if (vol->nls_map)
150
                return ntfs_dupuni2map(vol, in, in_len, out, out_len);
151
        else
152
                return ntfs_dupuni2utf8(in, in_len, out, out_len);
153
}
154
 
155
int ntfs_decodeuni(ntfs_volume *vol, char *in, int in_len, ntfs_u16 **out,
156
                int *out_len)
157
{
158
        if (vol->nls_map)
159
                return ntfs_dupmap2uni(vol, in, in_len, out, out_len);
160
        else
161
                return ntfs_duputf82uni(in, in_len, out, out_len);
162
}
163
 
164
/* Same address space copies. */
165
void ntfs_put(ntfs_io *dest, void *src, ntfs_size_t n)
166
{
167
        ntfs_memcpy(dest->param, src, n);
168
        ((char*)dest->param) += n;
169
}
170
 
171
void ntfs_get(void* dest, ntfs_io *src, ntfs_size_t n)
172
{
173
        ntfs_memcpy(dest, src->param, n);
174
        ((char*)src->param) += n;
175
}
176
 
177
void *ntfs_calloc(int size)
178
{
179
        void *result = ntfs_malloc(size);
180
        if (result)
181
                ntfs_bzero(result, size);
182
        return result;
183
}
184
 
185
/* Copy len ascii characters from from to to. :) */
186
void ntfs_ascii2uni(short int *to, char *from, int len)
187
{
188
        int i;
189
 
190
        for (i = 0; i < len; i++)
191
                NTFS_PUTU16(to + i, from[i]);
192
        to[i] = 0;
193
}
194
 
195
/* strncmp for Unicode strings. */
196
int ntfs_uni_strncmp(short int* a, short int *b, int n)
197
{
198
        int i;
199
 
200
        for(i = 0; i < n; i++)
201
        {
202
                if (NTFS_GETU16(a + i) < NTFS_GETU16(b + i))
203
                        return -1;
204
                if (NTFS_GETU16(b + i) < NTFS_GETU16(a + i))
205
                        return 1;
206
                if (NTFS_GETU16(a + i) == 0)
207
                        break;
208
        }
209
        return 0;
210
}
211
 
212
/* strncmp between Unicode and ASCII strings. */
213
int ntfs_ua_strncmp(short int* a, char* b, int n)
214
{
215
        int i;
216
 
217
        for (i = 0; i < n; i++)  {
218
                if(NTFS_GETU16(a + i) < b[i])
219
                        return -1;
220
                if(b[i] < NTFS_GETU16(a + i))
221
                        return 1;
222
                if (b[i] == 0)
223
                        return 0;
224
        }
225
        return 0;
226
}
227
 
228
#define NTFS_TIME_OFFSET ((ntfs_time64_t)(369*365 + 89) * 24 * 3600 * 10000000)
229
 
230
/* Convert the NT UTC (based 1.1.1601, in hundred nanosecond units)
231
 * into Unix UTC (based 1.1.1970, in seconds). */
232
ntfs_time_t ntfs_ntutc2unixutc(ntfs_time64_t ntutc)
233
{
234
        /* Subtract the NTFS time offset, then convert to 1s intervals. */
235
        ntfs_time64_t t = ntutc - NTFS_TIME_OFFSET;
236
        do_div(t, 10000000);
237
        return (ntfs_time_t)t;
238
}
239
 
240
/* Convert the Unix UTC into NT UTC. */
241
ntfs_time64_t ntfs_unixutc2ntutc(ntfs_time_t t)
242
{
243
        /* Convert to 100ns intervals and then add the NTFS time offset. */
244
        return (ntfs_time64_t)t * 10000000 + NTFS_TIME_OFFSET;
245
}
246
 
247
#undef NTFS_TIME_OFFSET
248
 
249
/* Fill index name. */
250
void ntfs_indexname(char *buf, int type)
251
{
252
        char hex[] = "0123456789ABCDEF";
253
        int index;
254
        *buf++ = '$';
255
        *buf++ = 'I';
256
        for (index = 24; index > 0; index -= 4)
257
                if ((0xF << index) & type)
258
                        break;
259
        while (index >= 0) {
260
                *buf++ = hex[(type >> index) & 0xF];
261
                index -= 4;
262
        }
263
        *buf = '\0';
264
}
265
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.