Ejemplo n.º 1
0
/**
 * Convert string into a bitset. Inverse of bitset_to_str().
 *
 */
bitset *str_to_bitset(char *str, char **end)
{
	int			nbits = 0;
	int			bytes;
	int			n;
	int			pos;
	int			b;
        int                     len;
	bitset                  *bp;
        char                    dst[1024];

        if (!str)
                return NULL;

        /* hex string has 0x prefix */
        if (str[0] == '0' && str[1] == 'x')
                str = str + 2;

        len = strlen(str);
        if (len % 2) {
                nbits = (len + 1) << 2;
                bytes = NUM_BYTES(nbits);
                pos = (bytes << 3) - 5;
        } else {
                nbits = len << 2;
                bytes = NUM_BYTES(nbits);
                pos = (bytes << 3) - 1;
        }

        if (0)
                hex2binary(str, dst);

	bp = bitset_new(nbits);

	for (; *str != '\0' && isxdigit(*str) && pos >= 0; str++) {
		b = digittoint(*str);
		for (n = 3; n >= 0; n--, pos--) {
			if (b & (1 << n)) {
				bitset_set(bp, pos);
			}
		}
	}

	if (end != NULL)
                *end = str - 1;

	return bp;
}
Ejemplo n.º 2
0
/**
 * Return a string representation of a bitset. We use hex to compress
 * the string somewhat and drop leading zeros.
 *
 * Format is "NN:HHHHHH..." where "NN" is the actual number of bits in hex,
 * and "HHHHH...." is a hex representation of the bits in the set. The number
 * of characters in the bit string is always rounded to the nearest byte.
 *
 * e.g. "111" -> "3:07"
 * 		"11011010101011101" -> "11:01b55d"
 */
char *bitset_to_str(bitset *b)
{
	int			bytes;
	int		        pbit;
	int                     bit;
	char                    *str;
	char                    *s;
	unsigned char           val;
	int                     found = 0;

	if (!b)
		return strdup("00");

	/*
	 * Find out how many bytes needed (rounded up)
	 */
	bytes = NUM_BYTES(b->bs_nbits);

	str = (char *)calloc(bytes * 2 + 1, 1);
	s = str;

	for (pbit = (bytes << 3) - 1; pbit > 0; ) {
		for (val = 0, bit = 3; bit >= 0; bit--, pbit--) {
			if (pbit < (int)b->bs_nbits && bitset_test(b, pbit)) {
				val |= (1 << bit);
                                found = 1;
			}
		}
		if (found)
			*s++ = tohex[val & 0x0f];
	}

	if (b->bs_nbits == 0) {
		*s++ = '0';
	}

	*s = '\0';

	return str;
}
Ejemplo n.º 3
0
int
structs_fixedarray_decode(const struct structs_type *type, const u_char *code,
	size_t cmax, void *data, char *ebuf, size_t emax)
{
	const struct structs_type *const etype = type->args[0].v;
	const u_int length = type->args[2].i;
	const u_int bitslen = NUM_BYTES(length);
	const u_char *bits;
	int clen = 0;
	u_int i;

	/* Make sure it's really a fixedarray type */
	if (type->tclass != STRUCTS_TYPE_FIXEDARRAY) {
		errno = EINVAL;
		return (-1);
	}

	/* Get bits array */
	if (cmax < bitslen) {
		strlcpy(ebuf, "encoded array is truncated", emax);
		errno = EINVAL;
		return (-1);
	}
	bits = code;
	code += bitslen;
	cmax -= bitslen;
	clen += bitslen;

	/* Decode elements */
	for (i = 0; i < length; i++) {
		void *const edata = (char *)data + (i * etype->size);
		int eclen;

		/* If element not present, assign it the default value */
		if ((bits[i / 8] & (1 << (i % 8))) == 0) {
			if (structs_init(etype, NULL, edata) == -1)
				goto fail;
			continue;
		}

		/* Decode element */
		if ((eclen = (*etype->decode)(etype,
		    code, cmax, edata, ebuf, emax)) == -1)
			goto fail;

		/* Go to next encoded element */
		code += eclen;
		cmax -= eclen;
		clen += eclen;
		continue;

		/* Un-do work done so far */
fail:		while (i-- > 0) {
			structs_free(etype, NULL,
			    (char *)data + (i * etype->size));
		}
		return (-1);
	}

	/* Done */
	return (clen);
}
Ejemplo n.º 4
0
int
structs_fixedarray_encode(const struct structs_type *type, const char *mtype,
	struct structs_data *code, const void *data)
{
	const struct structs_type *const etype = type->args[0].v;
	const u_int length = type->args[2].i;
	const u_int bitslen = NUM_BYTES(length);
	struct structs_data *ecodes;
	u_char *bits;
	void *delem;
	u_int tlen;
	int r = -1;
	u_int i;

