TIVI-153: Add as dependency for iputils
[profile/ivi/opensp.git] / lib / Fixed4CodingSystem.cxx
1 // Copyright (c) 2000 Matthias Clasen
2 // See the file COPYING for copying permission.
3
4 #include "splib.h"
5
6 #ifdef SP_MULTI_BYTE
7
8 #include "Fixed4CodingSystem.h"
9 #include "macros.h"
10 #include "constant.h"
11
12 #ifdef SP_NAMESPACE
13 namespace SP_NAMESPACE {
14 #endif
15
16 class Fixed4Decoder : public Decoder {
17 public:
18   Fixed4Decoder(Boolean lsbFirst, Boolean lswFirst);
19   size_t decode(Char *to, const char *from, size_t fromLen,
20                 const char **rest);
21   Boolean convertOffset(unsigned long &offset) const;
22 private:
23   // value for encoding error
24   enum { invalid = 0xfffd };
25   Boolean lsbFirst_;
26   Boolean lswFirst_;
27 };
28
29 class Fixed4Encoder : public Encoder {
30 public:
31   Fixed4Encoder();
32   ~Fixed4Encoder();
33   void output(Char *, size_t, OutputByteStream *);
34   void output(const Char *, size_t, OutputByteStream *);
35 private:
36   void allocBuf(size_t);
37   char *buf_;
38   size_t bufSize_;
39 };
40
41 Decoder *Fixed4CodingSystem::makeDecoder(Boolean lsbFirst, Boolean lswFirst) const
42 {
43   return new Fixed4Decoder(lsbFirst, lswFirst);
44 }
45
46 Encoder *Fixed4CodingSystem::makeEncoder() const
47 {
48   return new Fixed4Encoder;
49 }
50
51 unsigned Fixed4CodingSystem::fixedBytesPerChar() const
52 {
53   return 4;
54 }
55
56 Fixed4Decoder::Fixed4Decoder(Boolean lsbFirst, Boolean lswFirst)
57 : Decoder(4), lsbFirst_(lsbFirst), lswFirst_(lswFirst)
58 {
59 }
60
61 size_t Fixed4Decoder::decode(Char *to, const char *from, size_t fromLen,
62                            const char **rest)
63 {
64 #if 0
65   // FIXME for this optimization I need autoconf macros that tell
66   // me the byte order in 32bit words: 1234, 4321, 2143 or 3412.
67   // Look at the corresponding optimization in Fixed2Decoder.
68   if (sizeof(Char) == 4 && from == (char *)to) {
69     *rest = from + (fromLen & ~3);
70     for (size_t n = 0; n < fromLen/4; n++)
71       if (charMax < to[n])
72         to[n] = invalid;
73     return fromLen/4;
74   }
75 #endif
76   fromLen &= ~3;
77   *rest = from + fromLen;
78   //  lsbFirst,  lswFirst: 0123
79   //  lsbFirst, !lswFirst: 2301
80   // !lsbFirst,  lswFirst: 1032
81   // !lsbFirst, !lswFirst: 3210   
82   size_t shift0 = 8*(!lsbFirst_ + 2*!lswFirst_); 
83   size_t shift1 = 8*(lsbFirst_ + 2*!lswFirst_); 
84   size_t shift2 = 8*(!lsbFirst_ + 2*lswFirst_); 
85   size_t shift3 = 8*(lsbFirst_ + 2*lswFirst_); 
86   for (size_t n = fromLen; n > 0; n -= 4) {
87     Unsigned32 c = ((unsigned char)from[0] << shift0) 
88                  + ((unsigned char)from[1] << shift1) 
89                  + ((unsigned char)from[2] << shift2) 
90                  + ((unsigned char)from[3] << shift3);
91     *to++ = charMax < c ? invalid : c;
92     from += 4;
93   }
94   return fromLen/4;
95 }
96
97 Boolean Fixed4Decoder::convertOffset(unsigned long &n) const
98 {
99   n *= 4;
100   return true;
101 }
102
103 Fixed4Encoder::Fixed4Encoder()
104 : buf_(0), bufSize_(0)
105 {
106 }
107
108 Fixed4Encoder::~Fixed4Encoder()
109 {
110   delete [] buf_;
111 }
112
113 void Fixed4Encoder::allocBuf(size_t n)
114 {
115   if (bufSize_ < n) {
116     delete [] buf_;
117     buf_ = new char[bufSize_ = n];
118   }
119 }
120
121 void Fixed4Encoder::output(Char *s, size_t n, OutputByteStream *sb)
122 {
123 #ifdef SP_BIG_ENDIAN
124   if (sizeof(Char) == 4) {
125     sb->sputn((char *)s, n*4);
126     return;
127   }
128 #endif
129   ASSERT(sizeof(Char) >= 4);
130   char *p = (char *)s;
131   for (size_t i = 0; i < n; i++) {
132     Char c = s[i];
133     *p++ = (c >> 24) & 0xff;
134     *p++ = (c >> 16) & 0xff;
135     *p++ = (c >> 8) & 0xff;
136     *p++ = c & 0xff;
137   }
138   sb->sputn((char *)s, n*4);
139 }
140
141 void Fixed4Encoder::output(const Char *s, size_t n, OutputByteStream *sb)
142 {
143 #ifdef SP_BIG_ENDIAN
144   if (sizeof(Char) == 4) {
145     sb->sputn((char *)s, n*4);
146     return;
147   }
148 #endif
149   allocBuf(n*4);
150   for (size_t i = 0; i < n; i++) {
151     buf_[i*4] = (s[i] >> 24) & 0xff;
152     buf_[i*4 + 1] = (s[i] >> 16) & 0xff;
153     buf_[i*4 + 2] = (s[i] >> 8) & 0xff;
154     buf_[i*4 + 3] = s[i] & 0xff;
155   }
156   sb->sputn(buf_, n*4);
157 }
158
159 #ifdef SP_NAMESPACE
160 }
161 #endif
162
163 #else /* not SP_MULTI_BYTE */
164
165 #ifndef __GNUG__
166 static char non_empty_translation_unit; // sigh
167 #endif
168
169 #endif /* not SP_MULTI_BYTE */