FileDocCategorySizeDatePackage
QueuedHeader.javaAPI DocphoneME MR2 API (J2ME)12436Wed May 02 18:00:32 BST 2007com.sun.kvem.jsr082.obex

QueuedHeader

public class QueuedHeader extends Object

Fields Summary
private static final boolean
DEBUG
Debug information, should be false for RR.
private ObexPacketStream
stream
private int
type
private Object
value
byte[]
buffer
int
packetLength
Constructors Summary
QueuedHeader(ObexPacketStream stream)


      
        this.stream = stream;
    
Methods Summary
private final voidencodeInt(long val)

        buffer[packetLength++] = (byte)(val >> 24);
        buffer[packetLength++] = (byte)(val >> 16);
        buffer[packetLength++] = (byte)(val >> 8);
        buffer[packetLength++] = (byte)val;
    
private final voidencodeLength16(int value)

        buffer[packetLength++] = (byte)(value >> 8);
        buffer[packetLength++] = (byte)value;
    
private final voidencodeTime8601(java.util.Calendar cal)

        encodeLength16(19);

        // copy calendar as it can be with wrong timezone.
        Calendar cal2 = Calendar.getInstance(ObexPacketStream.utcTimeZone);
        cal2.setTime(cal.getTime());
        int year = cal2.get(Calendar.YEAR);
        int month = cal2.get(Calendar.MONTH) + 1; // Calendar.JANUARY = 0
        int date = cal2.get(Calendar.DATE);
        int hour = cal2.get(Calendar.HOUR_OF_DAY);
        int minute = cal2.get(Calendar.MINUTE);
        int second = cal2.get(Calendar.SECOND);
        int zero = 0x30; // zero ('0') code in latin1

        if (year < 0 || year > 9999) {
            if (DEBUG) {
                System.out.println("wrong date header");
            }
        }
        buffer[packetLength++] = (byte)(year / 1000 + zero);
        year = year % 1000;
        buffer[packetLength++] = (byte)(year / 100 + zero);
        year = year % 100;
        buffer[packetLength++] = (byte)(year / 10 + zero);
        year = year % 10;
        buffer[packetLength++] = (byte)(year + zero);
        buffer[packetLength++] = (byte)(month / 10 + zero);
        buffer[packetLength++] = (byte)(month % 10 + zero);
        buffer[packetLength++] = (byte)(date / 10 + zero);
        buffer[packetLength++] = (byte)(date % 10 + zero);
        buffer[packetLength++] = 0x54; // 'T' code in latin1
        buffer[packetLength++] = (byte)(hour / 10 + zero);
        buffer[packetLength++] = (byte)(hour % 10 + zero);
        buffer[packetLength++] = (byte)(minute / 10 + zero);
        buffer[packetLength++] = (byte)(minute % 10 + zero);
        buffer[packetLength++] = (byte)(second / 10 + zero);
        buffer[packetLength++] = (byte)(second % 10 + zero);
        buffer[packetLength++] = (byte)0x5A; // 'Z' code in latin1
    
private voidnewHeader()

        stream.queuedHeaders.addElement(this);
        if (stream.emptyHeadersPool.empty()) {
            stream.newHeader = new QueuedHeader(stream);
        } else {
            stream.newHeader = (QueuedHeader) stream.emptyHeadersPool.pop();
        }
    
voidqueue(int type, java.lang.Object value)
Adds the header to queue in ObexPacketStream.

param
type header's type defined in HeaderSetImpl class.
param
value header's value.
throws
IOException thrown if the header is too large.

        int maxSendLength = stream.maxSendLength;
        boolean fail = false;

        switch (HeaderSetImpl.internalType(type)) {
            // ids which require special handling
            case HeaderSetImpl.TYPE_SPECIAL_TIME_ISO:
            case HeaderSetImpl.TYPE_SPECIAL_TIME_4:
            case HeaderSetImpl.TYPE_LONG:
            case HeaderSetImpl.TYPE_BYTE:
                break;

            case HeaderSetImpl.TYPE_SPECIAL_TYPE:
                // type8 + len16 + head + len16 + bytes[length] + zero8
                if (((String)value).length() + 7 > maxSendLength) {
                    fail = true;
                }
                break;

            case HeaderSetImpl.TYPE_UNICODE:
                // type8 + len16 + head + len16 + bytes[length] + zero16
                if ((((String)value).length() << 1) + 8 > maxSendLength) {
                    fail = true;
                }
                break;

            case HeaderSetImpl.TYPE_BYTEARRAY:
                // type8 + len16 + head + len16 + bytes[length]
                if (((byte[])value).length + 6 > maxSendLength) {
                    fail = true;
                }
                break;

            case HeaderSetImpl.TYPE_AUTH_CHALLENGE:
                Vector challenges = (Vector)value;
                if (challenges.isEmpty())
		    return;
                int len = 0;
                for (int i = 0; i < challenges.size(); i++) {
                    len += ((ObexAuth) challenges.elementAt(i))
                        .prepareChallenge();
                }
                if (len + 3 > maxSendLength) {
                    fail = true;
                }
                break;
        }

        if (fail) {
            stream.headerTooLarge();
            return;
        }
        this.type = type;
        this.value = value;
        newHeader();
    
