Blame src/asn1c/BIT_STRING.c

Packit 728676
/*-
Packit 728676
 * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
Packit 728676
 * Redistribution and modifications are permitted subject to BSD license.
Packit 728676
 */
Packit 728676
#include <asn_internal.h>
Packit 728676
#include <BIT_STRING.h>
Packit 728676
#include <asn_internal.h>
Packit 728676
Packit 728676
/*
Packit 728676
 * BIT STRING basic type description.
Packit 728676
 */
Packit 728676
static ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
Packit 728676
	(ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
Packit 728676
};
Packit 728676
static asn_OCTET_STRING_specifics_t asn_DEF_BIT_STRING_specs = {
Packit 728676
	sizeof(BIT_STRING_t),
Packit 728676
	offsetof(BIT_STRING_t, _asn_ctx),
Packit 728676
	ASN_OSUBV_BIT
Packit 728676
};
Packit 728676
asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
Packit 728676
	"BIT STRING",
Packit 728676
	"BIT_STRING",
Packit 728676
	OCTET_STRING_free,         /* Implemented in terms of OCTET STRING */
Packit 728676
	BIT_STRING_print,
Packit 728676
	BIT_STRING_constraint,
Packit 728676
	OCTET_STRING_decode_ber,   /* Implemented in terms of OCTET STRING */
Packit 728676
	OCTET_STRING_encode_der,   /* Implemented in terms of OCTET STRING */
Packit 728676
	OCTET_STRING_decode_xer_binary,
Packit 728676
	BIT_STRING_encode_xer,
Packit 728676
	OCTET_STRING_decode_uper,	/* Unaligned PER decoder */
Packit 728676
	OCTET_STRING_encode_uper,	/* Unaligned PER encoder */
Packit 728676
	0, /* Use generic outmost tag fetcher */
Packit 728676
	asn_DEF_BIT_STRING_tags,
Packit 728676
	sizeof(asn_DEF_BIT_STRING_tags)
Packit 728676
	  / sizeof(asn_DEF_BIT_STRING_tags[0]),
Packit 728676
	asn_DEF_BIT_STRING_tags,	/* Same as above */
Packit 728676
	sizeof(asn_DEF_BIT_STRING_tags)
Packit 728676
	  / sizeof(asn_DEF_BIT_STRING_tags[0]),
Packit 728676
	0,	/* No PER visible constraints */
Packit 728676
	0, 0,	/* No members */
Packit 728676
	&asn_DEF_BIT_STRING_specs
Packit 728676
};
Packit 728676
Packit 728676
/*
Packit 728676
 * BIT STRING generic constraint.
Packit 728676
 */
Packit 728676
int
Packit 728676
BIT_STRING_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
Packit 728676
		asn_app_constraint_failed_f *ctfailcb, void *app_key) {
Packit 728676
	const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
Packit 728676
Packit 728676
	if(st && st->buf) {
Packit 728676
		if((st->size == 0 && st->bits_unused)
Packit 728676
		|| st->bits_unused < 0 || st->bits_unused > 7) {
Packit 728676
			_ASN_CTFAIL(app_key, td, sptr,
Packit 728676
				"%s: invalid padding byte (%s:%d)",
Packit 728676
				td->name, __FILE__, __LINE__);
Packit 728676
			return -1;
Packit 728676
		}
Packit 728676
	} else {
Packit 728676
		_ASN_CTFAIL(app_key, td, sptr,
Packit 728676
			"%s: value not given (%s:%d)",
Packit 728676
			td->name, __FILE__, __LINE__);
Packit 728676
		return -1;
Packit 728676
	}
Packit 728676
Packit 728676
	return 0;
Packit 728676
}
Packit 728676
Packit 728676
static char *_bit_pattern[16] = {
Packit 728676
	"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
Packit 728676
	"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
Packit 728676
};
Packit 728676
Packit 728676
asn_enc_rval_t
Packit 728676
BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
Packit 728676
	int ilevel, enum xer_encoder_flags_e flags,
