Home | History | Annotate | Download | only in wtf
      1 /*
      2 * Copyright (C) 2012 Google Inc. All rights reserved.
      3 *
      4 * Redistribution and use in source and binary forms, with or without
      5 * modification, are permitted provided that the following conditions are
      6 * met:
      7 *
      8 *     * Redistributions of source code must retain the above copyright
      9 * notice, this list of conditions and the following disclaimer.
     10 *     * Redistributions in binary form must reproduce the above
     11 * copyright notice, this list of conditions and the following disclaimer
     12 * in the documentation and/or other materials provided with the
     13 * distribution.
     14 *     * Neither the name of Google Inc. nor the names of its
     15 * contributors may be used to endorse or promote products derived from
     16 * this software without specific prior written permission.
     17 *
     18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 */
     30 
     31 #ifndef WTF_StreamBuffer_h
     32 #define WTF_StreamBuffer_h
     33 
     34 #include "wtf/Deque.h"
     35 #include "wtf/PassOwnPtr.h"
     36 
     37 namespace WTF {
     38 
     39 template <typename T, size_t BlockSize> class StreamBuffer {
     40 private:
     41     typedef Vector<T> Block;
     42 public:
     43     StreamBuffer()
     44         : m_size(0)
     45         , m_readOffset(0)
     46     {
     47     }
     48 
     49     ~StreamBuffer()
     50     {
     51     }
     52 
     53     bool isEmpty() const { return !size(); }
     54 
     55     void append(const T* data, size_t size)
     56     {
     57         if (!size)
     58             return;
     59 
     60         m_size += size;
     61         while (size) {
     62             if (!m_buffer.size() || m_buffer.last()->size() == BlockSize)
     63                 m_buffer.append(adoptPtr(new Block));
     64             size_t appendSize = std::min(BlockSize - m_buffer.last()->size(), size);
     65             m_buffer.last()->append(data, appendSize);
     66             data += appendSize;
     67             size -= appendSize;
     68         }
     69     }
     70 
     71     // This function consume data in the fist block.
     72     // Specified size must be less than over equal to firstBlockSize().
     73     void consume(size_t size)
     74     {
     75         ASSERT(m_size >= size);
     76         if (!m_size)
     77             return;
     78 
     79         ASSERT(m_buffer.size() > 0);
     80         ASSERT(m_readOffset + size <= m_buffer.first()->size());
     81         m_readOffset += size;
     82         m_size -= size;
     83         if (m_readOffset >= m_buffer.first()->size()) {
     84             m_readOffset = 0;
     85             m_buffer.removeFirst();
     86         }
     87     }
     88 
     89     size_t size() const { return m_size; }
     90 
     91     const T* firstBlockData() const
     92     {
     93         if (!m_size)
     94             return 0;
     95         ASSERT(m_buffer.size() > 0);
     96         return &m_buffer.first()->data()[m_readOffset];
     97     }
     98 
     99     size_t firstBlockSize() const
    100     {
    101         if (!m_size)
    102             return 0;
    103         ASSERT(m_buffer.size() > 0);
    104         return m_buffer.first()->size() - m_readOffset;
    105     }
    106 
    107 private:
    108     size_t m_size;
    109     size_t m_readOffset;
    110     Deque<OwnPtr<Block> > m_buffer;
    111 };
    112 
    113 } // namespace WTF
    114 
    115 using WTF::StreamBuffer;
    116 
    117 #endif // WTF_StreamBuffer_h
    118