/*
 * 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);
    ~SkROBuffer() override;

    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