Packit 728676
		asn_app_consume_bytes_f *cb, void *app_key) {
Packit 728676
	asn_enc_rval_t er;
Packit 728676
	char scratch[128];
Packit 728676
	char *p = scratch;
Packit 728676
	char *scend = scratch + (sizeof(scratch) - 10);
Packit 728676
	const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
Packit 728676
	int xcan = (flags & XER_F_CANONICAL);
Packit 728676
	uint8_t *buf;
Packit 728676
	uint8_t *end;
Packit 728676
Packit 728676
	if(!st || !st->buf)
Packit 728676
		_ASN_ENCODE_FAILED;
Packit 728676
Packit 728676
	er.encoded = 0;
Packit 728676
Packit 728676
	buf = st->buf;
Packit 728676
	end = buf + st->size - 1;	/* Last byte is special */
Packit 728676
Packit 728676
	/*
Packit 728676
	 * Binary dump
Packit 728676
	 */
Packit 728676
	for(; buf < end; buf++) {
Packit 728676
		int v = *buf;
Packit 728676
		int nline = xcan?0:(((buf - st->buf) % 8) == 0);
Packit 728676
		if(p >= scend || nline) {
Packit 728676
			er.encoded += p - scratch;
Packit 728676
			_ASN_CALLBACK(scratch, p - scratch);
Packit 728676
			p = scratch;
Packit 728676
			if(nline) _i_ASN_TEXT_INDENT(1, ilevel);
Packit 728676
		}
Packit 728676
		memcpy(p + 0, _bit_pattern[v >> 4], 4);
Packit 728676
		memcpy(p + 4, _bit_pattern[v & 0x0f], 4);
Packit 728676
		p += 8;
Packit 728676
	}
Packit 728676
Packit 728676
	if(!xcan && ((buf - st->buf) % 8) == 0)
Packit 728676
		_i_ASN_TEXT_INDENT(1, ilevel);
Packit 728676
	er.encoded += p - scratch;
Packit 728676
	_ASN_CALLBACK(scratch, p - scratch);
Packit 728676
	p = scratch;
Packit 728676
Packit 728676
	if(buf == end) {
Packit 728676
		int v = *buf;
Packit 728676
		int ubits = st->bits_unused;
Packit 728676
		int i;
Packit 728676
		for(i = 7; i >= ubits; i--)
Packit 728676
			*p++ = (v & (1 << i)) ? 0x31 : 0x30;
Packit 728676
		er.encoded += p - scratch;
Packit 728676
		_ASN_CALLBACK(scratch, p - scratch);
Packit 728676
	}
Packit 728676
Packit 728676
	if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
Packit 728676
Packit 728676
	_ASN_ENCODED_OK(er);
Packit 728676
cb_failed:
Packit 728676
	_ASN_ENCODE_FAILED;
Packit 728676
}
Packit 728676
Packit 728676
Packit 728676
/*
Packit 728676
 * BIT STRING specific contents printer.
Packit 728676
 */
Packit 728676
int
Packit 728676
BIT_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
Packit 728676
		asn_app_consume_bytes_f *cb, void *app_key) {
Packit 728676
	static const char *h2c = "0123456789ABCDEF";
Packit 728676
	char scratch[64];
Packit 728676
	const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
Packit 728676
	uint8_t *buf;
Packit 728676
	uint8_t *end;
Packit 728676
	char *p = scratch;
Packit 728676
Packit 728676
	(void)td;	/* Unused argument */
Packit 728676
Packit 728676
	if(!st || !st->buf)
Packit 728676
		return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
Packit 728676
Packit 728676
	ilevel++;
Packit 728676
	buf = st->buf;
Packit 728676
	end = buf + st->size;
Packit 728676
Packit 728676
	/*
Packit 728676
	 * Hexadecimal dump.
Packit 728676
	 */
Packit 728676
	for(; buf < end; buf++) {
Packit 728676
		if((buf - st->buf) % 16 == 0 && (st->size > 16)
Packit 728676
				&& buf != st->buf) {
Packit 728676
			_i_INDENT(1);
Packit 728676
			/* Dump the string */
Packit 728676
			if(cb(scratch, p - scratch, app_key) < 0) return -1;
Packit 728676
			p = scratch;
Packit 728676
		}
Packit 728676
		*p++ = h2c[*buf >> 4];
Packit 728676
		*p++ = h2c[*buf & 0x0F];
Packit 728676
		*p++ = 0x20;
Packit 728676
	}
Packit 728676
Packit 728676
	if(p > scratch) {
Packit 728676
		p--;	/* Eat the tailing space */
Packit 728676
Packit 728676
		if((st->size > 16)) {
Packit 728676
			_i_INDENT(1);
Packit 728676
		}
Packit 728676
Packit 728676
		/* Dump the incomplete 16-bytes row */
Packit 728676
		if(cb(scratch, p - scratch, app_key) < 0)
Packit 728676
			return -1;
Packit 728676
	}
Packit 728676
Packit 728676
	return 0;
Packit 728676
}
Packit 728676