Net-Radio-Location-SUPL-Test

 view release on metacpan or  search on metacpan

asn1/xer_decoder.c  view on Meta::CPAN

			&& size == (size_t)chunk_size)		\
			RETURN(RC_WMORE);			\
		chunk_size = converted_size;			\
	} while(0)
#define	XER_GOT_EMPTY()	do {					\
	if(body_receiver(struct_key, 0, 0, size > 0) == -1)	\
			RETURN(RC_FAIL);			\
	} while(0)

/*
 * Generalized function for decoding the primitive values.
 */
asn_dec_rval_t
xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
	asn_struct_ctx_t *ctx,	/* Type decoder context */
	void *struct_key,
	const char *xml_tag,	/* Expected XML tag */
	const void *buf_ptr, size_t size,
	int (*opt_unexpected_tag_decoder)
		(void *struct_key, const void *chunk_buf, size_t chunk_size),
	ssize_t (*body_receiver)
		(void *struct_key, const void *chunk_buf, size_t chunk_size,
			int have_more)
	) {

	asn_dec_rval_t rval;
	ssize_t consumed_myself = 0;

	(void)opt_codec_ctx;

	/*
	 * Phases of XER/XML processing:
	 * Phase 0: Check that the opening tag matches our expectations.
	 * Phase 1: Processing body and reacting on closing tag.
	 */
	if(ctx->phase > 1) RETURN(RC_FAIL);
	for(;;) {
		pxer_chunk_type_e ch_type;	/* XER chunk type */
		ssize_t ch_size;		/* Chunk size */
		xer_check_tag_e tcv;		/* Tag check value */

		/*
		 * Get the next part of the XML stream.
		 */
		ch_size = xer_next_token(&ctx->context, buf_ptr, size,
			&ch_type);
		switch(ch_size) {
		case -1: RETURN(RC_FAIL);
		case 0:
			RETURN(RC_WMORE);
		default:
			switch(ch_type) {
			case PXER_COMMENT:		/* Got XML comment */
				ADVANCE(ch_size);	/* Skip silently */
				continue;
			case PXER_TEXT:
				if(ctx->phase == 0) {
					/*
					 * We have to ignore whitespace here,
					 * but in order to be forward compatible
					 * with EXTENDED-XER (EMBED-VALUES, #25)
					 * any text is just ignored here.
					 */
				} else {
					XER_GOT_BODY(buf_ptr, ch_size, size);
				}
				ADVANCE(ch_size);
				continue;
			case PXER_TAG:
				break;	/* Check the rest down there */
			}
		}

		assert(ch_type == PXER_TAG && size);

		tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
		/*
		 * Phase 0:
		 * 	Expecting the opening tag
		 * 	for the type being processed.
		 * Phase 1:
		 * 	Waiting for the closing XML tag.
		 */
		switch(tcv) {
		case XCT_BOTH:
			if(ctx->phase) break;
			/* Finished decoding of an empty element */
			XER_GOT_EMPTY();
			ADVANCE(ch_size);
			ctx->phase = 2;	/* Phase out */
			RETURN(RC_OK);
		case XCT_OPENING:
			if(ctx->phase) break;
			ADVANCE(ch_size);
			ctx->phase = 1;	/* Processing body phase */
			continue;
		case XCT_CLOSING:
			if(!ctx->phase) break;
			ADVANCE(ch_size);
			ctx->phase = 2;	/* Phase out */
			RETURN(RC_OK);
		case XCT_UNKNOWN_BO:
			/*
			 * Certain tags in the body may be expected.
			 */
			if(opt_unexpected_tag_decoder
			&& opt_unexpected_tag_decoder(struct_key,
					buf_ptr, ch_size) >= 0) {
				/* Tag's processed fine */
				ADVANCE(ch_size);
				if(!ctx->phase) {
					/* We are not expecting
					 * the closing tag anymore. */
					ctx->phase = 2;	/* Phase out */
					RETURN(RC_OK);
				}
				continue;
			}
			/* Fall through */
		default:
			break;		/* Unexpected tag */



( run in 1.819 second using v1.01-cache-2.11-cpan-71847e10f99 )