Skip to content

Commit 87ff7e4

Browse files
authored
Merge pull request #515 from edsiper/unpacker_size
unpack: new msgpack_unpacker_next_with_size() function
2 parents c1f19c0 + da46fb1 commit 87ff7e4

File tree

3 files changed

+105
-3
lines changed

3 files changed

+105
-3
lines changed

include/msgpack/unpack.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,18 @@ static inline void msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, si
146146
MSGPACK_DLLEXPORT
147147
msgpack_unpack_return msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* pac);
148148

149+
/**
150+
* Deserializes one object and set the number of parsed bytes involved.
151+
* Returns true if it successes. Otherwise false is returned.
152+
* @param mpac pointer to an initialized msgpack_unpacker object.
153+
* @param result pointer to an initialized msgpack_unpacked object.
154+
* @param p_bytes pointer to variable that will be set with the number of parsed bytes.
155+
*/
156+
MSGPACK_DLLEXPORT
157+
msgpack_unpack_return msgpack_unpacker_next_with_size(msgpack_unpacker* mpac,
158+
msgpack_unpacked* result,
159+
size_t *p_bytes);
160+
149161
/**
150162
* Initializes a msgpack_unpacked object.
151163
* The initialized object must be destroyed by msgpack_unpacked_destroy(msgpack_unpacker*).
@@ -267,4 +279,3 @@ static inline msgpack_zone* msgpack_unpacked_release_zone(msgpack_unpacked* resu
267279
#endif
268280

269281
#endif /* msgpack/unpack.h */
270-

src/unpack.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,8 @@ void msgpack_unpacker_reset(msgpack_unpacker* mpac)
510510
mpac->parsed = 0;
511511
}
512512

513-
msgpack_unpack_return msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* result)
513+
static inline msgpack_unpack_return unpacker_next(msgpack_unpacker* mpac,
514+
msgpack_unpacked* result)
514515
{
515516
int ret;
516517

@@ -529,11 +530,40 @@ msgpack_unpack_return msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpa
529530
}
530531
result->zone = msgpack_unpacker_release_zone(mpac);
531532
result->data = msgpack_unpacker_data(mpac);
532-
msgpack_unpacker_reset(mpac);
533533

534534
return MSGPACK_UNPACK_SUCCESS;
535535
}
536536

537+
msgpack_unpack_return msgpack_unpacker_next(msgpack_unpacker* mpac,
538+
msgpack_unpacked* result)
539+
{
540+
int ret;
541+
542+
ret = unpacker_next(mpac, result);
543+
if (ret == MSGPACK_UNPACK_SUCCESS) {
544+
msgpack_unpacker_reset(mpac);
545+
}
546+
547+
return ret;
548+
}
549+
550+
msgpack_unpack_return
551+
msgpack_unpacker_next_with_size(msgpack_unpacker* mpac,
552+
msgpack_unpacked* result, size_t *p_bytes)
553+
{
554+
int ret;
555+
556+
ret = unpacker_next(mpac, result);
557+
if (ret == MSGPACK_UNPACK_SUCCESS || ret == MSGPACK_UNPACK_CONTINUE) {
558+
*p_bytes = mpac->parsed;
559+
}
560+
561+
if (ret == MSGPACK_UNPACK_SUCCESS) {
562+
msgpack_unpacker_reset(mpac);
563+
}
564+
565+
return ret;
566+
}
537567

538568
msgpack_unpack_return
539569
msgpack_unpack(const char* data, size_t len, size_t* off,

test/streaming_c.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,64 @@ TEST(streaming, basic)
120120
msgpack_unpacked_destroy(&result);
121121
msgpack_sbuffer_free(buffer);
122122
}
123+
124+
TEST(streaming, basic_with_size)
125+
{
126+
int ret;
127+
size_t bytes;
128+
size_t parsed = 0;
129+
msgpack_sbuffer* buffer = msgpack_sbuffer_new();
130+
msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write);
131+
msgpack_unpacked result;
132+
msgpack_unpacker *unp;
133+
134+
// 1, 2, 3, "str", ["str_data"], "bin", ["bin_data"], {0.3: 0.4}
135+
msgpack_pack_int(pk, 1);
136+
msgpack_pack_int(pk, 2);
137+
msgpack_pack_int(pk, 3);
138+
msgpack_pack_str(pk, 3);
139+
msgpack_pack_str_body(pk, "str", 3);
140+
msgpack_pack_array(pk, 1);
141+
msgpack_pack_str(pk, 8);
142+
msgpack_pack_str_body(pk, "str_data", 8);
143+
msgpack_pack_bin(pk, 3);
144+
msgpack_pack_bin_body(pk, "bin", 3);
145+
msgpack_pack_array(pk, 1);
146+
msgpack_pack_bin(pk, 8);
147+
msgpack_pack_bin_body(pk, "bin_data", 8);
148+
msgpack_pack_map(pk, 1);
149+
msgpack_pack_float(pk, 0.4f);
150+
msgpack_pack_double(pk, 0.8);
151+
msgpack_packer_free(pk);
152+
153+
unp = msgpack_unpacker_new(32 * 1024);
154+
msgpack_unpacked_init(&result);
155+
156+
const char* input = buffer->data;
157+
158+
while (parsed < buffer->size) {
159+
memcpy(msgpack_unpacker_buffer(unp), input, 1);
160+
msgpack_unpacker_buffer_consumed(unp, 1);
161+
input += 1;
162+
163+
bytes = 0;
164+
ret = msgpack_unpacker_next_with_size(unp, &result, &bytes);
165+
if (ret == MSGPACK_UNPACK_CONTINUE) {
166+
EXPECT_GT(bytes, 0);
167+
continue;
168+
}
169+
170+
while (ret == MSGPACK_UNPACK_SUCCESS) {
171+
EXPECT_GT(bytes, 0);
172+
parsed += bytes;
173+
ret = msgpack_unpacker_next_with_size(unp, &result, &bytes);
174+
}
175+
176+
}
177+
178+
EXPECT_EQ(parsed, buffer->size);
179+
180+
msgpack_unpacked_destroy(&result);
181+
msgpack_unpacker_free(unp);
182+
msgpack_sbuffer_free(buffer);
183+
}

0 commit comments

Comments
 (0)