Back to index

im-sdk  12.3.91
ProtocolData.java
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 
00043 
00044 package sun.awt.im.iiimp;
00045 
00046 import java.io.IOException;
00047 import java.io.EOFException;
00048 import java.util.HashSet;
00049 import java.text.AttributedCharacterIterator.Attribute;
00050 
00051 class ProtocolData implements IIIMProtocol {
00052     int pos;
00053     int count;
00054     byte buf[];
00055 
00056     private final static int DATA_BOUNDARY = 4;
00057 
00061     ProtocolData() {
00062        buf = new byte[32];
00063        count = 0;
00064        pos = 0;
00065     }
00066 
00071     ProtocolData(byte b[], int start, int len) {
00072        pos = 0;
00073        count = len;
00074        if (len > 0) {
00075            buf = new byte[len];
00076            System.arraycopy(b, start, buf, 0, len);
00077        }
00078     }
00079 
00080     ProtocolData(byte b[], int len) {
00081        this(b, 0, len);
00082     }
00083 
00084     ProtocolData(byte b[]) {
00085         this(b, b.length);
00086     }
00087 
00092     ProtocolData(ProtocolData d) {
00093        int newVal = d.count - d.pos;
00094        if (newVal > 0) {
00095            byte newValue[] = new byte[newVal];
00096            System.arraycopy(d.buf, d.pos, newValue, 0, newVal);
00097            buf = newValue;
00098        }
00099        count = newVal;
00100        pos = 0;
00101     }
00102 
00103     void write(int b) throws IOException {
00104        ensureCapacity(count + 1);
00105        buf[count++] = (byte) (b & 0xFF);
00106     }
00107 
00108     void write2(int b) throws IOException {
00109        ensureCapacity(count + 2);
00110        buf[count++] = (byte) ((b >>> 8) & 0xFF);
00111        buf[count++] = (byte) ((b >>> 0) & 0xFF);
00112     }
00113 
00114     void write4(int b) throws IOException {
00115        ensureCapacity(count + 4);
00116        buf[count++] = (byte) ((b >>> 24) & 0xFF);
00117        buf[count++] = (byte) ((b >>> 16) & 0xFF);
00118        buf[count++] = (byte) ((b >>>  8) & 0xFF);
00119        buf[count++] = (byte) ((b >>>  0) & 0xFF);
00120     }
00121 
00122     void writeBytes(byte b[]) throws IOException {
00123        ensureCapacity(count + b.length);
00124        System.arraycopy(b, 0, buf, count, b.length);
00125        count += b.length;
00126     }
00127 
00128     void writeBytes(byte b[], int length) throws IOException {
00129        ensureCapacity(count + length);
00130        System.arraycopy(b, 0, buf, count, length);
00131        count += length;
00132     }
00133 
00134     void writeString(String utf) throws IOException {
00135        int utflen = utf.length();
00136        int len = utflen * 2;
00137 
00138        write2(len);
00139 
00140        int pad = paddings(len + 2);
00141 
00142        ensureCapacity(count + len + pad);
00143 
00144        for (int i = 0 ; i < utflen ; i++) {
00145            char c = utf.charAt(i);
00146            buf[count++] = (byte) ((c >>  8) & 0xFF);
00147            buf[count++] = (byte) ((c >>  0) & 0xFF);
00148        }
00149 
00150        for (int j = 0; j < pad; j++) {
00151            buf[count++] = (byte) 0;
00152        }
00153     }
00154 
00155     int read() throws IOException {
00156        if (pos >= count) {
00157            throw new EOFException();
00158        }
00159        int ch = (int) (buf[pos++] & 0x000000FF);
00160        if (ch < 0) {
00161            throw new EOFException();
00162        }
00163        return ch;
00164     }
00165 
00166     int read2() throws IOException {
00167        int ch1 = read();
00168        int ch2 = read();
00169        return (ch1 << 8) + (ch2 << 0);
00170     }
00171 
00172     int read4() throws IOException {
00173        int ch1 = read();
00174        int ch2 = read();
00175        int ch3 = read();
00176        int ch4 = read();
00177        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
00178     }
00179 
00180     int read(byte b[], int offset, int size) throws IOException {
00181        if (size <= 0) {
00182            return 0;
00183        }
00184 
00185        int c = read();
00186        if (c == -1) {
00187            return -1;
00188        }
00189        b[offset] = (byte) c;
00190 
00191        int i = 1;
00192        try {
00193            for (; i < size ; i++) {
00194               c = read();
00195               if (c == -1) {
00196                   break;
00197               }
00198               if (b != null) {
00199                   b[offset + i] = (byte) c;
00200               }
00201            }
00202        } catch (IOException ee) {
00203        }
00204        return i;
00205     }
00206 
00207     String readString() throws IOException {
00208        int len = read2();
00209        if (len == 0) {
00210            // need to read 2 bytes for padding
00211            read2();
00212            return (String)null;
00213        }
00214 
00215        int utflen = len / 2;
00216         char str[] = new char[utflen];
00217        int i = 0;
00218        while (i < utflen) {
00219            int ch1 = read();
00220            int ch2 = read();
00221            str[i++] = (char) ((ch1 << 8) + (ch2 << 0));
00222        }
00223        int pad = paddings(len + 2);
00224        for (int j = 0; j < pad; j++) {
00225            read();
00226        }
00227         return new String(str, 0, utflen);
00228     }
00229 
00230     AnnotationValue[] readStringAnnotationValues(Attribute attribute)
00231        throws IOException {
00232        int size = read4();
00233        if (size < 4 * 3) {
00234            // size must be bigger than start+end+value_size
00235            skipBytes(size);
00236            return null;
00237        }
00238        HashSet hs = new HashSet();
00239        while (size > 0) {
00240            int start = read4();
00241            int end = read4();
00242            int len = read4();
00243            String value = readString();
00244            pad();
00245            hs.add(new AnnotationValue(start, end, attribute, value));
00246        }
00247        Object[] oa = hs.toArray();
00248        AnnotationValue[] ava = new AnnotationValue[oa.length];
00249        for (int i = 0; i < oa.length; i++) {
00250            ava[i] = (AnnotationValue)oa[i];
00251        }
00252 
00253        return ava;
00254     }
00255 
00256     AnnotationValue[] readTextAnnotationValues(Attribute attribute)
00257        throws IOException {
00258        int size = read4();
00259        if (size < 4 * 3) { 
00260            // size must be bigger than start+end+value_size
00261            skipBytes(size);
00262            return null;
00263        }
00264        HashSet hs = new HashSet();
00265        while (size > 0) {
00266            int start = read4();
00267            int end = read4();
00268            int len = read4();
00269            int feedbackCharLen = read4();
00270            StringBuffer sb = new StringBuffer();
00271            while (feedbackCharLen > 0) {
00272               sb.append(read2());
00273               int sk = read2();
00274               skipBytes(sk);
00275            }
00276            String value = sb.toString();
00277            pad();
00278            hs.add(new AnnotationValue(start, end, attribute, value));
00279        }
00280        Object[] oa = hs.toArray();
00281        AnnotationValue[] ava = new AnnotationValue[oa.length];
00282        for (int i = 0; i < oa.length; i++) {
00283            ava[i] = (AnnotationValue)oa[i];
00284        }
00285 
00286        return ava;
00287     }
00288 
00289     void ensureCapacity(int minimumNum) {
00290        int maxNum = buf.length;
00291        if (minimumNum > maxNum) {
00292            int newNum = (maxNum + 1) * 2;
00293            if (minimumNum > newNum) {
00294               newNum = minimumNum;
00295            }
00296            byte newValue[] = new byte[newNum];
00297            System.arraycopy(buf, 0, newValue, 0, count);
00298            buf = newValue;
00299        }
00300     }
00301 
00302     final static int paddings(int len) {
00303        return ((DATA_BOUNDARY -((len) % DATA_BOUNDARY)) % DATA_BOUNDARY);
00304     }
00305 
00306     void pad() throws IOException {
00307        int pad = paddings(count);
00308        int total = count + pad;
00309        for (int i = count; i < total; i++) {
00310            write(0);
00311        }
00312     }
00313 
00314     void skipBytes(int skip) {
00315        int num = (count < (pos + skip)) ? (count - pos) : skip;
00316        pos += num;
00317     }
00318 
00319     int available() {
00320        return (count > pos) ? (count - pos) : 0;
00321     }
00322     
00323     void read(IIIMPInputStream in, int count) {
00324         try {
00325             pos = 0;
00326         
00327             this.count = count;
00328         
00329             buf = new byte[count];
00330             
00331             in.readFully(buf);
00332         } catch(IOException e) {
00333             debug("e = " + e);
00334         }
00335     }
00336     
00337     void write(IIIMPOutputStream out) {
00338         try {
00339             out.write(buf, 0 , count);
00340         } catch(IOException e) {
00341             debug("e = " + e);
00342         }
00343     }
00344 
00345     private void debug(String str) {
00346        if (Manager.DEBUG) {
00347            System.err.println(str);
00348        }
00349     }
00350 }