]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_utilities/lib/streams.h
2 * Copyright (c) 2000-2002,2004,2011,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 // streams.h - lightweight source and sink objects
36 using UnixPlusPlus::FileDesc
;
40 // An abstract Source object.
41 // Source can yield data when its produce method is called. Produce can yield
42 // anything between zero and length bytes and sets length accordingly.
43 // If the last call to produce returned zero bytes (and only then), the state method
44 // will yield an explanation:
45 // producing -> we're in business; there just no data quite yet (try again)
46 // stalled -> there may be more data coming, but not in the near future;
47 // wait a while then call state again to see
48 // endOfData -> no more data will be produced by this Source
49 // When called *before* the first call to produce, getSize may return the number
50 // of bytes that all calls to produce will yield together. If getSize returns unknownSize,
51 // this value cannot be determined beforehand. GetSize *may* yield the number of bytes
52 // yet to come when called after produce, but this is not guaranteed for all Sources.
56 virtual void produce(void *data
, size_t &length
) = 0;
59 static const size_t unknownSize
= size_t(-1);
60 virtual size_t getSize();
63 producing
, // yielding data (go ahead)
64 stalled
, // no data now, perhaps more later
65 endOfData
// end of data (no more data)
67 virtual State
state() const;
70 State mState
; // auto-regulated state (can be overridden)
75 // An abstract Sink object.
76 // Sinks can cansume data when their consume method is called.
77 // Sinks cannot refuse data; they always consume all data given to consume.
78 // There is currently no flow control/throttle mechanism (one will probably
85 virtual void consume(const void *data
, size_t length
) = 0;
86 virtual void setSize(size_t expectedSize
);
87 size_t getSize() {return mSize
;}
96 // The NullSource produces no data.
98 class NullSource
: public Source
{
100 void produce(void *addr
, size_t &len
);
106 // A FileSource reads from a UNIX file or file descriptor.
107 // Note that getSize will yield the size of the underlying i-node,
108 // which is usually correct but may not be in the case of simultaneous
111 class FileSource
: public Source
, public FileDesc
{
113 FileSource(const char *path
, int mode
= O_RDONLY
) : FileDesc(path
, mode
) { mState
= producing
; }
114 FileSource(int fd
) : FileDesc(fd
) { mState
= producing
; }
115 void produce(void *data
, size_t &length
);
121 // A MemorySource yields the contents of a preset contiguous memory block.
123 class MemorySource
: public Source
{
125 MemorySource(const void *data
, size_t length
) : mData(data
), mRemaining(length
) { }
127 template <class Data
>
128 MemorySource(const Data
&data
) : mData(data
.data()), mRemaining(data
.length()) { }
130 void produce(void *data
, size_t &length
);
141 // A NullSink eats all data and discards it quietly.
143 class NullSink
: public Sink
{
145 void consume(const void *data
, size_t length
);
150 // A FileSink writes its received data to a UNIX file or file descriptor.
152 class FileSink
: public Sink
, public FileDesc
{
154 FileSink(const char *path
, int mode
= O_WRONLY
| O_CREAT
| O_TRUNC
)
155 : FileDesc(path
, mode
) { }
156 FileSink(int fd
) : FileDesc(fd
) { }
157 void consume(const void *data
, size_t length
);
162 // MemorySinks collect output in a contiguous memory block.
163 // This is not often a good idea, so if you find yourself using this,
164 // consider consuming on-the-fly or streaming to secondary media,
165 // or (at least) use a BufferFifo instead.
167 class MemorySink
: public Sink
{
169 MemorySink() : mBuffer(NULL
), mMax(0) { }
170 ~MemorySink() { free(mBuffer
); }
172 void consume(const void *data
, size_t length
);
173 void setSize(size_t expectedSize
);
175 void *data() const { return mBuffer
; }
176 size_t length() const { return mSize
; }
178 void clear() { free(mBuffer
); mBuffer
= NULL
; mSize
= mMax
= 0; }
181 void grow(size_t newSize
);
184 void *mBuffer
; // buffer base
185 size_t mMax
; // currently allocated
189 } // end namespace Security
192 #endif /* _H_STREAMS */