388eba323edc050177eddb3485e553c72fd7facc
[platform/core/messaging/email-service.git] / email-ipc / email-ipc-api / email-ipc-param-list.c
1 /*
2 *  email-service
3 *
4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5 *
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 */
21
22
23 #include <string.h>
24 #include <stdlib.h>
25 #include <malloc.h>
26
27 #include "email-ipc-build.h"
28 #include "email-ipc-param-list.h"
29
30 #include "email-debug-log.h"
31 #include "email-utilities.h"
32
33 /*  stream */
34 /*  +----------------------------------------------------------------------------------------------------------+ */
35 /*  | API ID(4B) | Resp. ID (4B) | Param Count(4B) | Param1 Len | Param1 Data | ... | ParamN Len | ParamN data |  */
36 /*  +----------------------------------------------------------------------------------------------------------+ */
37
38
39 EXPORT_API emipc_param_list *emipc_create_param_list()
40 {
41         emipc_param_list *new_param_list = NULL;
42
43         new_param_list = (emipc_param_list *) em_malloc (sizeof(emipc_param_list));
44         if (new_param_list == NULL) {
45                 EM_DEBUG_EXCEPTION("em_malloc failed.");
46                 return NULL;
47         }
48         memset(new_param_list, 0x00, sizeof(emipc_param_list));
49
50         return new_param_list;
51 }
52
53 EXPORT_API bool emipc_destroy_param_list(emipc_param_list *param_list)
54 {
55         int count = 10;
56         int index = 0;
57
58         if (!param_list) {
59                 EM_DEBUG_EXCEPTION("Invalid parameter.");
60                 return false;
61         }
62
63         for (index = 0; index < count; index++) {
64                 emipc_free_param(param_list->params[index]);
65         }
66         EM_SAFE_FREE(param_list->byte_stream);
67         EM_SAFE_FREE(param_list);
68         return true;
69 }
70
71 /* making stream into param length and param data */
72 EXPORT_API bool emipc_parse_stream_of_param_list(emipc_param_list *param_list, void *stream)
73 {
74         EM_DEBUG_FUNC_BEGIN();
75         long parameter_count = *((long *)stream + eSTREAM_COUNT);
76         if(parameter_count <= 0) {
77                 EM_DEBUG_EXCEPTION("INVALID_PARAM : count %d", parameter_count);
78                 return false;
79         }
80
81         int stream_len = malloc_usable_size(stream);
82         int remain_len = stream_len - (sizeof(long) * eSTREAM_DATA);
83         EM_DEBUG_LOG("Allocated stream size : %dbyte", stream_len);
84
85         unsigned char* cur = ((unsigned char*)stream) + sizeof(int)*eSTREAM_DATA;
86
87         int i = 0;
88         /* stream is composed of data type which is encoded into length and data field */
89         int len = 0;
90         for(i = 0; i < parameter_count; i++) {
91
92                 if (remain_len < sizeof(int)) {
93                         EM_DEBUG_EXCEPTION("Not enough remain stream_len[%d]", remain_len);
94                         return false;
95                 }
96
97                 /* reading length */
98                 memcpy(&len, cur, sizeof(int));
99
100                 /* moving from length field to data field */
101                 cur += sizeof(int);
102                 remain_len -= sizeof(int);
103
104                 if (remain_len > 0 && len > 0 && remain_len >= len)
105                         emipc_add_param_to_param_list(param_list, (void*)cur, len);
106                 else {
107                         EM_DEBUG_EXCEPTION("data_len[%d] is not in the boundary of remain stream_len", len);
108                         return false;
109                 }
110
111                 EM_DEBUG_LOG("Parsing stream : element %d is %dbyte long ", i, len);
112
113                 /*  move to next parameter       */
114                 cur += len;
115                 remain_len -= len;
116         }
117
118         EM_DEBUG_FUNC_END();
119         return true;
120 }
121
122 EXPORT_API unsigned char *emipc_serialize_param_list(emipc_param_list *param_list, int *stream_length)
123 {
124         EM_DEBUG_FUNC_BEGIN();
125         if(param_list->byte_stream)
126                 return param_list->byte_stream;
127
128         int stream_len = emipc_sum_param_list_length (param_list);
129
130         if (stream_len <= 0) {
131                 EM_DEBUG_EXCEPTION("stream_len error %d", stream_len);
132                 EM_SAFE_FREE(param_list->byte_stream);
133                 return NULL;
134         }
135
136         param_list->byte_stream = (unsigned char*)calloc(1, stream_len);
137         int pos = sizeof(long)*eSTREAM_COUNT;
138
139         if (pos + (int)sizeof(param_list->param_count) > stream_len ) {
140                 EM_DEBUG_EXCEPTION("%d > stream_len", pos + sizeof(param_list->param_count));
141                 EM_SAFE_FREE(param_list->byte_stream);
142                 return NULL;
143         }
144
145         memcpy((param_list->byte_stream + pos), &param_list->param_count, sizeof(param_list->param_count));
146
147         pos += sizeof(long);
148         int index = 0, length = 0;
149
150         /* stream format */
151         /* | param1 length | (param1 data) | param2 length | (param2 data) | ... |*/
152         /* if param is 0 long, the param data is omitted */
153         for(index=0; index<param_list->param_count; index++) {
154                 length = emipc_get_length(param_list->params[index]);
155                 if (length < 0) {
156                         EM_DEBUG_EXCEPTION("index = %d, length = %d", index, length);
157                         EM_SAFE_FREE(param_list->byte_stream);
158                         return NULL;
159                 }
160
161                 if (pos + (int)sizeof(long) > stream_len) {
162                         EM_DEBUG_EXCEPTION("%d > stream_len", pos + sizeof(long));
163                         EM_SAFE_FREE(param_list->byte_stream);
164                         return NULL;
165                 }
166                 /* write param i length */
167                 memcpy((param_list->byte_stream+pos), &length, sizeof(long));
168                 pos += sizeof(long);
169
170                 if (pos + length > stream_len) {
171                         EM_DEBUG_EXCEPTION("%d > stream_len", pos + length);
172                         EM_SAFE_FREE(param_list->byte_stream);
173                         return NULL;
174                 }
175                 /* write param i data if length is greater than 0 */
176                 if( length > 0 ) {
177                         memcpy((param_list->byte_stream+pos), emipc_get_data(param_list->params[index]), length);
178                         pos += length;
179                 }
180         }
181         *stream_length = stream_len;
182
183         EM_DEBUG_FUNC_END();
184         return param_list->byte_stream;
185 }
186
187 EXPORT_API int emipc_sum_param_list_length(emipc_param_list *param_list)
188 {
189         int length = sizeof(long) * eSTREAM_DATA;
190         int index;
191         for (index = 0; index < param_list->param_count; index++) {
192                 length += sizeof(long);
193                 length += emipc_get_length(param_list->params[index]);
194         }
195         return length;
196 }
197
198 EXPORT_API bool emipc_add_param_to_param_list(emipc_param_list *param_list, void *data, int len)
199 {
200         EM_DEBUG_FUNC_BEGIN();
201         if (emipc_set_param(&(param_list->params[param_list->param_count]), data, len)) {
202                 param_list->param_count++;
203                 EM_SAFE_FREE(param_list->byte_stream);
204                 return true;
205         }
206         return false;
207 }
208
209 EXPORT_API void emipc_add_dynamic_param_to_param_list(emipc_param_list *param_list, void *data, int len)
210 {
211         EM_DEBUG_FUNC_BEGIN();
212         emipc_set_dynamic_param(&(param_list->params[param_list->param_count]), data, len);
213         param_list->param_count++;
214         EM_SAFE_FREE(param_list->byte_stream);
215 }
216
217 EXPORT_API void *emipc_get_param_of_param_list(emipc_param_list *param_list, int index)
218 {
219         EM_DEBUG_FUNC_BEGIN("index [%d]", index);
220         if (index < 0 || index >= param_list->param_count) {
221                 EM_DEBUG_EXCEPTION("Index value is not valid");
222                 return NULL;
223         }
224         return emipc_get_data(param_list->params[index]);
225 }
226
227 EXPORT_API int emipc_get_param_len_of_param_list(emipc_param_list *param_list, int index)
228 {
229         EM_DEBUG_FUNC_BEGIN();
230         if (index < 0 || index >= param_list->param_count) {
231                 EM_DEBUG_EXCEPTION("Index valud is not valid");
232                 return 0;
233         }
234         return emipc_get_length(param_list->params[index]);
235 }
236
237