booleansend(int type, java.lang.Object value)

        buffer = stream.buffer;
        packetLength = stream.packetLength;
        int maxSendLength = stream.maxSendLength;
        if (DEBUG) {
            System.out.println("Sending header 0x" + Integer.toHexString(type));
        }

        try {
            buffer[packetLength++] = (byte)type;
            switch (HeaderSetImpl.internalType(type)) {
                // ids which require special handling
                case HeaderSetImpl.TYPE_SPECIAL_TIME_ISO:
                    encodeTime8601((Calendar)value);
                    break;

                case HeaderSetImpl.TYPE_SPECIAL_TIME_4:
                    encodeInt(((Calendar)value).getTime().getTime() / 1000L);
                    break;

                case HeaderSetImpl.TYPE_SPECIAL_TYPE:
                    byte[] str = ((String)value).getBytes("ISO-8859-1");

                    // head + len16 + bytes[length] + zero8
                    encodeLength16(str.length + 4);
                    System.arraycopy(str, 0, buffer, packetLength,
                            str.length);
                    packetLength += str.length;
                    // null terminator required by protocol spec
                    buffer[packetLength++] = 0;
                    break;

                case HeaderSetImpl.TYPE_AUTH_CHALLENGE:
                    packetLength--;
                    Vector challenges = (Vector) value;

                    stream.authFailed = false;

                    for (int i = 0; i < challenges.size(); i++) {
                        ObexAuth auth = (ObexAuth) challenges.elementAt(i);
                        packetLength += auth.addChallenge(buffer, packetLength);
                    }

                    // need to be shure - challenges are added
                    if (packetLength > maxSendLength) {
                        break;
                    }

                    // if we still there, then authChallenges
		    // successfully added
                    for (int i = 0; i < challenges.size(); i++) {
                        stream.authFailed = true;
                        stream.authChallenges.addElement(
                                challenges.elementAt(i));
                    }
                    break;

                    // normal ids

                    // 4 byte integer values, range (0xC0 - 0xFF)
                    // system and user defined
                case HeaderSetImpl.TYPE_LONG:
                    encodeInt(((Long)value).longValue());
                    break;

                    // unicode encoded string values, range (0x00 - 0x3F)
                    // system and user defined
                case HeaderSetImpl.TYPE_UNICODE:
                    str = ((String)value).getBytes("UTF-16BE");
                    // str = ((String)value).getBytes("ISO-8859-1");

                    // head + len16 + bytes[length] + zero16
                    encodeLength16(str.length + 5);
                    System.arraycopy(str, 0, buffer, packetLength,
                            str.length);
                    packetLength += str.length;
                    // end of unicode string
                    buffer[packetLength++] = 0;
                    buffer[packetLength++] = 0;
                    break;

                    // byte[] array values, range (0x40 - 0x7F)
                    // system and user defined
                case HeaderSetImpl.TYPE_BYTEARRAY:
                    byte[] array = (byte[]) value;

                    // head + len16 + bytes[length]
                    encodeLength16(array.length + 3);
                    System.arraycopy(array, 0, buffer, packetLength,
                            array.length);
                    packetLength += array.length;
                    stream.containsTargetHeader |=
                        (type == HeaderSetImpl.TARGET);
                    break;

                    // byte values, range (0x80 - 0xBF)
                    // user defined
                case HeaderSetImpl.TYPE_BYTE:
                    buffer[packetLength++] =
                        (byte)((Byte)value).byteValue();
                    break;

                    // case HeaderSetImpl.TYPE_UNSUPPORTED:
                default:
                    if (DEBUG) {
                        System.out.println("wrong or unsupported header");
                    }
            }
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.toString());
        } catch (ArrayIndexOutOfBoundsException e) {
            stream.moreHeaders = false;
            return false;
        }
        if (packetLength > maxSendLength) {
            stream.moreHeaders = false;
            return false;
        }

        // finally closing body headers if opened
        if (stream.dataOpened) {
            int dataOffset = stream.dataOffset;
            int len = stream.packetLength - dataOffset;
            buffer[dataOffset+1] = (byte)(len >> 8);
            buffer[dataOffset+2] = (byte)len;
            stream.dataOpened = false;
            stream.dataClosed = true;
        }
        stream.packetLength = packetLength;

        // gc header value
        this.value = null;
        if (DEBUG) {
            System.out.println("  -> sent!");
        }
        return true;
    
booleansendAllQueued()

        while (stream.queuedHeaders.size() > 0 && stream.moreHeaders) {
            QueuedHeader header = (QueuedHeader)
                stream.queuedHeaders.firstElement();
            boolean res = header.trySendAgain();
            if (!res) {
                return false;
            }
            stream.queuedHeaders.removeElementAt(0);
        }
        return true;
    
voidsendOrQueue(int type, java.lang.Object value)

param
type
param
value
throws
IOException

        if (stream.moreHeaders && send(type, value)) {
            stream.challengesToSend = true;
            return;
        }
        queue(type, value);
    
booleantrySendAgain()

        return send(type, value);