	/* Make sure it's really a fixedarray type */
	if (type->tclass != STRUCTS_TYPE_FIXEDARRAY) {
		errno = EINVAL;
		return (-1);
	}

	/* Get the default value for an element */
	if ((delem = MALLOC(TYPED_MEM_TEMP, etype->size)) == NULL)
		return (-1);
	if (structs_init(etype, NULL, delem) == -1)
		goto fail1;

	/* Create bit array. Each bit indicates an element that is present. */
	if ((bits = MALLOC(TYPED_MEM_TEMP, bitslen)) == NULL)
		goto fail2;
	memset(bits, 0, bitslen);
	tlen = bitslen;

	/* Create array of individual encodings, one per element */
	if ((ecodes = MALLOC(TYPED_MEM_TEMP, length * sizeof(*ecodes))) == NULL)
		goto fail3;
	for (i = 0; i < length; i++) {
		const void *const elem = (char *)data + (i * etype->size);
		struct structs_data *const ecode = &ecodes[i];

		/* Check for default value, leave out if same as */
		if ((*etype->equal)(etype, elem, delem) == 1) {
			memset(ecode, 0, sizeof(*ecode));
			continue;
		}
		bits[i / 8] |= (1 << (i % 8));

		/* Encode element */
		if ((*etype->encode)(etype, TYPED_MEM_TEMP, ecode, elem) == -1)
			goto fail4;
		tlen += ecode->length;
	}

	/* Allocate final encoded region */
	if ((code->data = MALLOC(mtype, tlen)) == NULL)
		goto fail4;

	/* Copy bits array */
	memcpy(code->data, bits, bitslen);
	code->length = bitslen;

	/* Copy encoded elements */
	for (i = 0; i < length; i++) {
		struct structs_data *const ecode = &ecodes[i];

		memcpy(code->data + code->length, ecode->data, ecode->length);
		code->length += ecode->length;
	}

	/* OK */
	r = 0;

	/* Clean up and exit */
fail4:	while (i-- > 0)
		FREE(TYPED_MEM_TEMP, ecodes[i].data);
	FREE(TYPED_MEM_TEMP, ecodes);
fail3:	FREE(TYPED_MEM_TEMP, bits);
fail2:	structs_free(etype, NULL, delem);
fail1:	FREE(TYPED_MEM_TEMP, delem);
	return (r);
}
Ejemplo n.º 5
0
int
structs_array_decode(const struct structs_type *type, const u_char *code,
	size_t cmax, void *data, char *ebuf, size_t emax)
{
	const struct structs_type *const etype = type->args[0].v;
	const char *const mtype = type->args[1].v;
	struct structs_array *const ary = data;
	const u_char *bits;
	u_int32_t elength;
	u_int bitslen;
	int clen;
	u_int i;

	/* Make sure it's really an array type */
	if (type->tclass != STRUCTS_TYPE_ARRAY) {
		errno = EINVAL;
		return (-1);
	}

	/* Get number of elements */
	if (cmax < 4)
		goto truncated;
	memcpy(&elength, code, 4);
	ary->length = ntohl(elength);
	code += 4;
	cmax -= 4;
	clen = 4;

	/* Get bits array */
	bitslen = NUM_BYTES(ary->length);
	if (cmax < bitslen) {
truncated:	strlcpy(ebuf, "encoded array is truncated", emax);
		errno = EINVAL;
		return (-1);
	}
	bits = code;
	code += bitslen;
	cmax -= bitslen;
	clen += bitslen;

	/* Allocate array elements */
	if ((ary->elems = MALLOC(mtype, ary->length * etype->size)) == NULL)
		return (-1);

	/* Decode elements */
	for (i = 0; i < ary->length; i++) {
		void *const edata = (char *)ary->elems + (i * etype->size);
		int eclen;

		/* If element not present, assign it the default value */
		if ((bits[i / 8] & (1 << (i % 8))) == 0) {
			if (structs_init(etype, NULL, edata) == -1)
				goto fail;
			continue;
		}

		/* Decode element */
		if ((eclen = (*etype->decode)(etype,
		    code, cmax, edata, ebuf, emax)) == -1)
			goto fail;

		/* Go to next encoded element */
		code += eclen;
		cmax -= eclen;
		clen += eclen;
		continue;

		/* Un-do work done so far */
fail:		while (i-- > 0) {
			structs_free(etype, NULL,
			    (char *)ary->elems + (i * etype->size));
		}
		FREE(mtype, ary->elems);
		return (-1);
	}

	/* Done */
	return (clen);
}