forked from apache/cassandra-python-driver
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcql_type_map.cpp
More file actions
140 lines (114 loc) · 3.76 KB
/
cql_type_map.cpp
File metadata and controls
140 lines (114 loc) · 3.76 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include "cql_types.hpp"
#include "cql_type_factory.hpp"
#include "marshal.hpp"
using namespace pyccassandra;
CqlMapType::CqlMapType(CqlType* keyType,
CqlType* valueType,
PyObject* pyMapType)
: _keyType(keyType),
_valueType(valueType),
_pyMapType(pyMapType)
{
}
CqlMapType::~CqlMapType()
{
delete _keyType;
delete _valueType;
}
PyObject* CqlMapType::Deserialize(Buffer& buffer, int protocolVersion)
{
// Determine the number of items in the set.
std::size_t itemCount;
std::size_t sizeSize = (protocolVersion >= 3 ? 4 : 2);
const unsigned char* itemCountData = buffer.Consume(sizeSize);
if (!itemCountData)
{
PyErr_SetString(PyExc_EOFError,
"unexpected end of buffer while reading map "
"item count");
return NULL;
}
itemCount = (protocolVersion >= 3 ?
UnpackInt32(itemCountData) :
UnpackInt16(itemCountData));
// Initialize a tuple to contain the items.
ScopedReference tuple(PyTuple_New(itemCount));
if (!tuple)
return NULL;
// Drain the items from the set.
for (std::size_t i = 0; i < itemCount; ++i)
{
// Read the size of the key.
const unsigned char* sizeData = buffer.Consume(sizeSize);
const unsigned char* itemData;
if (!sizeData)
{
PyErr_SetString(PyExc_EOFError,
"unexpected end of buffer while reading map "
"key size");
return NULL;
}
int32_t size = (protocolVersion >= 3 ?
UnpackInt32(sizeData) :
UnpackInt16(sizeData));
ScopedReference key;
if (size < 0)
key = _keyType->Empty();
else
{
// Create a local buffer for the key.
itemData = buffer.Consume(size);
if (!itemData)
{
PyErr_SetString(PyExc_EOFError,
"unexpected end of buffer while reading map "
"key data");
return NULL;
}
Buffer keyBuffer(itemData, size);
key = _keyType->Deserialize(keyBuffer, protocolVersion);
if (!key)
return NULL;
}
// Read the size of the value.
sizeData = buffer.Consume(sizeSize);
if (!sizeData)
{
PyErr_SetString(PyExc_EOFError,
"unexpected end of buffer while reading map "
"value size");
return NULL;
}
size = (protocolVersion >= 3 ?
UnpackInt32(sizeData) :
UnpackInt16(sizeData));
ScopedReference value;
if (size < 0)
value = _valueType->Empty();
else
{
// Create a local buffer for the value.
itemData = buffer.Consume(size);
if (!itemData)
{
PyErr_SetString(PyExc_EOFError,
"unexpected end of buffer while reading map "
"value");
return NULL;
}
Buffer valueBuffer(itemData, size);
value = _valueType->Deserialize(valueBuffer, protocolVersion);
if (!value)
return NULL;
}
PyObject* pair = PyTuple_Pack(2, key.Get(), value.Get());
if (!pair)
return NULL;
PyTuple_SetItem(tuple.Get(), i, pair);
}
// Construct a map from the tuple.
ScopedReference args(PyTuple_Pack(1, tuple.Get()));
if (!args)
return NULL;
return PyObject_CallObject(_pyMapType, args.Get());
}