Crypt-SecretBuffer
view release on metacpan or search on metacpan
SecretBuffer.h view on Meta::CPAN
#ifndef CRYPT_SECRETBUFFER_H
/* 'data' is an array of bytes allocated to 'capacity'.
* 'len' is how much of the buffer is holding data. All bytes beyond are zeros
* 'stringify_sv' is initially NULL, but exists after the first stringify event
* 'wrapper' is the object to which this struct is attached (via Magic)
* and will normally be an HV, but could potentially be other things if
* 'secret_buffer_from_magic' was called on a non-HV ref with AUTOCREATE flag
*/
typedef struct {
char *data;
size_t len, capacity;
SV *stringify_sv;
SV *wrapper;
} secret_buffer;
struct secret_buffer_charset;
typedef struct secret_buffer_charset secret_buffer_charset;
/* Given a Regexp-ref either return a cached secret_buffer_charset from a
* previous call, or build a new one by
* analyzing the regexp, then cache it in MAGIC.
* The regexp must be a single character class specification and nothing else,
* but it may use the case-insensitive flag. If the pattern uses anything more
* than simple characters or ranges, the bitmap is determined by passing the
* range of characters 0..255 through `s/$patern//g` and building the bitmap
* from the result.
*/
extern secret_buffer_charset * secret_buffer_charset_from_regexpref(SV *ref);
/* Test whether the charset contains an 8-bit byte.
* This relies solely on the bitmap.
*/
extern bool secret_buffer_charset_test_byte(const secret_buffer_charset *cset, U8 b);
/* Test whether the charset contains a unicode character. This uses the perl regex
* engine if the codepoint is higher than 0x7F, to ensure correct matching.
*/
extern bool secret_buffer_charset_test_codepoint(const secret_buffer_charset *cset, U32 cp);
/* encoding flags can be combined with other flags */
#define SECRET_BUFFER_ENCODING_MASK 0xFF
#define SECRET_BUFFER_ENCODING_ISO8859_1 0
#define SECRET_BUFFER_ENCODING_ASCII 1
#define SECRET_BUFFER_ENCODING_UTF8 2
#define SECRET_BUFFER_ENCODING_UTF16LE 3
#define SECRET_BUFFER_ENCODING_UTF16BE 4
#define SECRET_BUFFER_ENCODING_HEX 5
#define SECRET_BUFFER_ENCODING_BASE64 6
#define SECRET_BUFFER_ENCODING_I32 7
#define SECRET_BUFFER_ENCODING_MAX 7
#define SECRET_BUFFER_ENCODING_IS_UNICODE(x) \
( (x) == SECRET_BUFFER_ENCODING_UTF8 \
|| (x) == SECRET_BUFFER_ENCODING_UTF16LE \
|| (x) == SECRET_BUFFER_ENCODING_UTF16BE \
|| (x) == SECRET_BUFFER_ENCODING_ISO8859_1 \
)
/* secret_buffer_parse struct is used as a generic way to support parsing on whole
* secret_buffers or on spans within one, or even a span within a perl SV.
* Crypt::SecretBuffer::Span does not have a public struct for now, but can be
* used to initialize a parse struct using secret_buffer_parse_init_from_sv.
*/
typedef struct {
const U8 *pos, *lim;
const char *error;
int encoding;
U8 pos_bit, lim_bit;
secret_buffer *sbuf; /* may be NULL when referencing a span from a plain PV */
} secret_buffer_parse;
/* secret_buffer_parse with writable characters */
typedef struct {
U8 *pos, *lim;
const char *error;
int encoding;
U8 pos_bit, lim_bit;
secret_buffer *sbuf; /* may be NULL when referencing a span from a plain PV */
} secret_buffer_parse_rw;
/* Initialize a parse struct, and also verify that the described span is within the
* defined length of the buffer. If not, it returns false and sets ->error.
*/
extern bool secret_buffer_parse_init(secret_buffer_parse *parse,
secret_buffer *buf, size_t pos, size_t lim, int encoding);
/* Initialize a parse struct, either from a Span, or a SecretBuffer, or a plain Scalar.
*/
extern bool secret_buffer_parse_init_from_sv(secret_buffer_parse *parse, SV *sv);
/* Create a Crypt::SecretBuffer::Span object, returning a mortal ref */
extern SV * secret_buffer_span_new_obj(secret_buffer *buf, size_t pos, size_t lim, int encoding);
/* Create a Crypt::SecretBuffer::Span object for the specified span of a SecretBuffer
* and return a mortal ref to that object. The parse struct 'sbuf' field must not be NULL
* because the span needs to hold a reference to it.
*/
extern SV * secret_buffer_span_new_obj_from_parse(secret_buffer_parse *p);
/* Scan through a SecretBuffer looking for the first (and maybe also last)
* character belonging to a set. The 'pos' and 'lim' of the parse struct
* define the range that will be searched, and will be updated with the result
* of the scan. If pos == lim at the end, the character was not found.
* Returns true if the scan completed (found or not) and false if it was
* interrupted by an invalid character.
*
* The _NEGATE flag can be used to negate the charset without altering it.
*
* The _REVERSE flag can be used to search backward from [lim-1] back to [pos],
* in which case 'lim' will be updated with the results of the scan.
*
* The _SPAN flag requests that after finding the first match and updating
* 'pos' (or 'lim' if reversed), it will then begin looking for a character not
* belonging to the charset, and then update 'lim'. (or 'pos' if reversed)
*
* If the parse state specifies an encoding, pos and lim must be at character
* boundaries, and invalid characters will stop the parse and store a message
* in ->error, also updating pos (or lim) to indicate the byte offset.
* Note that every codepoint higher than 255 compared to a charset with the
* maybe_unicode flag will call out to the perl regex engine and be a bit slow.
*/
#define SECRET_BUFFER_MATCH_REVERSE 0x0100
#define SECRET_BUFFER_MATCH_NEGATE 0x0200
#define SECRET_BUFFER_MATCH_MULTI 0x0400
#define SECRET_BUFFER_MATCH_ANCHORED 0x0800
#define SECRET_BUFFER_MATCH_CONST_TIME 0x1000
extern bool secret_buffer_match(secret_buffer_parse *p, SV *pattern, int flags);
extern bool secret_buffer_match_charset(secret_buffer_parse *p, secret_buffer_charset *cset, int flags);
extern bool secret_buffer_match_bytestr(secret_buffer_parse *p, char *data, size_t datalen, int flags);
/* Count number of bytes required to transcode the source.
* If the source contains an invalid character for its encoding, or that codepoint
* can't be encoded as the dst_encoding, this returns -1 and sets src->error
* and also sets src->pos pointing at the character that could not be converted.
*/
extern SSize_t secret_buffer_sizeof_transcode(secret_buffer_parse *src, int dst_encoding);
/* Transcode from source to destination, respecting the ->encoding of each.
*/
extern bool secret_buffer_transcode(secret_buffer_parse *src, secret_buffer_parse_rw *dst);
/* Copy characters from a parse struct to a Perl SV, optionally appending.
* This respects the src->encoding, as opposed to secret_buffer_splice which always copies
* bytes even if the source is a ::Span with an encoding.
*/
extern bool secret_buffer_copy_to(secret_buffer_parse *src, SV *dst_sv, int encoding, bool append);
/* Create a new Crypt::SecretBuffer object with a mortal ref and return its secret_buffer
* struct pointer.
* If ref_out is NULL then the mortal ref remains mortal, and as your function exits the next
* FREETMPS destroys the ref which destroys the object which destroys the magic which destroys
* the secret_buffer struct which also clears it.
* If you supply a pointer to receive ref_out, you can then increment the refcount or copy the
* ref to a new SV if you want to keep the object. As a weak-ref, it's also convenient to push
* onto perl's stack.
* Always returns a secret_buffer, or croaks on failure.
*/
extern secret_buffer * secret_buffer_new(size_t capacity, SV **ref_out);
/* Given a SV which you expect to be a reference to a blessed object with SecretBuffer
* magic, return the secret_buffer struct pointer.
* With no flags, this returns NULL if any of the above assumption are not correct.
* Specify AUTOCREATE to create a new secret_buffer (and attach with magic) if it is a blessed
* object and doesn't have the magic yet.
* Specify OR_DIE if you want an exception instead of NULL return value.
* Specify UNDEF_OK if you want input C<undef> to translate to C<NULL> even when OR_DIE is
* requested. i.e. undef becomes NULL but something which is not a SecretBuffer dies.
*/
#define SECRET_BUFFER_MAGIC_AUTOCREATE 1
#define SECRET_BUFFER_MAGIC_OR_DIE 2
#define SECRET_BUFFER_MAGIC_UNDEF_OK 4
extern secret_buffer * secret_buffer_from_magic(SV *ref, int flags);
/* Reallocate (or free) the buffer of secret_buffer, fully erasing it before deallocation.
* If capacity is zero, the buffer will be freed and 'data' pointer set to NULL.
* Any other size will allocate exactly that number of bytes, copy any previous bytes,
* wipe the old buffer, and free it.
*/
extern void secret_buffer_realloc(secret_buffer *buf, size_t new_capacity);
( run in 0.878 second using v1.01-cache-2.11-cpan-e1769b4cff6 )