1 /*
   2  * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package sun.print;
  26 
  27 import java.io.ByteArrayInputStream;
  28 
  29 public class AttributeClass {
  30     private String myName;
  31     private int myType;
  32     private int nameLen;
  33     private Object myValue;
  34 
  35     public static final int TAG_UNSUPPORTED_VALUE = 0x10;
  36     public static final int TAG_INT = 0x21;
  37     public static final int TAG_BOOL = 0x22;
  38     public static final int TAG_ENUM = 0x23;
  39     public static final int TAG_OCTET = 0x30;
  40     public static final int TAG_DATE = 0x31;
  41     public static final int TAG_RESOLUTION = 0x32;
  42     public static final int TAG_RANGE_INTEGER = 0x33;
  43 
  44     public static final int TAG_TEXT_LANGUAGE = 0x35;
  45     public static final int TAG_NAME_LANGUAGE = 0x36;
  46 
  47     public static final int TAG_TEXT_WO_LANGUAGE = 0x41;
  48     public static final int TAG_NAME_WO_LANGUAGE = 0x42;
  49     public static final int TAG_KEYWORD = 0x44;
  50     public static final int TAG_URI = 0x45;
  51     public static final int TAG_CHARSET = 0x47;
  52     public static final int TAG_NATURALLANGUAGE = 0x48;
  53     public static final int TAG_MIME_MEDIATYPE = 0x49;
  54     public static final int TAG_MEMBER_ATTRNAME = 0x4A;
  55 
  56 
  57     public static final AttributeClass ATTRIBUTES_CHARSET =
  58         new AttributeClass("attributes-charset",
  59                            TAG_CHARSET, "utf-8");
  60     public static final AttributeClass ATTRIBUTES_NATURAL_LANGUAGE =
  61         new AttributeClass("attributes-natural-language",
  62                            TAG_NATURALLANGUAGE, "en");
  63 
  64     /*
  65      * value passed in by IPPPrintService.readIPPResponse is a sequence
  66      * of bytes with this format
  67      * | length1 | byte1 | byte 2 | ... byten | length2 | byte1 ... byten |
  68      *      :
  69      * | lengthN | byte1 ... byten | total number of values|
  70      */
  71     protected AttributeClass(String name, int type, Object value) {
  72         myName = name;
  73         myType = type;
  74         nameLen = name.length();
  75         myValue = value;
  76     }
  77 
  78     public byte getType() {
  79         return (byte)myType;
  80     }
  81 
  82     public char[] getLenChars() {
  83         char[] chars = new char[2];
  84         chars[0] = 0;
  85         chars[1] = (char)nameLen;
  86         return chars;
  87     }
  88 
  89     /**
  90      * Returns raw data.
  91      */
  92     public Object getObjectValue() {
  93         return myValue;
  94     }
  95 
  96     /**
  97      * Returns single int value.
  98      */
  99     public int getIntValue() {
 100         byte[] bufArray = (byte[])myValue;
 101 
 102         if (bufArray != null) {
 103             byte[] buf = new byte[4];
 104             for (int i=0; i<4; i++) {
 105                 buf[i] = bufArray[i+1];
 106             }
 107 
 108             return convertToInt(buf);
 109         }
 110         return 0;
 111     }
 112 
 113     /**
 114      * Returns array of int values.
 115      */
 116     public int[] getArrayOfIntValues() {
 117 
 118         byte[] bufArray = (byte[])myValue;
 119         if (bufArray != null) {
 120 
 121             //ArrayList valList = new ArrayList();
 122             ByteArrayInputStream bufStream =
 123                 new ByteArrayInputStream(bufArray);
 124             int available = bufStream.available();
 125 
 126             // total number of values is at the end of the stream
 127             bufStream.mark(available);
 128             bufStream.skip(available-1);
 129             int length = bufStream.read();
 130             bufStream.reset();
 131 
 132             int[] valueArray = new int[length];
 133             for (int i = 0; i < length; i++) {
 134                 // read length
 135                 int valLength = bufStream.read();
 136                 if (valLength != 4) {
 137                     // invalid data
 138                     return null;
 139                 }
 140 
 141                 byte[] bufBytes = new byte[valLength];
 142                 bufStream.read(bufBytes, 0, valLength);
 143                 valueArray[i] = convertToInt(bufBytes);
 144 
 145             }
 146             return valueArray;
 147         }
 148         return null;
 149     }
 150 
 151     /**
 152      * Returns 2 int values.
 153      */
 154     public int[] getIntRangeValue() {
 155         int[] range = {0, 0};
 156         byte[] bufArray = (byte[])myValue;
 157         if (bufArray != null) {
 158             int nBytes = 4; // 32-bit signed integer
 159             for (int j=0; j<2; j++) { // 2 set of integers
 160                 byte[] intBytes = new byte[nBytes];
 161                 // REMIND: # bytes should be 8
 162                 for (int i=0; i< nBytes; i++) {
 163                     //+ 1 because the 1st byte is length
 164                     intBytes[i] = bufArray[i+(4*j)+1];
 165                 }
 166                 range[j] = convertToInt(intBytes);
 167             }
 168         }
 169         return range;
 170 
 171     }
 172 
 173     /**
 174      * Returns String value.
 175      */
 176     public String getStringValue() {
 177         //assumes only 1 attribute value.  Will get the first value
 178         // if > 1.
 179         String strVal = null;
 180         byte[] bufArray = (byte[])myValue;
 181         if (bufArray != null) {
 182             ByteArrayInputStream bufStream =
 183                 new ByteArrayInputStream(bufArray);
 184 
 185             int valLength = bufStream.read();
 186 
 187             byte[] strBytes = new byte[valLength];
 188             bufStream.read(strBytes, 0, valLength);
 189             try {
 190                 strVal = new String(strBytes, "UTF-8");
 191             } catch (java.io.UnsupportedEncodingException uee) {
 192             }
 193         }
 194         return strVal;
 195     }
 196 
 197 
 198     /**
 199      * Returns array of String values.
 200      */
 201     public String[] getArrayOfStringValues() {
 202 
 203         byte[] bufArray = (byte[])myValue;
 204         if (bufArray != null) {
 205             ByteArrayInputStream bufStream =
 206                 new ByteArrayInputStream(bufArray);
 207             int available = bufStream.available();
 208 
 209             // total number of values is at the end of the stream
 210             bufStream.mark(available);
 211             bufStream.skip(available-1);
 212             int length = bufStream.read();
 213             bufStream.reset();
 214 
 215             String[] valueArray = new String[length];
 216             for (int i = 0; i < length; i++) {
 217                 // read length
 218                 int valLength = bufStream.read();
 219                 byte[] bufBytes = new byte[valLength];
 220                 bufStream.read(bufBytes, 0, valLength);
 221                 try {
 222                     valueArray[i] = new String(bufBytes, "UTF-8");
 223                 } catch (java.io.UnsupportedEncodingException uee) {
 224                 }
 225             }
 226             return valueArray;
 227         }
 228         return null;
 229     }
 230 
 231 
 232     /**
 233      * Returns single byte value.
 234      */
 235     public byte getByteValue() {
 236         byte[] bufArray = (byte[])myValue;
 237 
 238         if ((bufArray != null) && (bufArray.length>=2)) {
 239             return bufArray[1];
 240         }
 241         return 0;
 242     }
 243 
 244     /**
 245      * Returns attribute name.
 246      */
 247     public String getName() {
 248         return myName;
 249     }
 250 
 251     public boolean equals(Object obj) {
 252         return
 253             obj != null &&
 254             obj instanceof AttributeClass &&
 255             obj.toString().equals (((AttributeClass) obj).toString());
 256     }
 257 
 258     public String toString() {
 259         return myName;
 260     }
 261 
 262     private int unsignedByteToInt(byte b) {
 263         return (int) (b & 0xff);
 264     }
 265 
 266     private int convertToInt(byte[] buf) {
 267         int intVal = 0;
 268         int pos = 0;
 269         intVal+= unsignedByteToInt(buf[pos++]) << 24;
 270         intVal+= unsignedByteToInt(buf[pos++]) << 16;
 271         intVal+= unsignedByteToInt(buf[pos++]) << 8;
 272         intVal+= unsignedByteToInt(buf[pos++]) << 0;
 273         return intVal;
 274     }
 275 }