Implement raising exceptions
[platform/core/connectivity/smartcard-service.git] / common / SimpleTLV.cpp
1 /*
2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18 /* standard library header */
19 #include <stdio.h>
20 #include <string.h>
21
22 /* SLP library header */
23
24 /* local header */
25 #include "Debug.h"
26 #include "SimpleTLV.h"
27
28 namespace smartcard_service_api
29 {
30         SimpleTLV::SimpleTLV():TLVHelper()
31         {
32         }
33
34         SimpleTLV::SimpleTLV(TLVHelper *parent):TLVHelper(parent)
35         {
36                 parentTLV = parent;
37         }
38
39         SimpleTLV::SimpleTLV(const ByteArray &array):TLVHelper(array)
40         {
41         }
42
43         SimpleTLV::SimpleTLV(const ByteArray &array, TLVHelper *parent):TLVHelper(array, parent)
44         {
45                 parentTLV = parent;
46         }
47
48         SimpleTLV::~SimpleTLV()
49         {
50                 if (childTLV != NULL)
51                 {
52                         delete childTLV;
53                         childTLV = NULL;
54                 }
55         }
56
57         int SimpleTLV::decodeTag(unsigned char *buffer)
58         {
59                 /* 0x00 or 0xFF is invalid tag value */
60                 if (buffer[0] == 0x00 || buffer[0] == 0xFF)
61                 {
62                         return -1;
63                 }
64
65                 currentT = buffer[0];
66
67                 return 1;
68         }
69
70         int SimpleTLV::decodeLength(unsigned char *buffer)
71         {
72                 int count = 0;
73
74                 if (buffer[0] == 0xFF)
75                 {
76                         /* 3 bytes length */
77                         currentL = (buffer[1] << 8) | buffer[2];
78                         count = 3;
79                 }
80                 else
81                 {
82                         /* 1 byte length */
83                         currentL = buffer[0];
84                         count = 1;
85                 }
86
87                 return count;
88         }
89
90         int SimpleTLV::decodeValue(unsigned char *buffer)
91         {
92                 if (currentL == 0)
93                         return 0;
94
95                 currentV.setBuffer(buffer, currentL);
96
97                 return currentL;
98         }
99
100         ByteArray SimpleTLV::encode(unsigned int tag, ByteArray buffer)
101         {
102                 bool isLongBuffer = false;
103                 ByteArray result;
104                 unsigned int total_len = 0;
105                 unsigned int current = 0;
106                 unsigned char *temp_buffer = NULL;
107
108                 /* add tag's length */
109                 total_len += 1;
110
111                 /* add length's length */
112                 if (buffer.getLength() < 255)
113                 {
114                         total_len += 1;
115                 }
116                 else if (buffer.getLength() < 65536)
117                 {
118                         total_len += 3;
119                         isLongBuffer = true;
120                 }
121                 else
122                 {
123                         return result;
124                 }
125
126                 /* add buffer's length */
127                 total_len += buffer.getLength();
128
129                 /* alloc new buffer */
130                 temp_buffer = new unsigned char[total_len];
131                 if (temp_buffer == NULL)
132                 {
133                         return result;
134                 }
135                 memset(temp_buffer, 0, total_len);
136
137                 /* fill tag */
138                 temp_buffer[current++] = (unsigned char)tag;
139
140                 /* fill length */
141                 if (isLongBuffer == true)
142                 {
143                         temp_buffer[current++] = (unsigned char)(0xFF);
144                         temp_buffer[current++] = (unsigned char)(buffer.getLength() >> 8);
145                         temp_buffer[current++] = (unsigned char)(buffer.getLength());
146                 }
147                 else
148                 {
149                         temp_buffer[current++] = (unsigned char)(buffer.getLength());
150                 }
151
152                 /* fill value */
153                 if (buffer.getLength() > 0)
154                         memcpy(temp_buffer + current, buffer.getBuffer(), buffer.getLength());
155
156                 result.setBuffer(temp_buffer, total_len);
157
158                 delete []temp_buffer;
159
160                 return result;
161         }
162
163         ByteArray SimpleTLV::encode(unsigned int tag, unsigned char *buffer, unsigned int length)
164         {
165                 return encode(tag, ByteArray(buffer, length));
166         }
167
168         TLVHelper *SimpleTLV::getChildTLV(ByteArray data)
169         {
170                 if (childTLV != NULL)
171                 {
172                         delete childTLV;
173                         childTLV = NULL;
174                 }
175                 childTLV = new SimpleTLV(data, this);
176
177                 return (TLVHelper *)childTLV;
178         }
179
180         ByteArray SimpleTLV::getOctetString(const ByteArray &array)
181         {
182                 SimpleTLV tlv(array);
183
184                 return SimpleTLV::getOctetString(tlv);
185         }
186
187         ByteArray SimpleTLV::getOctetString(SimpleTLV &tlv)
188         {
189                 ByteArray result;
190
191                 if (tlv.decodeTLV() == true && tlv.getTag() == 0x04) /* OCTET STRING */
192                 {
193                         result = tlv.getValue();
194                 }
195                 else
196                 {
197                         SCARD_DEBUG_ERR("getOctetString failed (0x%02X)", tlv.getTag());
198                 }
199
200                 return result;
201         }
202
203         bool SimpleTLV::getBoolean(const ByteArray &array)
204         {
205                 SimpleTLV tlv(array);
206
207                 return SimpleTLV::getBoolean(tlv);
208         }
209
210         bool SimpleTLV::getBoolean(SimpleTLV &tlv)
211         {
212                 bool result = false;
213
214                 if (tlv.decodeTLV() == true && tlv.getTag() == 0x80) /* BOOLEAN */
215                 {
216                         if (tlv.getValue().getAt(0) == 0)
217                                 result = false;
218                         else
219                                 result = true;
220                 }
221                 else
222                 {
223                         SCARD_DEBUG_ERR("getBoolean failed (0x%02X)", tlv.getTag());
224                 }
225
226                 return result;
227         }
228
229         int SimpleTLV::getInteger(const ByteArray &array)
230         {
231                 SimpleTLV tlv(array);
232
233                 return SimpleTLV::getInteger(tlv);
234         }
235
236         int SimpleTLV::getInteger(SimpleTLV &tlv)
237         {
238                 int result = 0;
239
240                 if (tlv.decodeTLV() == true && tlv.getTag() == 0x80) /* TODO : INTEGER */
241                 {
242                 }
243                 else
244                 {
245                         SCARD_DEBUG_ERR("getInteger failed (0x%02X)", tlv.getTag());
246                 }
247
248                 return result;
249         }
250 } /* namespace smartcard_service_api */