// Written in the D programming language.

/**
Serialize data to `ubyte` arrays.

 * Copyright: Copyright The D Language Foundation 2000 - 2015.
 * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
 * Authors:   $(HTTP digitalmars.com, Walter Bright)
 * Source:    $(PHOBOSSRC std/outbuffer.d)
 *
 * $(SCRIPT inhibitQuickIndex = 1;)
 */
module std.outbuffer;

import core.stdc.stdarg;
import std.traits : isSomeString;

/*********************************************
 * OutBuffer provides a way to build up an array of bytes out
 * of raw data. It is useful for things like preparing an
 * array of bytes to write out to a file.
 * OutBuffer's byte order is the format native to the computer.
 * To control the byte order (endianness), use a class derived
 * from OutBuffer.
 *
 * OutBuffer's internal buffer is allocated with the GC. Pointers
 * stored into the buffer are scanned by the GC, but you have to
 * ensure proper alignment, e.g. by using `alignSize((void*).sizeof)`.
 */

class OutBuffer
{
    ubyte[] data;
    size_t offset;

    invariant()
    {
        assert(offset <= data.length);
    }

  pure nothrow @safe
  {
    /*********************************
     * Convert to array of bytes.
     */
    inout(ubyte)[] toBytes() scope inout { return data[0 .. offset]; }

    /***********************************
     * Preallocate nbytes more to the size of the internal buffer.
     *
     * This is a
     * speed optimization, a good guess at the maximum size of the resulting
     * buffer will improve performance by eliminating reallocations and copying.
     */
    void reserve(size_t nbytes) @trusted
        in
        {
            assert(offset + nbytes >= offset);
        }
        out
        {
            assert(offset + nbytes <= data.length);
        }
        do
        {
            if (data.length < offset + nbytes)
            {
                void[] vdata = data;
                vdata.length = (offset + nbytes + 7) * 2; // allocates as void[] to not set BlkAttr.NO_SCAN
                data = cast(ubyte[]) vdata;
            }
        }

    /**********************************
     * put enables OutBuffer to be used as an OutputRange.
     */
    alias put = write;

    /*************************************
     * Append data to the internal buffer.
     */

    void write(scope const(ubyte)[] bytes)
        {
            reserve(bytes.length);
            data[offset .. offset + bytes.length] = bytes[];
            offset += bytes.length;
        }

    void write(scope const(wchar)[] chars) @trusted
        {
        write(cast(ubyte[]) chars);
        }

    void write(scope const(dchar)[] chars) @trusted
        {
        write(cast(ubyte[]) chars);
        }

    void write(ubyte b)         /// ditto
        {
            reserve(ubyte.sizeof);
            this.data[offset] = b;
            offset += ubyte.sizeof;
        }

    void write(byte b) { write(cast(ubyte) b); }         /// ditto
    void write(char c) { write(cast(ubyte) c); }         /// ditto
    void write(dchar c) { write(cast(uint) c); }         /// ditto

    void write(ushort w) @trusted                /// ditto
    {
        reserve(ushort.sizeof);
        *cast(ushort *)&data[offset] = w;
        offset += ushort.sizeof;
    }

    void write(short s) { write(cast(ushort) s); }               /// ditto

    void write(wchar c) @trusted        /// ditto
    {
        reserve(wchar.sizeof);
        *cast(wchar *)&data[offset] = c;
        offset += wchar.sizeof;
    }

    void write(uint w) @trusted         /// ditto
    {
        reserve(uint.sizeof);
        *cast(uint *)&data[offset] = w;
        offset += uint.sizeof;
    }

    void write(int i) { write(cast(uint) i); }           /// ditto

    void write(ulong l) @trusted         /// ditto
    {
        reserve(ulong.sizeof);
        *cast(ulong *)&data[offset] = l;
        offset += ulong.sizeof;
    }

    void write(long l) { write(cast(ulong) l); }         /// ditto

    void write(float f) @trusted         /// ditto
    {
        reserve(float.sizeof);
        *cast(float *)&data[offset] = f;
        offset += float.sizeof;
    }

    void write(double f) @trusted               /// ditto
    {
        reserve(double.sizeof);
        *cast(double *)&data[offset] = f;
        offset += double.sizeof;
    }

    void write(real f) @trusted         /// ditto
    {
        reserve(real.sizeof);
        *cast(real *)&data[offset] = f;
        offset += real.sizeof;
    }

    void write(scope const(char)[] s) @trusted             /// ditto
    {
        write(cast(ubyte[]) s);
    }

    void write(scope const OutBuffer buf)           /// ditto
    {
        write(buf.toBytes());
    }

    /****************************************
     * Append nbytes of val to the internal buffer.
     * Params:
     *   nbytes = Number of bytes to fill.
     *   val = Value to fill, defaults to 0.
     */

    void fill(size_t nbytes, ubyte val = 0)
    {
        reserve(nbytes);
        data[offset .. offset + nbytes] = val;
        offset += nbytes;
    }

    /****************************************
     * Append nbytes of 0 to the internal buffer.
     * Param:
     *   nbytes - number of bytes to fill.
     */
    void fill0(size_t nbytes)
    {
        fill(nbytes);
    }

    /**********************************
     * Append bytes until the buffer aligns on a power of 2 boundary.
     *
     * By default fills with 0 bytes.
     *
     * Params:
     *   alignsize = Alignment value. Must be power of 2.
     *   val = Value to fill, defaults to 0.
     */

    void alignSize(size_t alignsize, ubyte val = 0)
    in
    {
        assert(alignsize && (alignsize & (alignsize - 1)) == 0);
    }
    out
    {
        assert((offset & (alignsize - 1)) == 0);
    }
    do
    {
        auto nbytes = offset & (alignsize - 1);
        if (nbytes)
            fill(alignsize - nbytes, val);
    }
    ///
    @safe unittest
    {
        OutBuffer buf = new OutBuffer();
        buf.write(cast(ubyte) 1);
        buf.align2();
        assert(buf.toBytes() == "\x01\x00");
        buf.write(cast(ubyte) 2);
        buf.align4();
        assert(buf.toBytes() == "\x01\x00\x02\x00");
        buf.write(cast(ubyte) 3);
        buf.alignSize(8);
        assert(buf.toBytes() == "\x01\x00\x02\x00\x03\x00\x00\x00");
    }
    /// ditto
    @safe unittest
    {
        OutBuffer buf = new OutBuffer();
        buf.write(cast(ubyte) 1);
        buf.align2(0x55);
        assert(buf.toBytes() == "\x01\x55");
        buf.write(cast(ubyte) 2);
        buf.align4(0x55);
        assert(buf.toBytes() == "\x01\x55\x02\x55");
        buf.write(cast(ubyte) 3);
        buf.alignSize(8, 0x55);
        assert(buf.toBytes() == "\x01\x55\x02\x55\x03\x55\x55\x55");
    }

    /// Clear the data in the buffer
    void clear()
    {
        offset = 0;
    }

    /****************************************
     * Optimize common special case alignSize(2)
     * Params:
     *   val = Value to fill, defaults to 0.
     */

    void align2(ubyte val = 0)
    {
        if (offset & 1)
            write(cast(byte) val);
    }

    /****************************************
     * Optimize common special case alignSize(4)
     * Params:
     *   val = Value to fill, defaults to 0.
     */

    void align4(ubyte val = 0)
    {
        if (offset & 3)
        {   auto nbytes = (4 - offset) & 3;
            fill(nbytes, val);
        }
    }

    /**************************************
     * Convert internal buffer to array of chars.
     */

    override string toString() const
    {
        //printf("OutBuffer.toString()\n");
        return cast(string) data[0 .. offset].idup;
    }
  }

