summaryrefslogtreecommitdiffstats
path: root/src/lib/string_stream.h
blob: 939489c911c2d927d0d73c65260cc13cbd62689b (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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
#ifndef __STRING_STREAM_H__
#define __STRING_STREAM_H__

// $Id: string_stream.h,v 1.2 2014/02/03 01:30:25 daviddu Exp $
// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/string_stream.h,v $
//-----------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2013
// *! All Rights Reserved -- Property of IBM
// *! *** IBM Confidential ***
//-----------------------------------------------------------------------------

/// \file string_stream.h
/// \brief Implementations of string streams.

#include "ssx_io.h"

/// A string stream
///
/// This structure is used for the public CircularStream and WrappingStream
/// types, as well as for the library-internal types used to implement
/// sprintf() and snprintf().

typedef struct {

    /// The base class
    FILE stream;

    /// Data storage - provided by the creator
    uint8_t *data;

    /// The size of the data storage
    size_t size;

    /// The index of the next byte to write
    size_t next_write;

    /// The index of the next byte to read
    size_t next_read;

    /// Stream flags, see \ref string_stream_flags
    int flags;

} StringStream;


/// A StringStream with circular buffer semantics
///
/// The swrite() method copies the input data to the stream buffer, which is
/// treated as a circular buffer.  If the swrite() would overflow the buffer,
/// then as much data as possible is written and swrite returns -EAGAIN.  In
/// all cases swrite() returns the number of bytes actually written to the
/// buffer.
///
/// The sread() method copies data from the StringStream circular buffer to
/// the caller's buffer until either the caller's request is satisfied or all
/// of the immediately available data has been read from the buffer.  If the
/// caller's request can not be immediately granted then as much data as
/// possible is copied and sread() returns -EAGAIN. In all cases sread()
/// returns the number of bytes actually read from the buffer.
///
/// The fflush() method marks the buffer as empty, effectively losing any data
/// currently stored in the buffer.

typedef StringStream CircularStream;


/// A StringStream with wrapping circular buffer semantics
///
/// The swrite() method copies the input data to the stream buffer, which is
/// treated as a circular buffer.  If the swrite() would overflow the buffer,
/// then unread data is overwritten with new data.  If the size of the
/// swrite() exceeds the buffer length then the effect is simply to fill the
/// buffer with the final bytes of the caller's data.  swrite() always returns
/// the number of bytes requested to be written.
///
/// The sread() method copies data from the StringStream circular buffer to
/// the caller's buffer until either the caller's request is satisfied or all
/// of the immediately available data has been read from the buffer.  If the
/// caller's request can not be immediately granted then as much data as
/// possible is copied and sread() returns -EAGAIN. In all cases sread()
/// returns the number of bytes actually read from the buffer.
///
/// The fflush() method marks the buffer as empty, effectively losing any data
/// currently stored in the buffer.

typedef StringStream WrappingStream;


/// Create a StringStream
///
/// \param stream The StringStream to initialize
///
/// \param buf The stream data buffer
///
/// \param size The size of the data buffer in bytes
///
/// \param flags Flags for FILE_create()
///
/// \param swrite  The function to be installed as the swrite() function for
/// the underlying FILE object.  The sread() and fflush() functions are fixed.
///
/// This API initializes a StringStream structure for use in I/O operations.
/// This API will typically only be used by the creation functions of specific
/// StringStream types.
///
/// \retval 0 Success
///
/// \retval -STRING_STREAM_INVALID_ARGUMENT Either \a stream is NULL (0) 
/// or \a buf is NULL(0) and \a size is non-0.

int
_string_stream_create(StringStream* stream,
                      void* buf, size_t size, int flags,
                      int (*swrite)(FILE* stream,
                                    const void* buf,
                                    size_t size,
                                    size_t* written));

/// Create a CircularStream
///
/// \param stream The CircularStream to initialize
///
/// \param buf The stream data buffer
///
/// \param size The size of the data buffer in bytes
///
/// \param flags Flags for FILE_create()
///
/// This API initializes a CircularStream structure for use in I/O
/// operations.  Once created, the pointer to the CircularStream stream can be
/// cast to a FILE* and used for sread(), swrite(), fflush() and fprintf()
/// operations.
///
/// \retval 0 Success
///
/// \retval -STRING_STREAM_INVALID_ARGUMENT Either \a stream is NULL (0) 
/// or \a buf is NULL(0) and \a size is non-0.

int
circular_stream_create(CircularStream* stream,
                       void* buf, size_t size, int flags);


/// Create a WrappingStream
///
/// \param stream The WrappingStream to initialize
///
/// \param buf The stream data buffer
///
/// \param size The size of the data buffer in bytes
///
/// \param flags Flags for FILE_create()
///
/// This API initializes a WrappingStream structure for use in I/O
/// operations.  Once created, the pointer to the WrappingStream stream can be
/// cast to a FILE* and used for sread(), swrite(), fflush() and fprintf()
/// operations.
///
/// \retval 0 Success
///
/// \retval -STRING_STREAM_INVALID_ARGUMENT Either \a stream is NULL (0) 
/// or \a buf is NULL(0) and \a size is non-0.

int
wrapping_stream_create(CircularStream* stream,
                       void* buf, size_t size, int flags);


/// Create a LinearStream
///
/// \param stream The LinearStream to initialize
///
/// \param buf The stream data buffer
///
/// \param size The size of the data buffer in bytes
///
/// \param flags Flags for FILE_create()
///
/// This API initializes a LinearStream structure for use in I/O
/// operations.  Once created, the pointer to the WrappingStream stream can be
/// cast to a FILE* and used for sread(), swrite(), fflush() and fprintf()
/// operations.
///
/// \retval 0 Success
///
/// \retval -STRING_STREAM_INVALID_ARGUMENT Either \a stream is NULL (0) 
/// or \a buf is NULL(0) and \a size is non-0.


int
linear_stream_create(CircularStream* stream,
                       void* buf, size_t size, int flags);


/// A StringStream used as a read-only input stream
///
/// This is a CircualarStream created with a full buffer and without a write
/// method. It uses a special read method that returns EOF once the buffer is
/// empty rather than -EAGAIN.

typedef StringStream InputStream;


/// Create an InputStream
///
/// \param stream The InputStream to initialize
///
/// \param buf The stream data buffer.
///
/// \param size The size of the readable portion of the data buffer in bytes
///
/// \param flags Flags for FILE_create()
///
/// This API initializes an InputStream structure for use in input operations.
/// The stream data buffer contains \a size bytes of data which can be read.
/// Once created, the pointer to the InputStream stream can be cast to a FILE*
/// and used for sread(), fgetc() and ungetc() operations.  Neither fflush()
/// nor swrite() are supported on this class of stream. The read operations
/// will succeed until \a size bytes have been returned from the stream, at
/// which point the stream will return EOF on any subsequent reads.
///
/// \retval 0 Success
///
/// \retval -STRING_STREAM_INVALID_ARGUMENT Either \a stream is NULL (0) 
/// or \a buf is NULL(0) and \a size is non-0.

int
input_stream_create(InputStream* stream,
                    void* buf, size_t size, int flags);


/// \defgroup string_stream_flags StringStream Flags
///
/// @{

/// The StringStream is full
#define STRING_STREAM_FULL 0x1

/// @}


/// \defgroup string_stream_codes StringStream Error/Panic Codes
///
/// @{

/// A bug was detected in a StringStream function
#define STRING_STREAM_BUG              0x00787701
#define STRING_STREAM_INVALID_ARGUMENT 0x00787702

/// @}


#endif // __STRING_STREAM_H__
OpenPOWER on IntegriCloud