streambuf revision 743c6a2694bf16bf29d516c906363199a7bccf86
1/* -*- c++ -*- */
2/*
3 * Copyright (C) 2010 The Android Open Source Project
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *  * Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 *  * Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in
13 *    the documentation and/or other materials provided with the
14 *    distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#ifndef ANDROID_ASTL_STREAMBUF__
31#define ANDROID_ASTL_STREAMBUF__
32
33#include <char_traits.h>
34
35namespace std {
36
37/**
38 * Basic implementation of streambuf. The STL standard defines a
39 * basic_streambuf template that gets specialized for char and
40 * wchar. Since Android supports only char, we don't use a template
41 * here.
42 * Only output ops are supported.
43 * There are only 2 public entry points:
44 *  - sputc
45 *  - sputn
46 */
47
48class streambuf
49{
50  public:
51    typedef char_traits<char>       traits_type;
52    typedef traits_type::char_type  char_type;
53    typedef traits_type::int_type   int_type;
54    typedef streampos               pos_type;
55    typedef streamoff               off_type;
56
57  public:
58    virtual ~streambuf();
59
60    /**
61     *  Entry points for derived buffer functions. The public
62     *  version pubfoo dispatch to the protected foo member
63     *  functions.
64     */
65    int pubsync() { return this->sync(); }
66
67    /**
68     * Entry point for all single-character output functions. If a
69     * write position is available (buffer not full), stores c at that
70     * position, incr the position and return
71     * traits.::to_int_type(c). If no position is available returns
72     * overflow(c).
73     */
74    int_type sputc(char_type c) {
75        int_type ret;
76
77        if (this->pptr() < this->epptr()) {
78            *this->pptr() = c;
79            this->pbump(1);
80            return traits_type::to_int_type(c);
81        } else {
82            ret = this->overflow(traits_type::to_int_type(c));
83        }
84        return ret;
85    }
86
87    /**
88     * Write str[0] to str[n-1] to output sequence. Stops if sputc
89     * would return traits_type::eof().
90     * @param str  A buffer area.
91     * @param nnum  Maximum number of characters to write.
92     * @return  The number of characters written.
93     */
94    streamsize sputn(const char_type* str, streamsize num) {
95        return this->xsputn(str, num);
96    }
97
98  protected:
99    streambuf();
100
101
102    /**
103     *  Access to the put area.
104     *  - pbase() returns the beginning pointer for the output sequence.
105     *  - pptr() returns the next pointer for the output sequence.
106     *  - epptr() returns the end pointer for the output sequence.
107     *  - pbump(int) Advance the write postion in the output sequence.
108     */
109    char_type* pbase() const { return mPutBeg; }
110    char_type* pptr() const { return mPutCurr; }
111    char_type* epptr() const { return mPutEnd; }
112    void pbump(int num) {
113        if (mPutCurr + num > mPutCurr && mPutCurr + num <= mPutEnd) {
114            mPutCurr += num;
115        }
116    }
117
118    /**
119     * Set the 3 write pointers.
120     */
121    void setp(char_type* beg, char_type* end) {
122        if (end >= beg) {
123            mPutBeg = mPutCurr = beg;
124            mPutEnd = end;
125        }
126    }
127
128    /**
129     * Sync buffer array. Provided by derived class.
130     */
131    virtual int sync() { return 0; }
132
133    /**
134     * See sputn. Provided by derived class.
135     */
136    virtual streamsize xsputn(const char_type* str, streamsize num);
137
138    /**
139     * Consumes one char from the buffer, writes to the controlled
140     * sequence if possible. This is called when the buffer is
141     * full. Typically the impl will flush the buffer, write the
142     * character 'c'.
143     * Provided by derived class.
144     * @return traits::eof() in case of error, anything else otherwise.
145     */
146    virtual int_type overflow(int_type /* c */ = traits_type::eof())
147    { return traits_type::eof(); }
148
149    /**
150     * Minimal abstraction for an internal buffer.
151     *  -  put == output == write
152     */
153    char_type* 		mPutBeg;    // Start of put area.
154    char_type* 		mPutCurr;   // Current put area.
155    char_type* 		mPutEnd;    // End of put area.
156
157  private:
158    // No copy constructors.
159    streambuf(const streambuf& sb);
160    streambuf& operator=(const streambuf&) { return *this; }
161};
162
163}  // namespace std
164
165#endif
166