// 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) @trusted 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, ...) @trusted
    {
        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.printf(" %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");
  }
}
