Example #1
0
/**
 * Write NUL-terminated string.
 *
 * If (size_t) -1 is given as length, then it is computed via strlen(), in
 * which case the string buffer must be NUL-terminated.  Otherwise, the value
 * is taken to be the pre-computed string length.
 *
 * The string is written as: <ule64(length)><bytes>, no trailing NUL.
 */
void
pmsg_write_string(pmsg_t *mb, const char *str, size_t length)
{
	size_t len;

	g_assert(pmsg_is_writable(mb));	/* Not shared, or would corrupt data */

	len = (size_t) -1 == length ? strlen(str) : length;

	g_assert(UNSIGNED(pmsg_available(mb)) >= len + 10);	/* Need ule64 length */

	pmsg_write_ule64(mb, (uint64) len);
	if (len != 0) {
		pmsg_write(mb, str, len);
	}
}
Example #2
0
/**
 * Write NUL-terminated string, up to `n' characters or the first seen NUL
 * in the buffer, whichever comes first.
 *
 * The string is written as: <ule64(length)><bytes>, no trailing NUL.
 */
void
pmsg_write_fixed_string(pmsg_t *mb, const char *str, size_t n)
{
	size_t len;

	g_assert(pmsg_is_writable(mb));	/* Not shared, or would corrupt data */
	g_assert(UNSIGNED(pmsg_available(mb)) >= n + 10);	/* Need ule64 length */

	len = strlen(str);
	len = MIN(n, len);
	pmsg_write_ule64(mb, (uint64) len);

	if (len != 0) {
		pmsg_write(mb, str, len);
	}
}
Example #3
0
/**
 * Write an unsigned 64-bit quantity using variable length encoding (little
 * endian). Each serialized byte contains 7 bits, the highest bit is set when
 * this is the last byte of the encoded value.
 */
void
pmsg_write_ule64(pmsg_t *mb, uint64 v)
{
	uint64 value = v;

	g_assert(pmsg_is_writable(mb));	/* Not shared, or would corrupt data */
	g_assert(pmsg_available(mb) >= 10);	/* Will need 10 bytes at most */

	do {
		uint8 byt = (uint8) (value & 0x7f);		/* Lowest 7 bits */
		value >>= 7;
		if (0 == value) {
			byt |= 0x80;						/* Last byte emitted */
		}
		pmsg_write_u8(mb, byt);
	} while (value != 0);
}
Example #4
0
/**
 * Write NUL-terminated string, up to `n' characters or the first seen NUL
 * in the buffer, whichever comes first.
 *
 * The string is written as: <ule64(length)><bytes>, no trailing NUL.
 */
void
pmsg_write_fixed_string(pmsg_t *mb, const char *str, size_t n)
{
	size_t len;

	g_assert(pmsg_is_writable(mb));	/* Not shared, or would corrupt data */
	g_assert(UNSIGNED(pmsg_available(mb)) >= n + 10);	/* Need ule64 length */
	g_assert_log(size_is_non_negative(n), "%s(): n=%zd", G_STRFUNC, n);

	len = vstrlen(str);
	len = MIN(n, len);
	pmsg_write_ule64(mb, (uint64) len);

	if (len != 0) {
		pmsg_write(mb, str, len);
	}
}
Example #5
0
/**
 * Write NUL-terminated string.
 *
 * If (size_t) -1 is given as length, then it is computed via strlen(), in
 * which case the string buffer must be NUL-terminated.  Otherwise, the value
 * is taken to be the pre-computed string length.
 *
 * The string is written as: <ule64(length)><bytes>, no trailing NUL.
 */
void
pmsg_write_string(pmsg_t *mb, const char *str, size_t length)
{
	size_t len;

	g_assert(pmsg_is_writable(mb));	/* Not shared, or would corrupt data */
	g_assert_log(size_is_non_negative(length) || (size_t) -1 == length,
		"%s(): length=%zd", G_STRFUNC, length);

	len = (size_t) -1 == length ? strlen(str) : length;

	g_assert(UNSIGNED(pmsg_available(mb)) >= len + 10);	/* Need ule64 length */

	pmsg_write_ule64(mb, (uint64) len);
	if (len != 0) {
		pmsg_write(mb, str, len);
	}
}
Example #6
0
/**
 * Copy ``len'' bytes from the source message block to the destination by
 * reading the source bytes and writing them to the recipient.
 *
 * @returns amount of bytes written, which may be lower than the requested
 * amount if the source buffer was shorter or there is not enough room in
 * the destination.
 */
int
pmsg_copy(pmsg_t *dest, pmsg_t *src, int len)
{
	int copied, available;

	pmsg_check_consistency(dest);
	pmsg_check_consistency(src);
	g_assert(pmsg_is_writable(dest));	/* Not shared, or would corrupt data */

	copied = src->m_wptr - src->m_rptr;	/* Available data in source */
	copied = MIN(copied, len);
	available = pmsg_available(dest);	/* Room in destination buffer */
	copied = MIN(copied, available);

	if (copied > 0) {
		dest->m_wptr = mempcpy(dest->m_wptr, src->m_rptr, copied);
		src->m_rptr += copied;
	}

	return copied;
}
Example #7
0
/**
 * Write an IPv4 or IPv6 address.
 */
void
pmsg_write_ipv4_or_ipv6_addr(pmsg_t *mb, host_addr_t addr)
{
	g_assert(pmsg_is_writable(mb));	/* Not shared, or would corrupt data */
	g_assert(pmsg_available(mb) >= 17);

	switch (host_addr_net(addr)) {
	case NET_TYPE_IPV4:
		pmsg_write_u8(mb, 4);
		pmsg_write_be32(mb, host_addr_ipv4(addr));
		break;
	case NET_TYPE_IPV6:
		pmsg_write_u8(mb, 16);
		pmsg_write(mb, host_addr_ipv6(&addr), 16);
		break;
	case NET_TYPE_LOCAL:
	case NET_TYPE_NONE:
		g_error("unexpected address in pmsg_write_ipv4_or_ipv6_addr(): %s",
			host_addr_to_string(addr));
	}
}
Example #8
0
/**
 * Shift back unread data to the beginning of the buffer if that can make
 * at least 1/nth of the total arena size available for writing.
 */
void
pmsg_fractional_compact(pmsg_t *mb, int n)
{
	int shifting;

	g_assert(n > 0);
	pmsg_check_consistency(mb);
	g_assert(pmsg_is_writable(mb));		/* Not shared, or would corrupt data */
	g_assert(mb->m_rptr <= mb->m_wptr);

	shifting = mb->m_rptr - mb->m_data->d_arena;
	g_assert(shifting >= 0);

	if (shifting != 0) {
		unsigned available = pmsg_available(mb) + shifting;
		if (available >= pmsg_phys_len(mb) / n) {
			memmove(mb->m_data->d_arena, mb->m_rptr, pmsg_size(mb));
			mb->m_rptr -= shifting;
			mb->m_wptr -= shifting;
		}
	}
}