OpenIndiana and Solaris port
[oweals/cde.git] / cde / programs / nsgmls / IdentityCodingSystem.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: IdentityCodingSystem.C /main/1 1996/07/29 16:54:48 cde-hp $ */
24 // Copyright (c) 1994 James Clark
25 // See the file COPYING for copying permission.
26
27 #include "splib.h"
28 #include "IdentityCodingSystem.h"
29 #if defined(linux) || defined(CSRG_BASED) || defined(sun)
30 #include <iostream>
31 #else
32 #include <iostream.h>
33 #endif
34 #include <limits.h>
35
36 #ifdef SP_NAMESPACE
37 namespace SP_NAMESPACE {
38 #endif
39
40 class IdentityDecoder : public Decoder {
41 public:
42   size_t decode(Char *to, const char *from, size_t fromLen,
43                 const char **rest);
44   Boolean convertOffset(unsigned long &offset) const;
45 };
46
47 class IdentityEncoder : public Encoder {
48 public:
49   IdentityEncoder();
50   ~IdentityEncoder();
51   void output(Char *, size_t, streambuf *);
52   void output(const Char *, size_t, streambuf *);
53 private:
54   void allocBuf(size_t);
55   char *buf_;
56   size_t bufSize_;
57 };
58
59 IdentityCodingSystem::IdentityCodingSystem()
60 {
61 }
62
63 Decoder *IdentityCodingSystem::makeDecoder() const
64 {
65   return new IdentityDecoder;
66 }
67
68 Encoder *IdentityCodingSystem::makeEncoder() const
69 {
70   return new IdentityEncoder;
71 }
72
73 Boolean IdentityCodingSystem::isIdentity() const
74 {
75   return 1;
76 }
77
78 size_t IdentityDecoder::decode(Char *to, const char *from, size_t fromLen,
79                                const char **rest)
80 {
81   if (sizeof(Char) == sizeof(char) && from == (char *)to) {
82     *rest = from + fromLen;
83     return fromLen;
84   }
85   for (size_t n = fromLen; n > 0; n--)
86     *to++ = (unsigned char)*from++; // zero extend
87   *rest = from;
88   return fromLen;
89 }
90
91 Boolean IdentityDecoder::convertOffset(unsigned long &) const
92 {
93   return true;
94 }
95
96 IdentityEncoder::IdentityEncoder()
97 : buf_(0), bufSize_(0)
98 {
99 }
100
101 IdentityEncoder::~IdentityEncoder()
102 {
103   delete [] buf_;
104 }
105
106 void IdentityEncoder::allocBuf(size_t n)
107 {
108   if (bufSize_ < n) {
109     delete [] buf_;
110     buf_ = new char[bufSize_ = n];
111   }
112 }
113
114 // FIXME handle errors from streambuf::sputn
115
116 void IdentityEncoder::output(Char *s, size_t n, streambuf *sb)
117 {
118   char *p = (char *)s;
119   if (sizeof(Char) != sizeof(char)) {
120     size_t j = 0;
121     for (size_t i = 0; i < n; i++) {
122       if (s[i] > UCHAR_MAX) {
123         sb->sputn(p, j);
124         j = 0;
125         handleUnencodable(s[i], sb);
126       }
127       else
128         p[j++] = char(s[i]);
129     }
130     sb->sputn(p, j);
131   }
132   else
133     sb->sputn(p, n);
134 }
135
136 void IdentityEncoder::output(const Char *s, size_t n, streambuf *sb)
137 {
138   if (sizeof(Char) != sizeof(char)) {
139     allocBuf(n);
140     size_t j = 0;
141     for (size_t i = 0; i < n; i++) {
142       if (s[i] > UCHAR_MAX) {
143         sb->sputn(buf_, j);
144         j = 0;
145         handleUnencodable(s[i], sb);
146       }
147       else
148         buf_[j++] = char(s[i]);
149     }
150     sb->sputn(buf_, j);
151   }
152   else
153     sb->sputn((const char *)s, n);
154 }
155
156 #ifdef SP_NAMESPACE
157 }
158 #endif