]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_utilities/lib/streams.h
0d2036d7e097851b4cfe37fd4a9c4bb029b807d6
   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 */