79e26dea1aa3d2cd0aae4e188e4acae1f09a42d3
[packetcable.git] / packetcable-driver / src / main / java / org / pcmm / base / impl / PCMMBaseObject.java
1 /**
2  * 
3  */
4 package org.pcmm.base.impl;
5
6 import java.io.IOException;
7 import java.net.Socket;
8 import java.util.Arrays;
9
10 import org.pcmm.base.IPCMMBaseObject;
11 import org.umu.cops.stack.COPSData;
12
13 /**
14  * 
15  * Implementation of the base class {@link IPCMMBaseObject}
16  * 
17  */
18 public class PCMMBaseObject /* extends COPSPrObjBase */implements
19                 IPCMMBaseObject {
20
21         private byte sType;
22         private byte sNum;
23         private short len;
24         private COPSData copsData;
25         private COPSData pad;
26         protected final short offset = (short) 4;
27
28         public PCMMBaseObject(byte[] data) {
29                 parse(data);
30         }
31
32         public PCMMBaseObject(short len, byte sType, byte sNum) {
33                 this.len = (len);
34                 this.sType = (sType);
35                 this.sNum = (sNum);
36                 byte[] array = new byte[len - offset];
37                 Arrays.fill(array, (byte) 0);
38                 setData(new COPSData(array, 0, array.length));
39         }
40
41         protected COPSData getPadding(int len) {
42                 byte[] padBuf = new byte[len];
43                 Arrays.fill(padBuf, (byte) 0);
44                 COPSData d = new COPSData(padBuf, 0, len);
45                 return d;
46         }
47
48         /**
49          * Add head padding to the specified byte array filled with zeros
50          * 
51          * @param off
52          *            offset
53          * @param array
54          *            input array
55          * @return byte array
56          */
57         protected byte[] headPadding(int off, byte[] array) {
58                 byte[] returnArray = new byte[array.length + off];
59                 Arrays.fill(returnArray, (byte) 0);
60                 System.arraycopy(array, 0, returnArray, off, array.length);
61                 return returnArray;
62         }
63
64         protected void parse(byte[] data) {
65                 if (data == null || data.length == 0)
66                         throw new IllegalArgumentException("data could not be null");
67                 len = 0;
68                 len |= ((short) data[0]) << 8;
69                 len |= ((short) data[1]) & 0xFF;
70                 sNum = data[2];
71                 sType = data[3];
72                 copsData = new COPSData(data, offset, data.length - offset);
73         }
74
75         protected void setShort(short value, short startPos) {
76                 byte[] data = getData().getData();
77                 data[startPos] = (byte) (value >> 8);
78                 data[startPos + 1] = (byte) value;
79                 setData(new COPSData(data, 0, data.length));
80         }
81
82         protected short getShort(short startPos) {
83                 byte[] data = getData().getData();
84                 short retVal = 0;
85                 retVal |= ((short) data[startPos]) << 8;
86                 retVal |= ((short) data[startPos + 1]) & 0xFF;
87                 return retVal;
88         }
89
90         protected void setInt(int value, short startPos) {
91                 byte[] data = getData().getData();
92                 data[startPos] = (byte) (value >> 24);
93                 data[startPos + 1] = (byte) (value >> 16);
94                 data[startPos + 2] = (byte) (value >> 8);
95                 data[startPos + 3] = (byte) value;
96                 setData(new COPSData(data, 0, data.length));
97         }
98
99         protected int getInt(short startPos) {
100                 byte[] data = getData().getData();
101                 int retVal = 0;
102                 retVal |= ((short) data[startPos]) << 24;
103                 retVal |= ((short) data[startPos + 1]) << 16;
104                 retVal |= ((short) data[startPos + 2]) << 8;
105                 retVal |= ((short) data[startPos + 3]) & 0xFF;
106                 return retVal;
107         }
108
109         protected void setBytes(byte[] value, short startPos) {
110                 byte[] data = getData().getData();
111                 for (byte b : value)
112                         data[startPos++] = b;
113                 setData(new COPSData(data, 0, data.length));
114         }
115
116         protected byte[] getBytes(short startPos, short size) {
117                 return Arrays.copyOfRange(getData().getData(), startPos, startPos
118                                 + size);
119         }
120
121         protected void setByte(byte value, short startPos) {
122                 setBytes(new byte[] { value }, startPos);
123         }
124
125         protected byte getByte(short startPos) {
126                 return getBytes(startPos, (short) 1)[0];
127         }
128
129         /*
130          * (non-Javadoc)
131          * 
132          * @see org.pcmm.base.IPCMMBaseObject#setSType(byte)
133          */
134         @Override
135         public void setSType(byte stype) {
136                 this.sType = stype;
137
138         }
139
140         /*
141          * (non-Javadoc)
142          * 
143          * @see org.pcmm.base.IPCMMBaseObject#getSType()
144          */
145         @Override
146         public byte getSType() {
147                 return sType;
148         }
149
150         /*
151          * (non-Javadoc)
152          * 
153          * @see org.pcmm.base.IPCMMBaseObject#setSNum(byte)
154          */
155         @Override
156         public void setSNum(byte snum) {
157                 this.sNum = snum;
158         }
159
160         /*
161          * (non-Javadoc)
162          * 
163          * @see org.pcmm.base.IPCMMBaseObject#getSNum()
164          */
165         @Override
166         public byte getSNum() {
167                 return sNum;
168         }
169
170         /*
171          * (non-Javadoc)
172          * 
173          * @see org.pcmm.base.IPCMMBaseObject#setLength(short)
174          */
175         @Override
176         public void setLength(short len) {
177                 this.len = len;
178         }
179
180         /*
181          * (non-Javadoc)
182          * 
183          * @see org.pcmm.base.IPCMMBaseObject#getLength()
184          */
185         @Override
186         public short getLength() {
187                 return (short) (len + (pad != null ? pad.length() : 0));
188         }
189
190         /*
191          * (non-Javadoc)
192          * 
193          * @see org.pcmm.base.IPCMMBaseObject#setData(org.umu.cops.stack.COPSData)
194          */
195         @Override
196         public void setData(COPSData data) {
197                 this.copsData = data;
198                 if (data.length() % offset != 0) {
199                         int padLen = offset - (data.length() % offset);
200                         pad = getPadding(padLen);
201                 }
202                 len = (short) (data.length() + offset);
203         }
204
205         /*
206          * (non-Javadoc)
207          * 
208          * @see org.pcmm.base.IPCMMBaseObject#getData()
209          */
210         @Override
211         public COPSData getData() {
212                 return copsData;
213         }
214
215         /*
216          * (non-Javadoc)
217          * 
218          * @see org.pcmm.base.IPCMMBaseObject#writeData(java.net.Socket)
219          */
220         public void writeData(Socket id) throws IOException {
221                 byte[] data = getAsBinaryArray();
222                 id.getOutputStream().write(data, 0, data.length);
223         }
224
225         /*
226          * (non-Javadoc)
227          * 
228          * @see org.pcmm.base.IPCMMBaseObject#getAsBinaryArray()
229          */
230         @Override
231         public byte[] getAsBinaryArray() {
232                 byte[] array = new byte[getLength()];
233                 array[0] = (byte) (len >> 8);
234                 array[1] = (byte) len;
235                 array[2] = sNum;
236                 array[3] = sType;
237                 System.arraycopy(getData().getData(), 0, array, offset, getData()
238                                 .length());
239                 if (pad != null)
240                         System.arraycopy(pad.getData(), 0, array, offset
241                                         + getData().length(), pad.length());
242                 return array;
243         }
244 }