43e9f84b963dc0a2ae18d103bd2271261bc55a9a
[yaz-moved-to-github.git] / src / ucs4.c
1 /*
2  * Copyright (C) 1995-2008, Index Data ApS
3  * See the file LICENSE for details.
4  *
5  */
6 /**
7  * \file
8  * \brief UCS4 decoding and encoding
9  */
10
11 #if HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14
15 #include <assert.h>
16 #include <errno.h>
17 #include <string.h>
18 #include <ctype.h>
19
20 #include "iconv-p.h"
21
22 unsigned long yaz_read_UCS4(yaz_iconv_t cd, unsigned char *inp,
23                             size_t inbytesleft, size_t *no_read)
24 {
25     unsigned long x = 0;
26     
27     if (inbytesleft < 4)
28     {
29         yaz_iconv_set_errno(cd, YAZ_ICONV_EINVAL); /* incomplete input */
30         *no_read = 0;
31     }
32     else
33     {
34         x = (inp[0]<<24) | (inp[1]<<16) | (inp[2]<<8) | inp[3];
35         *no_read = 4;
36     }
37     return x;
38 }
39
40 unsigned long yaz_read_UCS4LE(yaz_iconv_t cd, unsigned char *inp,
41                               size_t inbytesleft, size_t *no_read)
42 {
43     unsigned long x = 0;
44     
45     if (inbytesleft < 4)
46     {
47         yaz_iconv_set_errno(cd, YAZ_ICONV_EINVAL); /* incomplete input */
48         *no_read = 0;
49     }
50     else
51     {
52         x = (inp[3]<<24) | (inp[2]<<16) | (inp[1]<<8) | inp[0];
53         *no_read = 4;
54     }
55     return x;
56 }
57
58 static size_t write_UCS4(yaz_iconv_t cd, yaz_iconv_encoder_t en,
59                          unsigned long x,
60                          char **outbuf, size_t *outbytesleft)
61 {
62     unsigned char *outp = (unsigned char *) *outbuf;
63     if (*outbytesleft >= 4)
64     {
65         *outp++ = (unsigned char) (x>>24);
66         *outp++ = (unsigned char) (x>>16);
67         *outp++ = (unsigned char) (x>>8);
68         *outp++ = (unsigned char) x;
69         (*outbytesleft) -= 4;
70     }
71     else
72     {
73         yaz_iconv_set_errno(cd, YAZ_ICONV_E2BIG);
74         return (size_t)(-1);
75     }
76     *outbuf = (char *) outp;
77     return 0;
78 }
79
80 static size_t write_UCS4LE(yaz_iconv_t cd, yaz_iconv_encoder_t en,
81                            unsigned long x,
82                            char **outbuf, size_t *outbytesleft)
83 {
84     unsigned char *outp = (unsigned char *) *outbuf;
85     if (*outbytesleft >= 4)
86     {
87         *outp++ = (unsigned char) x;
88         *outp++ = (unsigned char) (x>>8);
89         *outp++ = (unsigned char) (x>>16);
90         *outp++ = (unsigned char) (x>>24);
91         (*outbytesleft) -= 4;
92     }
93     else
94     {
95         yaz_iconv_set_errno(cd, YAZ_ICONV_E2BIG);
96         return (size_t)(-1);
97     }
98     *outbuf = (char *) outp;
99     return 0;
100 }
101
102
103 yaz_iconv_encoder_t yaz_ucs4_encoder(const char *tocode,
104                                      yaz_iconv_encoder_t e)
105     
106 {
107     if (!yaz_matchstr(tocode, "UCS4"))
108         e->write_handle = write_UCS4;
109     else if (!yaz_matchstr(tocode, "UCS4LE"))
110         e->write_handle = write_UCS4LE;
111     else
112         return 0;
113     return e;
114 }
115
116
117
118 /*
119  * Local variables:
120  * c-basic-offset: 4
121  * indent-tabs-mode: nil
122  * End:
123  * vim: shiftwidth=4 tabstop=8 expandtab
124  */