OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [javax/] [print/] [ipp/] [IppResponse.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* IppResponse.java --
2
 Copyright (C) 2006 Free Software Foundation, Inc.
3
 
4
 This file is part of GNU Classpath.
5
 
6
 GNU Classpath is free software; you can redistribute it and/or modify
7
 it under the terms of the GNU General Public License as published by
8
 the Free Software Foundation; either version 2, or (at your option)
9
 any later version.
10
 
11
 GNU Classpath is distributed in the hope that it will be useful, but
12
 WITHOUT ANY WARRANTY; without even the implied warranty of
13
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 General Public License for more details.
15
 
16
 You should have received a copy of the GNU General Public License
17
 along with GNU Classpath; see the file COPYING.  If not, write to the
18
 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
 02110-1301 USA.
20
 
21
 Linking this library statically or dynamically with other modules is
22
 making a combined work based on this library.  Thus, the terms and
23
 conditions of the GNU General Public License cover the whole
24
 combination.
25
 
26
 As a special exception, the copyright holders of this library give you
27
 permission to link this library with independent modules to produce an
28
 executable, regardless of the license terms of these independent
29
 modules, and to copy and distribute the resulting executable under
30
 terms of your choice, provided that you also meet, for each linked
31
 independent module, the terms and conditions of the license of that
32
 module.  An independent module is a module which is not derived from
33
 or based on this library.  If you modify this library, you may extend
34
 this exception to your version of the library, but you are not
35
 obligated to do so.  If you do not wish to do so, delete this
36
 exception statement from your version. */
37
 
38
 
39
package gnu.javax.print.ipp;
40
 
41
import gnu.classpath.debug.Component;
42
import gnu.classpath.debug.SystemLogger;
43
import gnu.javax.print.ipp.attribute.UnknownAttribute;
44
import gnu.javax.print.ipp.attribute.defaults.DocumentFormatDefault;
45
import gnu.javax.print.ipp.attribute.defaults.JobHoldUntilDefault;
46
import gnu.javax.print.ipp.attribute.defaults.JobSheetsDefault;
47
import gnu.javax.print.ipp.attribute.defaults.MediaDefault;
48
import gnu.javax.print.ipp.attribute.defaults.PrinterResolutionDefault;
49
import gnu.javax.print.ipp.attribute.job.AttributesCharset;
50
import gnu.javax.print.ipp.attribute.job.AttributesNaturalLanguage;
51
import gnu.javax.print.ipp.attribute.job.JobMoreInfo;
52
import gnu.javax.print.ipp.attribute.job.JobPrinterUri;
53
import gnu.javax.print.ipp.attribute.job.JobUri;
54
import gnu.javax.print.ipp.attribute.printer.CharsetConfigured;
55
import gnu.javax.print.ipp.attribute.printer.DocumentFormat;
56
import gnu.javax.print.ipp.attribute.printer.NaturalLanguageConfigured;
57
import gnu.javax.print.ipp.attribute.printer.PrinterCurrentTime;
58
import gnu.javax.print.ipp.attribute.printer.PrinterDriverInstaller;
59
import gnu.javax.print.ipp.attribute.supported.CharsetSupported;
60
import gnu.javax.print.ipp.attribute.supported.DocumentFormatSupported;
61
import gnu.javax.print.ipp.attribute.supported.GeneratedNaturalLanguageSupported;
62
import gnu.javax.print.ipp.attribute.supported.JobHoldUntilSupported;
63
import gnu.javax.print.ipp.attribute.supported.JobSheetsSupported;
64
import gnu.javax.print.ipp.attribute.supported.MediaSupported;
65
import gnu.javax.print.ipp.attribute.supported.PrinterResolutionSupported;
66
import gnu.javax.print.ipp.attribute.supported.PrinterUriSupported;
67
 
68
import java.io.ByteArrayOutputStream;
69
import java.io.DataInputStream;
70
import java.io.IOException;
71
import java.io.InputStream;
72
import java.net.URI;
73
import java.net.URISyntaxException;
74
import java.util.ArrayList;
75
import java.util.Calendar;
76
import java.util.Date;
77
import java.util.HashMap;
78
import java.util.HashSet;
79
import java.util.List;
80
import java.util.Map;
81
import java.util.Set;
82
import java.util.logging.Logger;
83
 
84
import javax.print.attribute.Attribute;
85
import javax.print.attribute.standard.CopiesSupported;
86
import javax.print.attribute.standard.DateTimeAtCompleted;
87
import javax.print.attribute.standard.DateTimeAtCreation;
88
import javax.print.attribute.standard.DateTimeAtProcessing;
89
import javax.print.attribute.standard.JobImpressionsSupported;
90
import javax.print.attribute.standard.JobKOctetsSupported;
91
import javax.print.attribute.standard.JobMediaSheetsSupported;
92
import javax.print.attribute.standard.JobStateReason;
93
import javax.print.attribute.standard.JobStateReasons;
94
import javax.print.attribute.standard.NumberUpSupported;
95
import javax.print.attribute.standard.PrinterMoreInfo;
96
import javax.print.attribute.standard.PrinterMoreInfoManufacturer;
97
import javax.print.attribute.standard.PrinterStateReason;
98
import javax.print.attribute.standard.PrinterStateReasons;
99
import javax.print.attribute.standard.Severity;
100
 
101
/**
102
 * <code>IppResponse</code> models a response received from an IPP
103
 * compatible server as described in RFC 2910 IPP 1.1 Encoding and Transport.
104
 *
105
 * @author Wolfgang Baer (WBaer@gmx.de)
106
 */
107
public class IppResponse
108
{
109
 
110
  /**
111
   * <code>ResponseReader</code> is responsible for parsing an IPP 1.1
112
   * response stream. It provides access to the attribute groups after parsing
113
   * via getter methods.
114
   * <p>
115
   * The enconding of a response is structured as follows (for an official
116
   * description please have a look at the RFC document mentioned above):
117
   * <ul>
118
   * <li>version-number            - 2 bytes - required</li>
119
   * <li>status-code               - 2 bytes - required</li>
120
   * <li>request-id                - 4 bytes - required</li>
121
   * <li>attribute-group           - n bytes - 0 or more</li>
122
   * <li>end-of-attributes-tag     - 1 byte  - required</li>
123
   * <li>data                      - q bytes - optional</li>
124
   * </ul>
125
   * </p><p>
126
   * Where each attribute-group (if any) is encoded as follows:
127
   * <ul>
128
   * <li>begin-attribute-group-tag - 1 byte</li>
129
   * <li>attribute                 - p bytes - 0 or more</li>
130
   * </ul>
131
   * </p><p>
132
   * Encoding of attributes:
133
   * <ul>
134
   * <li>attribute-with-one-value - q bytes</li>
135
   * <li>additional-value         - r bytes  - 0 or more</li>
136
   * </ul>
137
   * </p><p>
138
   * Encoding of attribute-with-one-value:
139
   * <ul>
140
   * <li>value-tag                  - 1 byte</li>
141
   * <li>name-length  (value is u)  - 2 bytes</li>
142
   * <li>name                       - u bytes</li>
143
   * <li>value-length  (value is v) - 2 bytes</li>
144
   * <li>value                      - v bytes</li>
145
   * </ul>
146
   * </p><p>
147
   * Encoding of additional value:
148
   * <ul>
149
   * <li>value-tag                       - 1 byte</li>
150
   * <li>name-length  (value is 0x0000)  - 2 bytes</li>
151
   * <li>value-length (value is w)       - 2 bytes</li>
152
   * <li>value                           - w bytes</li>
153
   * </ul>
154
   * </p>
155
   *
156
   * @author Wolfgang Baer (WBaer@gmx.de)
157
   */
158
  class ResponseReader
159
  {
160
    /** The IPP version defaults to 1.1 */
161
    private static final short VERSION = 0x0101;
162
 
163
    /**
164
     * Parses the inputstream containing the response of the IPP request.
165
     * @param input the inputstream
166
     * @throws IppException if unexpected exceptions occur.
167
     * @throws IOException if IO problems with the underlying inputstream occur.
168
     */
169
    public void parseResponse(InputStream input)
170
        throws IppException, IOException
171
    {
172
      DataInputStream stream = new DataInputStream(input);
173
 
174
      short version = stream.readShort();
175
      status_code = stream.readShort();
176
      request_id = stream.readInt();
177
 
178
      if (VERSION != version)
179
        throw new IppException("Version mismatch - "
180
          + "implementation does not support other versions than IPP 1.1");
181
 
182
      logger.log(Component.IPP, "Statuscode: "
183
        + Integer.toHexString(status_code) + " Request-ID: " + request_id);
184
 
185
      byte tag = 0;
186
      boolean proceed = true;
187
      HashMap<Class<? extends Attribute>, Set<Attribute>> tmp;
188
      // iterate over attribute-groups until end-of-attributes-tag is found
189
      while (proceed)
190
        {
191
          if (tag == 0) // only at start time
192
            tag = stream.readByte();
193
 
194
          logger.log(Component.IPP, "DelimiterTag: " + Integer.toHexString(tag));
195
 
196
          // check if end of attributes
197
          switch (tag)
198
            {
199
            case IppDelimiterTag.END_OF_ATTRIBUTES_TAG:
200
              proceed = false;
201
              break;
202
            case IppDelimiterTag.OPERATION_ATTRIBUTES_TAG:
203
              tmp = new HashMap<Class<? extends Attribute>, Set<Attribute>>();
204
              tag = parseAttributes(tmp, stream);
205
              operationAttributes.add(tmp);
206
              break;
207
            case IppDelimiterTag.JOB_ATTRIBUTES_TAG:
208
              tmp = new HashMap<Class<? extends Attribute>, Set<Attribute>>();
209
              tag = parseAttributes(tmp, stream);
210
              jobAttributes.add(tmp);
211
              break;
212
            case IppDelimiterTag.PRINTER_ATTRIBUTES_TAG:
213
              tmp = new HashMap<Class<? extends Attribute>, Set<Attribute>>();
214
              tag = parseAttributes(tmp, stream);
215
              printerAttributes.add(tmp);
216
              break;
217
            case IppDelimiterTag.UNSUPPORTED_ATTRIBUTES_TAG:
218
              System.out.println("Called");
219
              tmp = new HashMap<Class<? extends Attribute>, Set<Attribute>>();
220
              tag = parseAttributes(tmp, stream);
221
              unsupportedAttributes.add(tmp);
222
              break;
223
            default:
224
              throw new IppException("Unknown tag with value "
225
                                     + Integer.toHexString(tag) + " occured.");
226
            }
227
        }
228
 
229
      // if there are more bytes that has to be data.
230
      ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
231
      byte[] readbuf = new byte[2048];
232
      int len = 0;
233
 
234
      while ((len = stream.read(readbuf)) > 0)
235
        byteStream.write(readbuf, 0, len);
236
 
237
      byteStream.flush();
238
      data = byteStream.toByteArray();
239
    }
240
 
241
    /**
242
     * The actual parsing of the attributes and further putting into the
243
     * provided group maps.
244
     * @param attributes the provided attribute group map.
245
     * @param stream the provided stream to read from.
246
     * @return The last read tag byte (normally a DelimiterTag)
247
     * @throws IppException if unexpected exceptions occur.
248
     * @throws IOException if IO problems with the underlying inputstream occur.
249
     */
250
    private byte parseAttributes(Map<Class<? extends Attribute>, Set<Attribute>> attributes,
251
                                 DataInputStream stream)
252
        throws IppException, IOException
253
    {
254
      Attribute lastAttribute = null;
255
      Attribute attribute = null;
256
 
257
      // declaration of variables
258
      short nameLength;
259
      String name;
260
      short valueLength;
261
      byte[] value;
262
 
263
      // tmp variables for parsing
264
      // declared here so no name duplication occurs
265
      URI uri;
266
      String str;
267
 
268
      while (true)
269
        {
270
          byte tag = stream.readByte();
271
 
272
          if (IppDelimiterTag.isDelimiterTag(tag))
273
            return tag;
274
 
275
          // it must be a value tag now
276
          // so we have either a attribute-with-one-value
277
          // or (if setOf is possible) an additional-value
278
 
279
          // (1) Length of the name
280
          nameLength = stream.readShort();
281
 
282
          // (2) The name itself
283
          // may be an additional-value
284
          if (nameLength == 0x0000)
285
            name = lastAttribute.getName();
286
          else
287
            {
288
              byte[] nameBytes = new byte[nameLength];
289
              stream.read(nameBytes);
290
              name = new String(nameBytes);
291
            }
292
 
293
          // (3) Length of the value
294
          valueLength = stream.readShort();
295
 
296
          // (4) The value itself
297
          value = new byte[valueLength];
298
          stream.read(value);
299
 
300
          // the value itself
301
          switch (tag)
302
            {
303
            // out-of-band values
304
            case IppValueTag.UNSUPPORTED:
305
            case IppValueTag.UNKNOWN:
306
              // TODO implement out-of-band handling
307
              // We currently throw an exception to see when it occurs - not yet :-)
308
              throw new IppException(
309
                    "Unexpected name value for out-of-band value tag " + tag);
310
            case IppValueTag.NO_VALUE:
311
              attribute = null;
312
 
313
              break;
314
            case IppValueTag.INTEGER:
315
              int intValue = IppUtilities.convertToInt(value);
316
              attribute = IppUtilities.getIntegerAttribute(name, intValue);
317
 
318
              break;
319
            case IppValueTag.BOOLEAN:
320
              // JPS API models boolean syntax type as enums
321
              // 0x01 = true, 0x00 = false - all are enums
322
              attribute = IppUtilities.getEnumAttribute(name, new Integer(value[0]));
323
 
324
              break;
325
            case IppValueTag.ENUM:
326
              int intVal = IppUtilities.convertToInt(value);
327
              attribute = IppUtilities.getEnumAttribute(name, new Integer(intVal));
328
 
329
              break;
330
            case IppValueTag.OCTECTSTRING_UNSPECIFIED:
331
              // none exists according to spec
332
              // so lets report as exception to see when it occurs
333
              throw new IppException("Unspecified octet string occured.");
334
 
335
            case IppValueTag.DATETIME:
336
              Date date = parseDate(value);
337
              if (name.equals("printer-current-time"))
338
                attribute = new PrinterCurrentTime(date);
339
              else if (name.equals("date-time-at-creation"))
340
                attribute = new DateTimeAtCreation(date);
341
              else if (name.equals("date-time-at-processing"))
342
                attribute = new DateTimeAtProcessing(date);
343
              else if (name.equals("date-time-at-completed"))
344
                attribute = new DateTimeAtCompleted(date);
345
 
346
              break;
347
            case IppValueTag.RESOLUTION:
348
              int crossFeed = IppUtilities.convertToInt(value[0], value[1], value[2], value[3]);
349
              int feed = IppUtilities.convertToInt(value[4], value[5], value[6], value[7]);
350
              int units = value[8];
351
 
352
              if (name.equals("printer-resolution-default"))
353
                attribute = new PrinterResolutionDefault(crossFeed, feed, units);
354
              else if (name.equals("printer-resolution-supported")) // may be here also
355
                attribute = new PrinterResolutionSupported(crossFeed, feed, units);
356
 
357
              break;
358
            case IppValueTag.RANGEOFINTEGER:
359
              int lower = IppUtilities.convertToInt(value[0], value[1], value[2], value[3]);
360
              int upper = IppUtilities.convertToInt(value[4], value[5], value[6], value[7]);
361
 
362
              if (name.equals("copies-supported"))
363
                attribute = new CopiesSupported(lower, upper);
364
              else if (name.equals("number-up-supported"))
365
                attribute = new NumberUpSupported(lower, upper);
366
              else if (name.equals("job-k-octets-supported"))
367
                attribute = new JobKOctetsSupported(lower, upper);
368
              else if (name.equals("job-impressions-supported"))
369
                attribute = new JobImpressionsSupported(lower, upper);
370
              else if (name.equals("job-media-sheets-supported"))
371
                attribute = new JobMediaSheetsSupported(lower, upper);
372
 
373
              break;
374
            case IppValueTag.TEXT_WITH_LANGUAGE:
375
            case IppValueTag.TEXT_WITHOUT_LANGUAGE:
376
            case IppValueTag.NAME_WITH_LANGUAGE:
377
            case IppValueTag.NAME_WITHOUT_LANGUAGE:
378
              attribute = IppUtilities.getTextAttribute(name, tag, value);
379
 
380
              break;
381
            case IppValueTag.KEYWORD:
382
              str = new String(value);
383
              if (name.equals("job-hold-until-supported")) // may also be name type
384
                attribute = new JobHoldUntilSupported(str, null);
385
              else if (name.equals("job-hold-until-default"))
386
                attribute = new JobHoldUntilDefault(str, null);
387
              else if (name.equals("media-supported"))
388
                attribute = new MediaSupported(str, null);
389
              else if (name.equals("media-default"))
390
                attribute = new MediaDefault(str, null);
391
              else if (name.equals("job-sheets-default"))
392
                attribute = new JobSheetsDefault(str, null);
393
              else if (name.equals("job-sheets-supported"))
394
                attribute = new JobSheetsSupported(str, null);
395
              else if (name.equals("job-state-reasons")) // setOf
396
                attribute = parseJobStateReasons(value, lastAttribute);
397
              else if (name.equals("printer-state-reasons")) // setOf
398
                attribute = parsePrinterStateReasons(value, lastAttribute);
399
              else
400
                attribute = IppUtilities.getEnumAttribute(name, str);
401
 
402
              // all other stuff is either an enum or needs to be mapped to an
403
              // UnknownAttribute instance. Enums catched here are:
404
              // ipp-versions-supported, pdl-override-supported, compression-supported
405
              // uri-authentication-supported, uri-security-supported, sides-supported
406
              // sides-default, multiple-document-handling-supported, multiple-document-handling-default
407
 
408
              break;
409
            case IppValueTag.URI:
410
              try
411
                {
412
                  uri = new URI(new String(value));
413
                }
414
              catch (URISyntaxException e)
415
                {
416
                  throw new IppException("Wrong URI syntax encountered.", e);
417
                }
418
 
419
              if (name.equals("job-uri"))
420
                attribute = new JobUri(uri);
421
              else if (name.equals("job-printer-uri"))
422
                attribute = new JobPrinterUri(uri);
423
              else if (name.equals("job-more-info"))
424
                attribute = new JobMoreInfo(uri);
425
              else if (name.equals("printer-uri-supported")) // setOf
426
                attribute = new PrinterUriSupported(uri);
427
              else if (name.equals("printer-more-info"))
428
                attribute = new PrinterMoreInfo(uri);
429
              else if (name.equals("printer-driver-installer"))
430
                attribute = new PrinterDriverInstaller(uri);
431
              else if (name.equals("printer-more-info-manufacturer"))
432
                attribute = new PrinterMoreInfoManufacturer(uri);
433
 
434
              break;
435
            case IppValueTag.URI_SCHEME:
436
              // only one uri-scheme exists - and its an enum
437
              if (name.equals("reference-uri-schemes-supported"))
438
                attribute = IppUtilities.getEnumAttribute(name, new String(value));
439
 
440
              break;
441
            case IppValueTag.CHARSET:
442
              str = new String(value);
443
              if (name.equals("attributes-charset"))
444
                attribute = new AttributesCharset(str);
445
              else if (name.equals("charset-configured"))
446
                attribute = new CharsetConfigured(str);
447
              else if (name.equals("charset-supported")) // setOf
448
                attribute = new CharsetSupported(str);
449
 
450
              break;
451
            case IppValueTag.NATURAL_LANGUAGE:
452
              str = new String(value);
453
              if (name.equals("attributes-natural-language"))
454
                attribute = new AttributesNaturalLanguage(str);
455
              else if (name.equals("natural-language-configured"))
456
                attribute = new NaturalLanguageConfigured(str);
457
              else if (name.equals("generated-natural-language-supported")) // setOf
458
                attribute = new GeneratedNaturalLanguageSupported(str);
459
 
460
              break;
461
            case IppValueTag.MIME_MEDIA_TYPE:
462
              str = new String(value);
463
              if (name.equals("document-format-default"))
464
                attribute = new DocumentFormatDefault(str, null);
465
              else if (name.equals("document-format-supported")) // setOf
466
                attribute = new DocumentFormatSupported(str, null);
467
              else if (name.equals("document-format")) // setOf
468
                attribute = new DocumentFormat(str, null);
469
 
470
              break;
471
            default:
472
              throw new IppException("Unknown tag with value "
473
                                     + Integer.toHexString(tag) + " found.");
474
            }
475
 
476
          if (attribute == null)
477
            attribute = new UnknownAttribute(tag, name, value);
478
 
479
          addAttribute(attributes, attribute);
480
          lastAttribute = attribute;
481
 
482
          logger.log(Component.IPP, "Attribute: " + name
483
                     + " Value: " + attribute.toString());
484
        }
485
    }
486
 
487
    /**
488
     * Adds a new attribute to the given attribute group. If this is the fist
489
     * occurence of this attribute category a new set is created and associated
490
     * with its category as key.
491
     * @param attributeGroup
492
     *          the attribute group
493
     * @param attribute
494
     *          the attribute to add
495
     */
496
    private void addAttribute(Map<Class<? extends Attribute>, Set<Attribute>> attributeGroup,
497
                              Attribute attribute)
498
    {
499
      Class<? extends Attribute> clazz = attribute.getCategory();
500
      Set<Attribute> attributeValues = attributeGroup.get(clazz);
501
 
502
      if (attributeValues == null) // first attribute of this category
503
        {
504
          attributeValues = new HashSet<Attribute>();
505
          attributeGroup.put(clazz, attributeValues);
506
        }
507
 
508
      attributeValues.add(attribute);
509
    }
510
 
511
    /**
512
     * Parses a name with or without language attribute value from the byte[]
513
     * and returns the result as an object[].
514
     * @param value the byte[]
515
     * @param lastAttr the last attribute
516
     * @return The attribute.
517
     */
518
    private PrinterStateReasons parsePrinterStateReasons(byte[] value, Attribute lastAttr)
519
    {
520
      String str = new String(value);
521
      PrinterStateReasons attribute;
522
 
523
      if (lastAttr instanceof PrinterStateReasons)
524
        attribute = (PrinterStateReasons) lastAttr;
525
      else
526
        attribute = new PrinterStateReasons();
527
 
528
      // special case indicating no reasons
529
      if (str.equals("none"))
530
        return attribute;
531
 
532
      Severity severity = null;
533
      PrinterStateReason reason = null;
534
 
535
      if (str.endsWith(Severity.WARNING.toString()))
536
        severity = Severity.WARNING;
537
      else if (str.endsWith(Severity.REPORT.toString()))
538
        severity = Severity.REPORT;
539
      else if (str.endsWith(Severity.ERROR.toString()))
540
        severity = Severity.ERROR;
541
 
542
      if (severity != null)
543
        str = str.substring(0, str.lastIndexOf('-'));
544
      else // we must associate a severity
545
        severity = Severity.REPORT;
546
 
547
      reason = (PrinterStateReason)
548
        IppUtilities.getEnumAttribute("printer-state-reason", str);
549
 
550
      attribute.put(reason , severity);
551
      return attribute;
552
    }
553
 
554
    /**
555
     * Parses a name with or without language attribute value from the byte[]
556
     * and returns the result as an object[].
557
     * @param value the byte[]
558
     * @param lastAttr the last attribute
559
     * @return The attribute.
560
     */
561
    private JobStateReasons parseJobStateReasons(byte[] value, Attribute lastAttr)
562
    {
563
      String str = new String(value);
564
      JobStateReasons attribute;
565
 
566
      if (lastAttr instanceof JobStateReasons)
567
        attribute = (JobStateReasons) lastAttr;
568
      else
569
        attribute = new JobStateReasons();
570
 
571
      // special case indicating no reasons
572
      if (str.equals("none"))
573
        return attribute;
574
 
575
      JobStateReason reason = (JobStateReason)
576
        IppUtilities.getEnumAttribute("job-state-reason", str);
577
 
578
      attribute.add(reason);
579
      return attribute;
580
    }
581
 
582
    /**
583
     * Parses a DateTime syntax attribute and returns the constructed Date
584
     * object.
585
     * <p>
586
     * The syntax value is defined as 11 octets follwing the DateAndTime format
587
     * of RFC 1903:
588
     * <ul>
589
     * <li>field | octets | contents | range</li>
590
     * <li>1 | 1-2 | year | 0..65536</li>
591
     * <li>2 | 3 | month | 1..12</li>
592
     * <li>3 | 4 | day | 1..31</li>
593
     * <li>4 | 5 | hour | 0..23</li>
594
     * <li>5 | 6 | minutes | 0..59</li>
595
     * <li>6 | 7 | seconds | 0..60 (use 60 for leap-second)</li>
596
     * <li>7 | 8 | deci-seconds | 0..9</li>
597
     * <li>8 | 9 | direction from UTC | '+' / '-'</li>
598
     * <li>9 | 10 | hours from UTC | 0..11</li>
599
     * <li>10 | 11 | minutes from UTC | 0..59</li>
600
     * </ul>
601
     * </p>
602
     *
603
     * @param value the byte[]
604
     * @return The date object.
605
     */
606
    private Date parseDate(byte[] value)
607
    {
608
      short year = IppUtilities.convertToShort(value[0], value[1]);
609
 
610
      Calendar cal = Calendar.getInstance();
611
      cal.set(Calendar.YEAR, year);
612
      cal.set(Calendar.MONTH, value[2]);
613
      cal.set(Calendar.DAY_OF_MONTH, value[3]);
614
      cal.set(Calendar.HOUR_OF_DAY, value[4]);
615
      cal.set(Calendar.MINUTE, value[5]);
616
      cal.set(Calendar.SECOND, value[6]);
617
      cal.set(Calendar.MILLISECOND, value[7] * 100); // deci-seconds
618
 
619
      // offset from timezone
620
      int offsetMilli = value[9] * 3600000; // hours to millis
621
      offsetMilli = offsetMilli + value[10] * 60000; // minutes to millis
622
 
623
      if (((char) value[8]) == '-')
624
        offsetMilli = offsetMilli * (-1);
625
 
626
      cal.set(Calendar.ZONE_OFFSET, offsetMilli);
627
      return cal.getTime();
628
    }
629
  }
630
 
631
  /**
632
   * Logger for tracing - enable by passing
633
   * -Dgnu.classpath.debug.components=ipp to the vm.
634
   */
635
  static final Logger logger = SystemLogger.SYSTEM;
636
 
637
  URI uri;
638
  short operation_id;
639
  short status_code;
640
  int request_id;
641
 
642
  List<Map<Class<? extends Attribute>, Set<Attribute>>> operationAttributes;
643
  List<Map<Class<? extends Attribute>, Set<Attribute>>> printerAttributes;
644
  List<Map<Class<? extends Attribute>, Set<Attribute>>> jobAttributes;
645
  List<Map<Class<? extends Attribute>, Set<Attribute>>> unsupportedAttributes;
646
 
647
  byte[] data;
648
 
649
  /**
650
   * Creates an <code>IppResponse</code> instance.
651
   *
652
   * @param uri the uri the request was directy to.
653
   * @param operation_id the operation id of the request.
654
   */
655
  public IppResponse(URI uri, short operation_id)
656
  {
657
    this.uri = uri;
658
    this.operation_id = operation_id;
659
    operationAttributes =
660
      new ArrayList<Map<Class<? extends Attribute>, Set<Attribute>>>();
661
    jobAttributes =
662
      new ArrayList<Map<Class<? extends Attribute>, Set<Attribute>>>();
663
    printerAttributes =
664
      new ArrayList<Map<Class<? extends Attribute>, Set<Attribute>>>();
665
    unsupportedAttributes =
666
      new ArrayList<Map<Class<? extends Attribute>, Set<Attribute>>>();
667
  }
668
 
669
  /**
670
   * Sets the data received from the request sent.
671
   *
672
   * @param input the input stream received.
673
   * @throws IppException if parsing fails.
674
   */
675
  protected void setResponseData(InputStream input) throws IppException
676
  {
677
    ResponseReader reader = new ResponseReader();
678
 
679
    try
680
      {
681
        reader.parseResponse(input);
682
      }
683
    catch (IOException e)
684
      {
685
        throw new IppException(
686
            "Exception during response parsing caused by IOException", e);
687
      }
688
  }
689
 
690
  /**
691
   * Returns the uri of the original request.
692
   * @return The URI of the request.
693
   */
694
  public URI getURI()
695
  {
696
    return uri;
697
  }
698
 
699
  /**
700
   * Returns the operation id of the original request.
701
   * @return The operation id of the request.
702
   */
703
  public int getOperationID()
704
  {
705
    return operation_id;
706
  }
707
 
708
  /**
709
   * Returns the set of job attributes group maps.
710
   * There may occur more than one group of type job attribute in a response
711
   * because of e.g. multiple job or print service informations requested.
712
   *
713
   * @return The list of job attribute group maps.
714
   */
715
  public List<Map<Class<? extends Attribute>, Set<Attribute>>> getJobAttributes()
716
  {
717
    return jobAttributes;
718
  }
719
 
720
  /**
721
   * Returns the set of operation attributes group maps.
722
   * There may occur more than one group of type job attribute in a response
723
   * because of e.g. multiple job or print service informations requested.
724
   *
725
   * @return The list of operation attribute group maps.
726
   */
727
  public List<Map<Class<? extends Attribute>, Set<Attribute>>> getOperationAttributes()
728
  {
729
    return operationAttributes;
730
  }
731
 
732
  /**
733
   * Returns the set of printer attributes group maps.
734
   * There may occur more than one group of type job attribute in a response
735
   * because of e.g. multiple job or print service informations requested.
736
   *
737
   * @return The list of printer attribute group maps.
738
   */
739
  public List<Map<Class<? extends Attribute>, Set<Attribute>>> getPrinterAttributes()
740
  {
741
    return printerAttributes;
742
  }
743
 
744
  /**
745
   * Returns the ID of the initial request.
746
   *
747
   * @return The request ID.
748
   */
749
  public int getRequestID()
750
  {
751
    return request_id;
752
  }
753
 
754
  /**
755
   * Returns the status code of the response.
756
   * Defined in {@link IppStatusCode}.
757
   *
758
   * @return The status code.
759
   */
760
  public short getStatusCode()
761
  {
762
    return status_code;
763
  }
764
 
765
  /**
766
   * Returns the set of unsupported attributes group maps.
767
   * There may occur more than one group of type job attribute in a response
768
   * because of e.g. multiple job or print service informations requested.
769
   *
770
   * @return The list of unsupported attribute group maps.
771
   */
772
  public List<Map<Class<? extends Attribute>, Set<Attribute>>> getUnsupportedAttributes()
773
  {
774
    return unsupportedAttributes;
775
  }
776
 
777
  /**
778
   * Returns the data of the response.
779
   *
780
   * @return The data as byte[].
781
   */
782
  public byte[] getData()
783
  {
784
    return data;
785
  }
786
 
787
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.