/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef vm_Printer_h
#define vm_Printer_h

#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>

#include "js-confdefs.h"

class JSString;

namespace js {

class ExclusiveContext;
class LifoAlloc;

// Generic printf interface, similar to an ostream in the standard library.
//
// This class is useful to make generic printers which can work either with a
// file backend, with a buffer allocated with an ExclusiveContext or a link-list
// of chunks allocated with a LifoAlloc.
class GenericPrinter
{
  protected:
    bool                  hadOOM_;     // whether reportOutOfMemory() has been called.

    GenericPrinter();

  public:
    // Puts |len| characters from |s| at the current position and return an offset to
    // the beginning of this new data.
    virtual int put(const char* s, size_t len) = 0;
    virtual int put(const char* s);

    // Prints a formatted string into the buffer.
    virtual int printf(const char* fmt, ...);
    virtual int vprintf(const char* fmt, va_list ap);

    // Report that a string operation failed to get the memory it requested. The
    // first call to this function calls JS_ReportOutOfMemory, and sets this
    // Sprinter's outOfMemory flag; subsequent calls do nothing.
    virtual void reportOutOfMemory();

    // Return true if this Sprinter ran out of memory.
    virtual bool hadOutOfMemory() const;
};

// Sprintf, but with unlimited and automatically allocated buffering.
class Sprinter final : public GenericPrinter
{
  public:
    struct InvariantChecker
    {
        const Sprinter* parent;

        explicit InvariantChecker(const Sprinter* p) : parent(p) {
            parent->checkInvariants();
        }

        ~InvariantChecker() {
            parent->checkInvariants();
        }
    };

    ExclusiveContext*     context;          // context executing the decompiler

  private:
    static const size_t   DefaultSize;
#ifdef DEBUG
    bool                  initialized;      // true if this is initialized, use for debug builds
#endif
    bool                  shouldReportOOM;  // whether to report OOM to the context
    char*                 base;             // malloc'd buffer address
    size_t                size;             // size of buffer allocated at base
    ptrdiff_t             offset;           // offset of next free char in buffer

    bool realloc_(size_t newSize);

  public:
    explicit Sprinter(ExclusiveContext* cx, bool shouldReportOOM = true);
    ~Sprinter();

    // Initialize this sprinter, returns false on error.
    bool init();

    void checkInvariants() const;

    const char* string() const;
    const char* stringEnd() const;
    // Returns the string at offset |off|.
    char* stringAt(ptrdiff_t off) const;
    // Returns the char at offset |off|.
    char& operator[](size_t off);

    // Attempt to reserve len + 1 space (for a trailing nullptr byte). If the
    // attempt succeeds, return a pointer to the start of that space and adjust the
    // internal content. The caller *must* completely fill this space on success.
    char* reserve(size_t len);

    // Puts |len| characters from |s| at the current position and return an offset to
    // the beginning of this new data.
    using GenericPrinter::put;
    virtual int put(const char* s, size_t len) override;

    // Prints a formatted string into the buffer.
    virtual int vprintf(const char* fmt, va_list ap) override;

    int putString(JSString* str);

    ptrdiff_t getOffset() const;

    // Report that a string operation failed to get the memory it requested. The
    // first call to this function calls JS_ReportOutOfMemory, and sets this
    // Sprinter's outOfMemory flag; subsequent calls do nothing.
    virtual void reportOutOfMemory() override;
};

// Fprinter, print a string directly into a file.
class Fprinter final : public GenericPrinter
{
  private:
    FILE*                   file_;
    bool                    init_;

  public:
    explicit Fprinter(FILE* fp);
    Fprinter();
    ~Fprinter();

    // Initialize this printer, returns false on error.
    bool init(const char* path);
    void init(FILE* fp);
    bool isInitialized() const {
        return file_ != nullptr;
    }
    void flush();
    void finish();

    // Puts |len| characters from |s| at the current position and return an
    // offset to the beginning of this new data.
    virtual int put(const char* s, size_t len) override;
    virtual int put(const char* s) override;

    // Prints a formatted string into the buffer.
    virtual int printf(const char* fmt, ...) override;
    virtual int vprintf(const char* fmt, va_list ap) override;
};

// LSprinter, is similar to Sprinter except that instead of using an
// ExclusiveContext to allocate strings, it use a LifoAlloc as a backend for the
// allocation of the chunk of the string.
class LSprinter final : public GenericPrinter
{
  private:
    struct Chunk
    {
        Chunk* next;
        size_t length;

        char* chars() {
            return reinterpret_cast<char*>(this + 1);
        }
        char* end() {
            return chars() + length;
        }
    };

  private:
    LifoAlloc*              alloc_;          // LifoAlloc used as a backend of chunk allocations.
    Chunk*                  head_;
    Chunk*                  tail_;
    size_t                  unused_;

  public:
    explicit LSprinter(LifoAlloc* lifoAlloc);
    ~LSprinter();

    // Copy the content of the chunks into another printer, such that we can
    // flush the content of this printer to a file.
    void exportInto(GenericPrinter& out) const;

    // Drop the current string, and let them be free with the LifoAlloc.
    void clear();

    // Puts |len| characters from |s| at the current position and return an
    // offset to the beginning of this new data.
    virtual int put(const char* s, size_t len) override;
    virtual int put(const char* s) override;

    // Prints a formatted string into the buffer.
    virtual int printf(const char* fmt, ...) override;
    virtual int vprintf(const char* fmt, va_list ap) override;

    // Report that a string operation failed to get the memory it requested. The
    // first call to this function calls JS_ReportOutOfMemory, and sets this
    // Sprinter's outOfMemory flag; subsequent calls do nothing.
    virtual void reportOutOfMemory() override;

    // Return true if this Sprinter ran out of memory.
    virtual bool hadOutOfMemory() const override;
};

extern ptrdiff_t
Sprint(Sprinter* sp, const char* format, ...);

// Map escaped code to the letter/symbol escaped with a backslash.
extern const char       js_EscapeMap[];

// Return a GC'ed string containing the chars in str, with any non-printing
// chars or quotes (' or " as specified by the quote argument) escaped, and
// with the quote character at the beginning and end of the result string.
extern JSString*
QuoteString(ExclusiveContext* cx, JSString* str, char16_t quote);

extern char*
QuoteString(Sprinter* sp, JSString* str, char16_t quote);


} // namespace js

#endif // vm_Printer_h
