[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/WanderWalker/msgpack/java-0.5.1/python/msgpack/unpack_template.h [Back]  [Original]

/*
 * MessagePack unpacking routine template
 *
 * Copyright (C) 2008-2009 FURUHASHI Sadayuki
 *
 *    Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#ifndef msgpack_unpack_func
#error msgpack_unpack_func template is not defined
#endif

#ifndef msgpack_unpack_callback
#error msgpack_unpack_callback template is not defined
#endif

#ifndef msgpack_unpack_struct
#error msgpack_unpack_struct template is not defined
#endif

#ifndef msgpack_unpack_struct_decl
#define msgpack_unpack_struct_decl(name) msgpack_unpack_struct(name)
#endif

#ifndef msgpack_unpack_object
#error msgpack_unpack_object type is not defined
#endif

#ifndef msgpack_unpack_user
#error msgpack_unpack_user type is not defined
#endif

#ifndef USE_CASE_RANGE
#if !defined(_MSC_VER)
#define USE_CASE_RANGE
#endif
#endif

msgpack_unpack_struct_decl(_stack) {
	msgpack_unpack_object obj;
	size_t count;
	unsigned int ct;

    union {
        size_t curr;
        msgpack_unpack_object map_key;
    };
};

msgpack_unpack_struct_decl(_context) {
	msgpack_unpack_user user;
	unsigned int cs;
	unsigned int trail;
	unsigned int top;
	msgpack_unpack_struct(_stack) stack[MSGPACK_MAX_STACK_SIZE];
};


msgpack_unpack_func(void, _init)(msgpack_unpack_struct(_context)* ctx)
{
	ctx->cs = CS_HEADER;
	ctx->trail = 0;
	ctx->top = 0;
	ctx->stack[0].obj = msgpack_unpack_callback(_root)(&ctx->user);
}

msgpack_unpack_func(msgpack_unpack_object, _data)(msgpack_unpack_struct(_context)* ctx)
{
	return (ctx)->stack[0].obj;
}


msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off)
{
	assert(len >= *off);

	const unsigned char* p = (unsigned char*)data + *off;
	const unsigned char* const pe = (unsigned char*)data + len;
	const void* n = NULL;

	unsigned int trail = ctx->trail;
	unsigned int cs = ctx->cs;
	unsigned int top = ctx->top;
	msgpack_unpack_struct(_stack)* stack = ctx->stack;
	msgpack_unpack_user* user = &ctx->user;

	msgpack_unpack_object obj;
	msgpack_unpack_struct(_stack)* c = NULL;

	int ret;

#define push_simple_value(func) \
	if(msgpack_unpack_callback(func)(user, &obj) < 0) { goto _failed; } \
	goto _push
#define push_fixed_value(func, arg) \
	if(msgpack_unpack_callback(func)(user, arg, &obj) < 0) { goto _failed; } \
	goto _push
#define push_variable_value(func, base, pos, len) \
	if(msgpack_unpack_callback(func)(user, \
		(const char*)base, (const char*)pos, len, &obj) < 0) { goto _failed; } \
	goto _push

#define again_fixed_trail(_cs, trail_len) \
	trail = trail_len; \
	cs = _cs; \
	goto _fixed_trail_again
#define again_fixed_trail_if_zero(_cs, trail_len, ifzero) \
	trail = trail_len; \
	if(trail == 0) { goto ifzero; } \
	cs = _cs; \
	goto _fixed_trail_again

#define start_container(func, count_, ct_) \
	if(msgpack_unpack_callback(func)(user, count_, &stack[top].obj) < 0) { goto _failed; } \
	if((count_) == 0) { obj = stack[top].obj; goto _push; } \
	if(top >= MSGPACK_MAX_STACK_SIZE) { goto _failed; } \
	stack[top].ct = ct_; \
    stack[top].curr = 0; \
	stack[top].count = count_; \
	/*printf("container %d count %d stack %d\n",stack[top].obj,count_,top);*/ \
	/*printf("stack push %d\n", top);*/ \
	++top; \
	goto _header_again

#define NEXT_CS(p) \
	((unsigned int)*p & 0x1f)

#define PTR_CAST_8(ptr)   (*(uint8_t*)ptr)
#define PTR_CAST_16(ptr)  _msgpack_be16(*(uint16_t*)ptr)
#define PTR_CAST_32(ptr)  _msgpack_be32(*(uint32_t*)ptr)
#define PTR_CAST_64(ptr)  _msgpack_be64(*(uint64_t*)ptr)

#ifdef USE_CASE_RANGE
#define SWITCH_RANGE_BEGIN     switch(*p) {
#define SWITCH_RANGE(FROM, TO) case FROM ... TO:
#define SWITCH_RANGE_DEFAULT   default:
#define SWITCH_RANGE_END       }
#else
#define SWITCH_RANGE_BEGIN     { if(0) {
#define SWITCH_RANGE(FROM, TO) } else if(FROM curr == c->count) {
			msgpack_unpack_callback(_array_end)(user, &c->obj);
			obj = c->obj;
			--top;
			/*printf("stack pop %d\n", top);*/
			goto _push;
		}
		goto _header_again;
	case CT_MAP_KEY:
		c->map_key = obj;
		c->ct = CT_MAP_VALUE;
		goto _header_again;
	case CT_MAP_VALUE:
		if(msgpack_unpack_callback(_map_item)(user, &c->obj, c->map_key, obj) < 0) { goto _failed; }
		if(--c->count == 0) {
			msgpack_unpack_callback(_map_end)(user, &c->obj);
			obj = c->obj;
			--top;
			/*printf("stack pop %d\n", top);*/
			goto _push;
		}
		c->ct = CT_MAP_KEY;
		goto _header_again;

	default:
		goto _failed;
	}

_header_again:
		cs = CS_HEADER;
		++p;
	} while(p != pe);
	goto _out;


_finish:
	stack[0].obj = obj;
	++p;
	ret = 1;
	/*printf("-- finish --\n"); */
	goto _end;

_failed:
	/*printf("** FAILED **\n"); */
	ret = -1;
	goto _end;

_out:
	ret = 0;
	goto _end;

_end:
	ctx->cs = cs;
	ctx->trail = trail;
	ctx->top = top;
	*off = p - (const unsigned char*)data;

	return ret;
}


#undef msgpack_unpack_func
#undef msgpack_unpack_callback
#undef msgpack_unpack_struct
#undef msgpack_unpack_object
#undef msgpack_unpack_user

#undef push_simple_value
#undef push_fixed_value
#undef push_variable_value
#undef again_fixed_trail
#undef again_fixed_trail_if_zero
#undef start_container

#undef NEXT_CS
#undef PTR_CAST_8
#undef PTR_CAST_16
#undef PTR_CAST_32
#undef PTR_CAST_64


Web Proxy Viewer  |  New URL  |  Original Page