    /*****************************************
     * Append output of C's vprintf() to internal buffer.
     */

    void vprintf(scope string format, va_list args) @system nothrow
    {
        import core.stdc.stdio : vsnprintf;
        import core.stdc.stdlib : alloca;
        import std.string : toStringz;

        version (StdUnittest)
            char[3] buffer = void;      // trigger reallocation
        else
            char[128] buffer = void;
        int count;

        // Can't use `tempCString()` here as it will result in compilation error:
        // "cannot mix core.std.stdlib.alloca() and exception handling".
        auto f = toStringz(format);
        auto p = buffer.ptr;
        auto psize = buffer.length;
        for (;;)
        {
            va_list args2;
            va_copy(args2, args);
            count = vsnprintf(p, psize, f, args2);
            va_end(args2);
            if (count == -1)
            {
                if (psize > psize.max / 2) assert(0); // overflow check
                psize *= 2;
            }
            else if (count >= psize)
            {
                if (count == count.max) assert(0); // overflow check
                psize = count + 1;
            }
            else
                break;

            p = cast(char *) alloca(psize); // buffer too small, try again with larger size
        }
        write(cast(ubyte[]) p[0 .. count]);
    }

    /*****************************************
     * Append output of C's printf() to internal buffer.
     */

    void printf(scope string format, ...) @system
    {
        va_list ap;
        va_start(ap, format);
        vprintf(format, ap);
        va_end(ap);
    }

