michael@0: // Copyright 2011 Google Inc. All Rights Reserved. michael@0: // michael@0: // Redistribution and use in source and binary forms, with or without michael@0: // modification, are permitted provided that the following conditions are michael@0: // met: michael@0: // michael@0: // * Redistributions of source code must retain the above copyright michael@0: // notice, this list of conditions and the following disclaimer. michael@0: // * Redistributions in binary form must reproduce the above michael@0: // copyright notice, this list of conditions and the following disclaimer michael@0: // in the documentation and/or other materials provided with the michael@0: // distribution. michael@0: // * Neither the name of Google Inc. nor the names of its michael@0: // contributors may be used to endorse or promote products derived from michael@0: // this software without specific prior written permission. michael@0: // michael@0: // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR michael@0: // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT michael@0: // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@0: // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@0: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, michael@0: // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY michael@0: // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE michael@0: // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: michael@0: #ifndef UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_ michael@0: #define UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_ michael@0: michael@0: #include michael@0: michael@0: michael@0: namespace snappy { michael@0: michael@0: // A Sink is an interface that consumes a sequence of bytes. michael@0: class Sink { michael@0: public: michael@0: Sink() { } michael@0: virtual ~Sink(); michael@0: michael@0: // Append "bytes[0,n-1]" to this. michael@0: virtual void Append(const char* bytes, size_t n) = 0; michael@0: michael@0: // Returns a writable buffer of the specified length for appending. michael@0: // May return a pointer to the caller-owned scratch buffer which michael@0: // must have at least the indicated length. The returned buffer is michael@0: // only valid until the next operation on this Sink. michael@0: // michael@0: // After writing at most "length" bytes, call Append() with the michael@0: // pointer returned from this function and the number of bytes michael@0: // written. Many Append() implementations will avoid copying michael@0: // bytes if this function returned an internal buffer. michael@0: // michael@0: // If a non-scratch buffer is returned, the caller may only pass a michael@0: // prefix of it to Append(). That is, it is not correct to pass an michael@0: // interior pointer of the returned array to Append(). michael@0: // michael@0: // The default implementation always returns the scratch buffer. michael@0: virtual char* GetAppendBuffer(size_t length, char* scratch); michael@0: michael@0: private: michael@0: // No copying michael@0: Sink(const Sink&); michael@0: void operator=(const Sink&); michael@0: }; michael@0: michael@0: // A Source is an interface that yields a sequence of bytes michael@0: class Source { michael@0: public: michael@0: Source() { } michael@0: virtual ~Source(); michael@0: michael@0: // Return the number of bytes left to read from the source michael@0: virtual size_t Available() const = 0; michael@0: michael@0: // Peek at the next flat region of the source. Does not reposition michael@0: // the source. The returned region is empty iff Available()==0. michael@0: // michael@0: // Returns a pointer to the beginning of the region and store its michael@0: // length in *len. michael@0: // michael@0: // The returned region is valid until the next call to Skip() or michael@0: // until this object is destroyed, whichever occurs first. michael@0: // michael@0: // The returned region may be larger than Available() (for example michael@0: // if this ByteSource is a view on a substring of a larger source). michael@0: // The caller is responsible for ensuring that it only reads the michael@0: // Available() bytes. michael@0: virtual const char* Peek(size_t* len) = 0; michael@0: michael@0: // Skip the next n bytes. Invalidates any buffer returned by michael@0: // a previous call to Peek(). michael@0: // REQUIRES: Available() >= n michael@0: virtual void Skip(size_t n) = 0; michael@0: michael@0: private: michael@0: // No copying michael@0: Source(const Source&); michael@0: void operator=(const Source&); michael@0: }; michael@0: michael@0: // A Source implementation that yields the contents of a flat array michael@0: class ByteArraySource : public Source { michael@0: public: michael@0: ByteArraySource(const char* p, size_t n) : ptr_(p), left_(n) { } michael@0: virtual ~ByteArraySource(); michael@0: virtual size_t Available() const; michael@0: virtual const char* Peek(size_t* len); michael@0: virtual void Skip(size_t n); michael@0: private: michael@0: const char* ptr_; michael@0: size_t left_; michael@0: }; michael@0: michael@0: // A Sink implementation that writes to a flat array without any bound checks. michael@0: class UncheckedByteArraySink : public Sink { michael@0: public: michael@0: explicit UncheckedByteArraySink(char* dest) : dest_(dest) { } michael@0: virtual ~UncheckedByteArraySink(); michael@0: virtual void Append(const char* data, size_t n); michael@0: virtual char* GetAppendBuffer(size_t len, char* scratch); michael@0: michael@0: // Return the current output pointer so that a caller can see how michael@0: // many bytes were produced. michael@0: // Note: this is not a Sink method. michael@0: char* CurrentDestination() const { return dest_; } michael@0: private: michael@0: char* dest_; michael@0: }; michael@0: michael@0: michael@0: } michael@0: michael@0: #endif // UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_