001    /**
002     * Copyright (C) 2010, Skype Limited
003     *
004     * All intellectual property rights, including but not limited to copyrights,
005     * trademarks and patents, as well as know how and trade secrets contained in,
006     * relating to, or arising from the internet telephony software of
007     * Skype Limited (including its affiliates, "Skype"), including without
008     * limitation this source code, Skype API and related material of such
009     * software proprietary to Skype and/or its licensors ("IP Rights") are and
010     * shall remain the exclusive property of Skype and/or its licensors.
011     * The recipient hereby acknowledges and agrees that any unauthorized use of
012     * the IP Rights is a violation of intellectual property laws.
013     *
014     * Skype reserves all rights and may take legal action against infringers of
015     * IP Rights.
016     *
017     * The recipient agrees not to remove, obscure, make illegible or alter any
018     * notices or indications of the IP Rights and/or Skype's rights and
019     * ownership thereof.
020     */
021    
022    package com.skype.ipc;
023    
024    import java.io.IOException;
025    
026    import com.skype.util.Log;
027    
028    public class PropertyChange extends AbstractDecoder
029    {
030        private static final String TAG = "PropertyChange";
031        public int                  moid;
032        public int                  oid;
033        public int                  propid;
034        public int                  kind;
035        private Object              val;
036        private boolean             invalid;
037    
038        PropertyChange(Transport in) throws IOException
039        {
040            super(in);
041            // <modid><oid><typetag or N><propid><propvalueaccordingtotype or
042            // nothing if N>]]]z
043            invalid = false;
044            val = null;
045            moid = decodeVaruint();
046            oid = decodeVaruint();
047            kind = ioTransport.read();
048            propid = decodeVaruint();
049    
050            Log.d(TAG, "Property change moid=" + moid + ",oid=" + oid + ",kind='" + (char) kind + "',propid=" + propid + ".");
051    
052            if (kind != 'N') {
053                val = decodeOneOfKind(kind);
054            }
055            
056            // check for known future protocol change
057            if (ioTransport.peek() == ',') {
058                invalid = true;
059                throw new IOException("Multiple property changes in single message are not supported (yet)!");
060            }
061            
062            if (ioTransport.read() != ']' ||
063                    ioTransport.read() != ']' ||
064                    ioTransport.read() != ']' ||
065                    ioTransport.read() != 'z')
066            {
067                Log.e(TAG, "Propertychange with unregognized extra bytes.");
068                invalid = true;
069            }
070            else {
071                Log.d(TAG, "Propertychange moid=" + moid + ",oid=" + oid + ",kind='" + (char) kind + "',propid=" + propid + " decoded successfully.");
072                return;
073            }
074        }
075    
076        private void CheckValidity() throws IOException
077        {
078            if (invalid) {
079                throw new IOException("Attempt to access malformed PropertyChange.");
080            }
081            
082            if (val == null) {
083                Log.e(TAG, "Attempt to read PropertyChange which has no value. Please add check for hasValue().");
084            }
085        }
086    
087        public boolean hasValue()
088        {
089            return (!invalid && val != null);
090        }
091    
092        public boolean isValid()
093        {
094            return (!invalid);
095        }
096    
097        public int GetKind()
098        {
099            return kind;
100        }
101    
102        public int GetOid()
103        {
104            return oid;
105        }
106    
107        public int GetPropid()
108        {
109            return propid;
110        }
111    
112        public int GetAsInt() throws IOException
113        {
114            CheckValidity();
115            return ((Number) val).intValue();
116        }
117    
118        public boolean GetAsBoolean() throws IOException
119        {
120            CheckValidity();
121            return (((Number) val).intValue() != 0);
122        }
123    
124        public String GetAsString() throws IOException
125        {
126            CheckValidity();
127            return (String) val;
128        }
129    
130        public byte[] GetAsBinary(int tag) throws IOException
131        {
132            CheckValidity();
133            return (byte[]) val;
134        }
135    
136    }