summaryrefslogtreecommitdiff
path: root/egg/egg-buffer.h
blob: bd710f3ee0b10bee3ec8307ebef0e49670d87cb0 (plain)
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* egg-buffer.h - Generic data buffer, used by openssh, gnome-keyring

   Copyright (C) 2007, Stefan Walter

   The Gnome Keyring Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The Gnome Keyring Library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the Gnome Library; see the file COPYING.LIB.  If not,
   <http://www.gnu.org/licenses/>.

   Author: Stef Walter <stef@memberwebs.com>
*/

#ifndef EGG_BUFFER_H
#define EGG_BUFFER_H

#include <stdlib.h>
#include <stdint.h>

/* -------------------------------------------------------------------
 * EggBuffer 
 * 
 * IMPORTANT: This is pure vanila standard C, no glib. We need this 
 * because certain consumers of this protocol need to be built 
 * without linking in any special libraries. ie: the PKCS#11 module.
 * 
 * Memory Allocation
 * 
 * Callers can set their own allocator. If NULL is used then standard 
 * C library heap memory is used and failures will not be fatal. Memory 
 * failures will instead result in a zero return value or 
 * egg_buffer_has_error() returning one.
 * 
 * If you use something like g_realloc as the allocator, then memory 
 * failures become fatal just like in a standard GTK program.
 * 
 * Don't change the allocator manually in the EggBuffer structure. The 
 * egg_buffer_set_allocator() func will reallocate and handle things 
 * properly.
 * 
 * Pointers into the Buffer
 * 
 * Any write operation has the posibility of reallocating memory
 * and invalidating any direct pointers into the buffer.
 */
 
/* The allocator for the EggBuffer. This follows the realloc() syntax and logic */
typedef void* (*EggBufferAllocator) (void* p, size_t len);

typedef struct _EggBuffer {
	unsigned char *buf;
	size_t len;
	size_t allocated_len;
	int failures; 
	EggBufferAllocator allocator;
} EggBuffer;

#define 	EGG_BUFFER_EMPTY		{ NULL, 0, 0, 0, NULL }

int             egg_buffer_init                 (EggBuffer *buffer, size_t reserve);

int             egg_buffer_init_full            (EggBuffer *buffer, 
                                                 size_t reserve, 
                                                 EggBufferAllocator allocator);

void            egg_buffer_init_static          (EggBuffer *buffer,
                                                 const unsigned char *buf,
                                                 size_t len);

void            egg_buffer_init_allocated       (EggBuffer *buffer,
                                                 unsigned char *buf,
                                                 size_t len,
                                                 EggBufferAllocator allocator);
                                                 
void            egg_buffer_uninit               (EggBuffer *buffer);

unsigned char*  egg_buffer_uninit_steal         (EggBuffer *buffer,
                                                 size_t *n_result);

int             egg_buffer_set_allocator        (EggBuffer *buffer,
                                                 EggBufferAllocator allocator);

void 		egg_buffer_reset		(EggBuffer *buffer);

int		egg_buffer_equal		(EggBuffer *b1,
						 EggBuffer *b2);

int             egg_buffer_reserve              (EggBuffer *buffer,
                                                 size_t len);
						 
int             egg_buffer_resize               (EggBuffer *buffer,
                                                 size_t len);

int		egg_buffer_append 		(EggBuffer *buffer,
						 const unsigned char *val,
						 size_t len);

unsigned char*  egg_buffer_add_empty            (EggBuffer *buffer,
                                                 size_t len);

int 		egg_buffer_add_byte		(EggBuffer *buffer,
						 unsigned char val);

int 		egg_buffer_get_byte		(EggBuffer *buffer,
						 size_t offset,
						 size_t *next_offset,
						 unsigned char *val);
									 
void 		egg_buffer_encode_uint32	(unsigned char* buf, 
						 uint32_t val);

uint32_t	egg_buffer_decode_uint32	(unsigned char* buf);

int 		egg_buffer_add_uint32		(EggBuffer *buffer,
						 uint32_t val);

int		egg_buffer_set_uint32		(EggBuffer *buffer,
						 size_t offset, 
						 uint32_t val);

int		egg_buffer_get_uint32		(EggBuffer *buffer,
						 size_t offset,
						 size_t *next_offset,
						 uint32_t *val);

void 		egg_buffer_encode_uint16	(unsigned char* buf, 
						 uint16_t val);

uint16_t	egg_buffer_decode_uint16	(unsigned char* buf);

int 		egg_buffer_add_uint16		(EggBuffer *buffer,
						 uint16_t val);

int		egg_buffer_set_uint16		(EggBuffer *buffer,
						 size_t offset, 
						 uint16_t val);

int		egg_buffer_get_uint16		(EggBuffer *buffer,
						 size_t offset,
						 size_t *next_offset,
						 uint16_t *val);

int		egg_buffer_add_byte_array	(EggBuffer *buffer,
						 const unsigned char *val,
						 size_t len);

int		egg_buffer_get_byte_array	(EggBuffer *buffer,
						 size_t offset,
						 size_t *next_offset,
						 const unsigned char **val,
						 size_t *vlen);

unsigned char*  egg_buffer_add_byte_array_empty (EggBuffer *buffer,
                                                 size_t vlen);						 

int             egg_buffer_add_string           (EggBuffer *buffer, 
                                                 const char *str);
                                                 
int             egg_buffer_get_string           (EggBuffer *buffer, 
                                                 size_t offset, 
                                                 size_t *next_offset, 
                                                 char **str_ret, 
                                                 EggBufferAllocator allocator);

int             egg_buffer_add_stringv          (EggBuffer *buffer, 
                                                 const char** strv);

int             egg_buffer_get_stringv          (EggBuffer *buffer,
                                                 size_t offset,
                                                 size_t *next_offset,
                                                 char ***strv_ret, 
                                                 EggBufferAllocator allocator);

int		egg_buffer_add_uint64		(EggBuffer *buffer,
						 uint64_t val);

int		egg_buffer_get_uint64		(EggBuffer *buffer,
						 size_t offset,
						 size_t *next_offset,
						 uint64_t *val);

#define		egg_buffer_length(b)		((b)->len)

#define 	egg_buffer_has_error(b)		((b)->failures > 0)

#endif /* EGG_BUFFER_H */