    /**
     * Formats and writes its arguments in text format to the OutBuffer.
     *
     * Params:
     *  fmt = format string as described in $(REF formattedWrite, std,format)
     *  args = arguments to be formatted
     *
     * See_Also:
     *  $(REF _writef, std,stdio);
     *  $(REF formattedWrite, std,format);
     */
    void writef(Char, A...)(scope const(Char)[] fmt, A args)
    {
        import std.format.write : formattedWrite;
        formattedWrite(this, fmt, args);
    }

    ///
    @safe unittest
    {
        OutBuffer b = new OutBuffer();
        b.writef("a%sb", 16);
        assert(b.toString() == "a16b");
    }

    /// ditto
    void writef(alias fmt, A...)(A args)
    if (isSomeString!(typeof(fmt)))
    {
        import std.format : checkFormatException;

        alias e = checkFormatException!(fmt, A);
        static assert(!e, e);
        return this.writef(fmt, args);
    }

    ///
    @safe unittest
    {
        OutBuffer b = new OutBuffer();
        b.writef!"a%sb"(16);
        assert(b.toString() == "a16b");
    }

    /**
     * Formats and writes its arguments in text format to the OutBuffer,
     * followed by a newline.
     *
     * Params:
     *  fmt = format string as described in $(REF formattedWrite, std,format)
     *  args = arguments to be formatted
     *
     * See_Also:
     *  $(REF _writefln, std,stdio);
     *  $(REF formattedWrite, std,format);
     */
    void writefln(Char, A...)(scope const(Char)[] fmt, A args)
    {
        import std.format.write : formattedWrite;
        formattedWrite(this, fmt, args);
        put('\n');
    }

    ///
    @safe unittest
    {
        OutBuffer b = new OutBuffer();
        b.writefln("a%sb", 16);
        assert(b.toString() == "a16b\n");
    }

    /// ditto
    void writefln(alias fmt, A...)(A args)
    if (isSomeString!(typeof(fmt)))
    {
        import std.format : checkFormatException;

        alias e = checkFormatException!(fmt, A);
        static assert(!e, e);
        return this.writefln(fmt, args);
    }

    ///
    @safe unittest
    {
        OutBuffer b = new OutBuffer();
        b.writefln!"a%sb"(16);
        assert(b.toString() == "a16b\n");
    }

    /*****************************************
     * At offset index into buffer, create nbytes of space by shifting upwards
     * all data past index.
     */

    void spread(size_t index, size_t nbytes) pure nothrow @safe
        in
        {
            assert(index <= offset);
        }
        do
        {
            reserve(nbytes);

            // This is an overlapping copy - should use memmove()
            for (size_t i = offset; i > index; )
            {
                --i;
                data[i + nbytes] = data[i];
            }
            offset += nbytes;
        }
}

///
@safe unittest
{
    import std.string : cmp;

    OutBuffer buf = new OutBuffer();

    assert(buf.offset == 0);
    buf.write("hello");
    buf.write(cast(byte) 0x20);
    buf.write("world");
    buf.writef(" %d", 62665);
    assert(cmp(buf.toString(), "hello world 62665") == 0);

    buf.clear();
    assert(cmp(buf.toString(), "") == 0);
    buf.write("New data");
    assert(cmp(buf.toString(),"New data") == 0);
}

@safe unittest
{
    import std.range;
    static assert(isOutputRange!(OutBuffer, char));

    import std.algorithm;
  {
    OutBuffer buf = new OutBuffer();
    "hello".copy(buf);
    assert(buf.toBytes() == "hello");
  }
  {
    OutBuffer buf = new OutBuffer();
    "hello"w.copy(buf);
    version (LittleEndian)
        assert(buf.toBytes() == "h\x00e\x00l\x00l\x00o\x00");
    version (BigEndian)
        assert(buf.toBytes() == "\x00h\x00e\x00l\x00l\x00o");
  }
  {
    OutBuffer buf = new OutBuffer();
    "hello"d.copy(buf);
    version (LittleEndian)
        assert(buf.toBytes() == "h\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00");
    version (BigEndian)
        assert(buf.toBytes() == "\x00\x00\x00h\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o");
  }
}
