forked from dxFeed/dxfeed-c-api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathConfigurationDeserializer.c
115 lines (103 loc) · 3.38 KB
/
ConfigurationDeserializer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
* The contents of this file are subject to the Mozilla Public License Version
* 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Initial Developer of the Original Code is Devexperts LLC.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*/
#include <stdint.h>
#include <string.h>
#include "ConfigurationDeserializer.h"
#include "DXAlgorithms.h"
#include "DXErrorHandling.h"
typedef int dx_byte_array_pos_t;
static const dxf_short_t STREAM_MAGIC = (dxf_short_t)0xACED;
static const dxf_short_t STREAM_VERSION = 5;
#define TC_NULL 0x70
#define TC_STRING 0x74
#define TC_LONGSTRING 0x7C
#define READ_MULTIMBYTE_VALUE_BODY(multibyte_type, alias) \
static int read_##alias(dxf_byte_array_t* object, dx_byte_array_pos_t *pos, \
OUT multibyte_type *value) { \
dx_byte_array_pos_t last = *pos + sizeof(dxf_short_t); \
if (last >= object->size) \
return false; \
*value = 0; \
for (; *pos < last; (*pos)++) { \
*value = ((*value) << 8) | (dxf_ubyte_t)object->elements[*pos]; \
} \
return true; \
}
READ_MULTIMBYTE_VALUE_BODY(dxf_short_t, short)
READ_MULTIMBYTE_VALUE_BODY(dxf_long_t, long)
static int read_byte(dxf_byte_array_t* object, dx_byte_array_pos_t *pos,
OUT dxf_byte_t *value) {
dx_byte_array_pos_t last = *pos + sizeof(dxf_byte_t);
if (last >= object->size)
return false;
*value = object->elements[(*pos)++];
return true;
}
static int read_string(dxf_byte_array_t* object, dx_byte_array_pos_t *pos,
size_t length, OUT dxf_string_t *value) {
char *buf = NULL;
buf = dx_calloc(length + 1, sizeof(char));
if (buf == NULL)
return false;
strncpy(buf, (void*)&(object->elements[*pos]), length);
*value = dx_ansi_to_unicode(buf);
dx_free(buf);
return true;
}
int dx_configuration_deserialize_string(dxf_byte_array_t* object,
OUT dxf_string_t* string) {
dx_byte_array_pos_t pos = 0;
dxf_short_t short_value;
dxf_byte_t serialize_type;
dxf_long_t long_value;
if (!read_short(object, &pos, &short_value)
|| (short_value != STREAM_MAGIC)) {
return dx_set_error_code(dx_csdec_protocol_error);
}
if (!read_short(object, &pos, &short_value)
|| (short_value != STREAM_VERSION)) {
return dx_set_error_code(dx_csdec_unsupported_version);
}
if (!read_byte(object, &pos, &serialize_type))
return dx_set_error_code(dx_csdec_protocol_error);
switch (serialize_type)
{
case TC_STRING:
if (!read_short(object, &pos, &short_value)
|| !read_string(object, &pos, short_value, string)) {
return dx_set_error_code(dx_csdec_protocol_error);
}
break;
case TC_LONGSTRING:
if (!read_long(object, &pos, &long_value))
return dx_set_error_code(dx_csdec_protocol_error);
if (long_value >= SIZE_MAX)
return dx_set_error_code(dx_ec_invalid_func_param_internal);
if (!read_string(object, &pos, (size_t)long_value, string))
return false;
break;
case TC_NULL:
/* go through */
default:
/* In case of TC_NULL or unsupported types just exit and remain
OUT string empty */
break;
}
return true;
}