/*-
 * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
 * Redistribution and modifications are permitted subject to BSD license.
 */
#include <asn_internal.h>
#include <BIT_STRING.h>

/*
 * BIT STRING basic type description.
 */
static ber_tlv_tag_t asn1_DEF_BIT_STRING_tags[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
};
asn1_TYPE_descriptor_t asn1_DEF_BIT_STRING = {
	"BIT STRING",
	OCTET_STRING_free,         /* Implemented in terms of OCTET STRING */
	BIT_STRING_print,
	BIT_STRING_constraint,
	OCTET_STRING_decode_ber,   /* Implemented in terms of OCTET STRING */
	OCTET_STRING_encode_der,   /* Implemented in terms of OCTET STRING */
	0,				/* Not implemented yet */
	BIT_STRING_encode_xer,
	0, /* Use generic outmost tag fetcher */
	asn1_DEF_BIT_STRING_tags,
	sizeof(asn1_DEF_BIT_STRING_tags)
	  / sizeof(asn1_DEF_BIT_STRING_tags[0]),
	asn1_DEF_BIT_STRING_tags,	/* Same as above */
	sizeof(asn1_DEF_BIT_STRING_tags)
	  / sizeof(asn1_DEF_BIT_STRING_tags[0]),
	-1,	/* Both ways are fine */
	0, 0,	/* No members */
	(void *)-1	/* Special indicator that this is a BIT STRING */
};

/*
 * BIT STRING generic constraint.
 */
int
BIT_STRING_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
		asn_app_consume_bytes_f *app_errlog, void *app_key) {
	const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;

	if(st && st->buf) {
		if(st->size) {
			if(st->size == 1 && st->buf[0] != 0) {
				_ASN_ERRLOG(app_errlog, app_key,
					"%s: invalid padding byte (%s:%d)",
					td->name, __FILE__, __LINE__);
				return -1;
			}
		} else {
			_ASN_ERRLOG(app_errlog, app_key,
				"%s: no padding byte (%s:%d)",
				td->name, __FILE__, __LINE__);
			return -1;
		}
	} else {
		_ASN_ERRLOG(app_errlog, app_key,
			"%s: value not given (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}

	return 0;
}

static char *_bit_pattern[16] = {
	"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
	"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
};

asn_enc_rval_t
BIT_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
	int ilevel, enum xer_encoder_flags_e flags,
		asn_app_consume_bytes_f *cb, void *app_key) {
	asn_enc_rval_t er;
	char scratch[128];
	char *p = scratch;
	char *scend = scratch + (sizeof(scratch) - 10);
	const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
	uint8_t *buf;
	uint8_t *end;

	if(!st || !st->buf)
		_ASN_ENCODE_FAILED;

	er.encoded = 0;

	buf = st->buf;
	end = buf + st->size - 1;	/* Last byte is special */

	/*
	 * Binary dump
	 */
	for(buf++; buf < end; buf++) {
		int v = *buf;
		int nline = (flags & XER_F_CANONICAL)
			?0:((((buf - st->buf) - 1) % 16) == 0);
		if(p >= scend || nline) {
			er.encoded += p - scratch;
			_ASN_CALLBACK(scratch, p - scratch);
			p = scratch;
			if(nline) _i_ASN_TEXT_INDENT(1, ilevel);
		}
		memcpy(p + 0, _bit_pattern[v >> 4], 4);
		memcpy(p + 4, _bit_pattern[v & 0x0f], 4);
		p += 8;
	}

	er.encoded += p - scratch;
	_ASN_CALLBACK(scratch, p - scratch);

	if(buf < end + 1) {
		int v = *buf;
		int mbit = st->buf[0];	/* bits to skip from the right */
		int i;
		for(i = 7; i >= mbit; i--)
			*p++ = (v & (1 << i)) ? '1' : '0';
		er.encoded += p - scratch;
		_ASN_CALLBACK(scratch, p - scratch);
	}

	return er;
}


/*
 * BIT STRING specific contents printer.
 */
int
BIT_STRING_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
		asn_app_consume_bytes_f *cb, void *app_key) {
	static const char *h2c = "0123456789ABCDEF";
	char scratch[64];
	const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
	uint8_t *buf;
	uint8_t *end;
	char *p = scratch;

	(void)td;	/* Unused argument */

	if(!st || !st->buf) return cb("<absent>", 8, app_key);

	ilevel += 4;
	buf = st->buf;
	end = buf + st->size;

	/*
	 * Hexadecimal dump.
	 */
	for(buf++; buf < end; buf++) {
		if(((buf - st->buf) - 1) % 16 == 0 && (st->size > 16)) {
			int i;
			/* Indentation */
			if(cb("\n", 1, app_key)) return -1;
			for(i = 0; i < ilevel; i++) cb(" ", 1, app_key);
			/* Dump the string */
			if(cb(scratch, p - scratch, app_key)) return -1;
			p = scratch;
		}
		*p++ = h2c[*buf >> 4];
		*p++ = h2c[*buf & 0x0F];
		*p++ = 0x20;
	}
	if(p > scratch) p--;	/* Eat the tailing space */

	/* Dump the incomplete 16-bytes row */
	return cb(scratch, p - scratch, app_key);
}

