Commit 8253b9dd authored by Rusty Russell's avatar Rusty Russell

bytestring: new module.

parent 0a8d854a
../../licenses/LGPL-2.1
\ No newline at end of file
#include <string.h>
#include "config.h"
/**
* bytestring - simple bytestring handling
*
* This code handles manipulation of "bytestrings" represented as a
* structure containing a pointer and length. Bytestrings are not
* NUL-terminated, and may include internal \0 characters. The main
* use case is for referencing sub-sections of a large data buffer
* without the inconvenience of manually passing (and returning) both
* pointer and length all the time.
*
* Because of this use case, the bytestrings are treated as having
* immutable contents (we use a const char pointer). The caller code
* is responsible for ensuring that the lifetime of the data
* referenced by the bytestrings is long enough not to leave
* bytestring structures with a dangling pointer.
*
* Example:
* const char buf[] = "ABCDEFGH";
* struct bytestring abcd = BYTESTRING("ABCD");
*
* assert(bytestring_eq(bytestring(buf, 4), abcd));
*
* License: LGPL (v2.1 or any later version)
* Author: David Gibson <david@gibson.dropbear.id.au>
*/
int main(int argc, char *argv[])
{
/* Expect exactly one argument */
if (argc != 2)
return 1;
if (strcmp(argv[1], "depends") == 0) {
printf("ccan/array_size\n");
return 0;
}
return 1;
}
/* Licensed under LGPLv2+ - see LICENSE file for details */
#ifndef CCAN_BYTESTRING_H_
#define CCAN_BYTESTRING_H_
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <ccan/array_size/array_size.h>
struct bytestring {
const char *ptr;
size_t len;
};
/**
* bytestring - construct a new bytestring
* @p: pointer to the content of the bytestring
* @l: length of the bytestring
*
* Builds a new bytestring starting at p, of length l.
*
* Example:
* char x[5] = "abcde";
* struct bytestring bs = bytestring(x, 5);
* assert(bs.len == 5);
*/
static inline struct bytestring bytestring(const char *p, size_t l)
{
struct bytestring bs = {
.ptr = p,
.len = l,
};
return bs;
}
#define bytestring_NULL bytestring(NULL, 0)
/**
* BYTESTRING - construct a bytestring from a string literal
* @s: string literal
*
* Builds a new bytestring containing the given literal string, not
* including the terminating \0 (but including any internal \0s).
*
* Example:
* assert(BYTESTRING("abc\0def").len == 7);
*/
#define BYTESTRING(s) (bytestring((s), ARRAY_SIZE(s) - 1))
/**
* bytestring_from_string - construct a bytestring from a NUL terminated string
* @s: NUL-terminated string pointer
*
* Builds a new bytestring containing the given NUL-terminated string,
* up to, but not including, the terminating \0.
*
* Example:
* assert(bytestring_from_string("abc\0def").len == 3);
*/
static inline struct bytestring bytestring_from_string(const char *s)
{
return bytestring(s, strlen(s));
}
/**
* bytestring_eq - test if bytestrings have identical content
* @a, @b: bytestrings
*
* Returns 1 if the given bytestrings have identical length and
* content, 0 otherwise.
*/
static inline bool bytestring_eq(struct bytestring a, struct bytestring b)
{
return (a.len == b.len)
&& (memcmp(a.ptr, b.ptr, a.len) == 0);
}
#endif /* CCAN_BYTESTRING_H_ */
#include <stdio.h>
#include <ccan/bytestring/bytestring.h>
int main(int argc, char *argv[])
{
struct bytestring bs;
const char *x = "abcde";
#ifdef FAIL
bs = BYTESTRING(x);
#endif
printf("%zd %s\n", bs.len, x);
return 0;
}
#include <stdio.h>
#include <ccan/bytestring/bytestring.h>
int main(int argc, char *argv[])
{
struct bytestring bs;
bs = BYTESTRING(
#ifdef FAIL
argv[0]
#else
"literal"
#endif
);
printf("%zd\n", bs.len);
return 0;
}
#include <ccan/bytestring/bytestring.h>
#include <ccan/tap/tap.h>
#define TEST_STRING "test string"
#define TEST_STRING_2 "abc\0def"
const char str1[] = TEST_STRING;
const char *str2 = TEST_STRING;
int main(void)
{
struct bytestring bs, bs1, bs2, bs3, bs4;
/* This is how many tests you plan to run */
plan_tests(6);
bs = bytestring(str1, sizeof(str1) - 1);
ok1(bs.ptr == str1);
ok1(bs.len == (sizeof(str1) - 1));
bs1 = BYTESTRING(TEST_STRING);
ok1(bytestring_eq(bs, bs1));
bs2 = BYTESTRING(TEST_STRING_2);
ok1(bs2.len == 7);
bs3 = bytestring_from_string(str2);
ok1(bytestring_eq(bs3, bs));
bs4 = bytestring_from_string(TEST_STRING_2);
ok1(bs4.len == 3);
/* This exits depending on whether all tests passed */
return exit_status();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment