1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * ident	"%Z%%M%	%I%	%E% SMI"
24 *
25 * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
26 * All rights reserved.
27 */
28
29/**
30 * Copyright 1996 Active Software Inc.
31 */
32
33package sunsoft.jws.visual.rt.encoding;
34
35import java.io.*;
36
37// Referenced classes of package sunsoft.jws.visual.rt.encoding:
38//            CRC16
39
40public class UCEncoder
41{
42
43    protected int bytesPerAtom()
44    {
45        return 2;
46    }
47
48    protected int bytesPerLine()
49    {
50        return 48;
51    }
52
53    protected void encodeAtom(OutputStream outStream, byte data[],
54			      int offset, int len)
55	throws IOException
56    {
57        byte a = data[offset];
58        byte b;
59        if (len == 2)
60            b = data[offset + 1];
61        else
62            b = 0;
63        crc.update(a);
64        if (len == 2)
65            crc.update(b);
66        outStream.write(map_array[(a >>> 2 & 0x38) + (b >>> 5 & 0x7)]);
67        int p1 = 0;
68        int p2 = 0;
69        for (int i = 1; i < 256; i *= 2)
70	    {
71		if ((a & i) != 0)
72		    p1++;
73		if ((b & i) != 0)
74		    p2++;
75	    }
76
77        p1 = (p1 & 0x1) * 32;
78        p2 = (p2 & 0x1) * 32;
79        outStream.write(map_array[(a & 0x1f) + p1]);
80        outStream.write(map_array[(b & 0x1f) + p2]);
81    }
82
83    protected void encodeLinePrefix(OutputStream outStream, int length)
84	throws IOException
85    {
86        outStream.write(42);
87        crc.value = 0;
88        tmp[0] = (byte)length;
89        tmp[1] = (byte)sequence;
90        sequence = sequence + 1 & 0xff;
91        encodeAtom(outStream, tmp, 0, 2);
92    }
93
94    protected void encodeLineSuffix(OutputStream outStream)
95	throws IOException
96    {
97        tmp[0] = (byte)(crc.value >>> 8 & 0xff);
98        tmp[1] = (byte)(crc.value & 0xff);
99        encodeAtom(outStream, tmp, 0, 2);
100        pStream.println();
101    }
102
103    protected void encodeBufferPrefix(OutputStream a)
104	throws IOException
105    {
106        sequence = 0;
107        pStream = new PrintStream(a);
108    }
109
110    public void encodeBuffer(InputStream inStream,
111			     OutputStream outStream)
112	throws IOException
113    {
114        byte tmpbuffer[] = new byte[bytesPerLine()];
115        encodeBufferPrefix(outStream);
116        int numBytes;
117        do
118	    {
119		numBytes = readFully(inStream, tmpbuffer);
120		if (numBytes == -1)
121		    break;
122		encodeLinePrefix(outStream, numBytes);
123		for (int j = 0; j < numBytes; j += bytesPerAtom())
124		    if (j + bytesPerAtom() <= numBytes)
125			encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
126		    else
127			encodeAtom(outStream, tmpbuffer, j, numBytes - j);
128
129		encodeLineSuffix(outStream);
130	    }
131        while (numBytes >= bytesPerLine());
132        encodeBufferSuffix(outStream);
133    }
134
135    protected int readFully(InputStream in, byte buffer[])
136	throws IOException
137    {
138        for (int i = 0; i < buffer.length; i++)
139	    {
140		int q = in.read();
141		if (q == -1)
142		    return i;
143		buffer[i] = (byte)q;
144	    }
145
146        return buffer.length;
147    }
148
149    protected void encodeBufferSuffix(OutputStream outputstream)
150	throws IOException
151    {
152    }
153
154    public String encodeBuffer(byte aBuffer[])
155    {
156        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
157        ByteArrayInputStream inStream =
158	    new ByteArrayInputStream(aBuffer);
159        try
160	    {
161		encodeBuffer(inStream, outStream);
162	    }
163        catch (Exception ex)
164	    {
165		throw new Error("encodeBuffer internal error");
166	    }
167        return outStream.toString();
168    }
169
170    public UCEncoder()
171    {
172        super();
173        tmp = new byte[2];
174        crc = new CRC16();
175    }
176
177    private PrintStream pStream;
178    private static final byte map_array[] = {
179        48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
180        65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
181        75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
182        85, 86, 87, 88, 89, 90, 97, 98, 99, 100,
183        101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
184        111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
185        121, 122, 40, 41
186    };
187    private int sequence;
188    private byte tmp[];
189    private CRC16 crc;
190
191}
192