/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkRWBuffer_DEFINED
#define SkRWBuffer_DEFINED

#include "include/core/SkRefCnt.h"

struct SkBufferBlock;
struct SkBufferHead;
class SkRWBuffer;
class SkStreamAsset;

/**
 *  Contains a read-only, thread-sharable block of memory. To access the memory, the caller must
 *  instantiate a local iterator, as the memory is stored in 1 or more contiguous blocks.
 */
class SK_API SkROBuffer : public SkRefCnt {
public:
    /**
     *  Return the logical length of the data owned/shared by this buffer. It may be stored in
     *  multiple contiguous blocks, accessible via the iterator.
     */
    size_t size() const { return fAvailable; }

    class SK_API Iter {
    public:
        Iter(const SkROBuffer*);
        Iter(const sk_sp<SkROBuffer>&);

        void reset(const SkROBuffer*);

        /**
         *  Return the current continuous block of memory, or nullptr if the iterator is exhausted
         */
        const void* data() const;

        /**
         *  Returns the number of bytes in the current continguous block of memory, or 0 if the
         *  iterator is exhausted.
         */
        size_t size() const;

        /**
         *  Advance to the next contiguous block of memory, returning true if there is another
         *  block, or false if the iterator is exhausted.
         */
        bool next();

    private:
        const SkBufferBlock* fBlock;
        size_t               fRemaining;
        const SkROBuffer*    fBuffer;
    };

private:
    SkROBuffer(const SkBufferHead* head, size_t available, const SkBufferBlock* fTail);
    virtual ~SkROBuffer();

    const SkBufferHead*     fHead;
    const size_t            fAvailable;
    const SkBufferBlock*    fTail;

    friend class SkRWBuffer;
};

/**
 *  Accumulates bytes of memory that are "appended" to it, growing internal storage as needed.
 *  The growth is done such that at any time in the writer's thread, an RBuffer or StreamAsset
 *  can be snapped off (and safely passed to another thread). The RBuffer/StreamAsset snapshot
 *  can see the previously stored bytes, but will be unaware of any future writes.
 */
class SK_API SkRWBuffer {
public:
    SkRWBuffer(size_t initialCapacity = 0);
    ~SkRWBuffer();

    size_t size() const { return fTotalUsed; }

    /**
     *  Append |length| bytes from |buffer|.
     *
     *  If the caller knows in advance how much more data they are going to append, they can
     *  pass a |reserve| hint (representing the number of upcoming bytes *in addition* to the
     *  current append), to minimize the number of internal allocations.
     */
    void append(const void* buffer, size_t length, size_t reserve = 0);

    sk_sp<SkROBuffer> makeROBufferSnapshot() const {
        return sk_sp<SkROBuffer>(new SkROBuffer(fHead, fTotalUsed, fTail));
    }

    std::unique_ptr<SkStreamAsset> makeStreamSnapshot() const;

#ifdef SK_DEBUG
    void validate() const;
#else
    void validate() const {}
#endif

private:
    SkBufferHead*   fHead;
    SkBufferBlock*  fTail;
    size_t          fTotalUsed;
};

#endif
