1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
/*
* Copyright (C) 2008-2009 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup chunk chunk
* @{ @ingroup libstrongswan
*/
#ifndef CHUNK_H_
#define CHUNK_H_
typedef struct chunk_t chunk_t;
/**
* General purpose pointer/length abstraction.
*/
struct chunk_t {
/** Pointer to start of data */
u_char *ptr;
/** Length of data in bytes */
size_t len;
};
/**
* A { NULL, 0 }-chunk handy for initialization.
*/
extern chunk_t chunk_empty;
/**
* Create a new chunk pointing to "ptr" with length "len"
*/
static inline chunk_t chunk_create(u_char *ptr, size_t len)
{
chunk_t chunk = {ptr, len};
return chunk;
}
/**
* Free contents of a chunk
*/
static inline void chunk_free(chunk_t *chunk)
{
free(chunk->ptr);
*chunk = chunk_empty;
}
/**
* Overwrite the contents of a chunk and free it
*/
static inline void chunk_clear(chunk_t *chunk)
{
if (chunk->ptr)
{
memset(chunk->ptr, 0, chunk->len);
chunk_free(chunk);
}
}
/**
* Initialize a chunk using a char array
*/
#define chunk_from_chars(...) ((chunk_t){(char[]){__VA_ARGS__}, sizeof((char[]){__VA_ARGS__})})
/**
* Initialize a chunk to point to a thing
*/
#define chunk_from_thing(thing) chunk_create((char*)&(thing), sizeof(thing))
/**
* Allocate a chunk on the heap
*/
#define chunk_alloc(bytes) ({size_t x = (bytes); chunk_create(x ? malloc(x) : NULL, x);})
/**
* Allocate a chunk on the stack
*/
#define chunk_alloca(bytes) ({size_t x = (bytes); chunk_create(x ? alloca(x) : NULL, x);})
/**
* Clone a chunk on heap
*/
#define chunk_clone(chunk) ({chunk_t x = (chunk); chunk_create_clone(x.len ? malloc(x.len) : NULL, x);})
/**
* Skip n bytes in chunk (forward pointer, shorten length)
*/
static inline chunk_t chunk_skip(chunk_t chunk, size_t bytes)
{
if (chunk.len > bytes)
{
chunk.ptr += bytes;
chunk.len -= bytes;
return chunk;
}
return chunk_empty;
}
/**
* Skip a leading zero-valued byte
*/
static inline chunk_t chunk_skip_zero(chunk_t chunk)
{
if (chunk.len > 1 && *chunk.ptr == 0x00)
{
chunk.ptr++;
chunk.len--;
}
return chunk;
}
/**
* Compare two chunks, returns zero if a equals b
* or negative/positive if a is small/greater than b
*/
int chunk_compare(chunk_t a, chunk_t b);
/**
* Compare two chunks for equality,
* NULL chunks are never equal.
*/
static inline bool chunk_equals(chunk_t a, chunk_t b)
{
return a.ptr != NULL && b.ptr != NULL &&
a.len == b.len && memeq(a.ptr, b.ptr, a.len);
}
/**
* Compare two chunks (given as pointers) for equality (useful as callback),
* NULL chunks are never equal.
*/
static inline bool chunk_equals_ptr(chunk_t *a, chunk_t *b)
{
return a != NULL && b != NULL && chunk_equals(*a, *b);
}
/**
* Check if a chunk has printable characters only.
*
* If sane is given, chunk is cloned into sane and all non printable characters
* get replaced by "replace".
*
* @param chunk chunk to check for printability
* @param sane pointer where sane version is allocated, or NULL
* @param replace character to use for replaceing unprintable characters
* @return TRUE if all characters in chunk are printable
*/
bool chunk_printable(chunk_t chunk, chunk_t *sane, char replace);
#endif
|