/**
 * @file out.c
 * @author Radek Krejci <rkrejci@cesnet.cz>
 * @brief libyang output functions.
 *
 * Copyright (c) 2015 - 2020 CESNET, z.s.p.o.
 *
 * This source code is licensed under BSD 3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/BSD-3-Clause
 */

#define _GNU_SOURCE
#define _POSIX_C_SOURCE 200809L /* strdup, vdprintf */

#include "out.h"
#include "out_internal.h"

#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "common.h"
#include "compat.h"
#include "log.h"
#include "printer_data.h"
#include "printer_internal.h"
#include "tree_data.h"
#include "tree_schema.h"

/**
 * @brief informational structure shared by printers
 */
struct ext_substmt_info_s ext_substmt_info[] = {
    {NULL, NULL, 0},                            /**< LYEXT_SUBSTMT_SELF */
    {"argument", "name", SUBST_FLAG_ID},        /**< LYEXT_SUBSTMT_ARGUMENT */
    {"base", "name", SUBST_FLAG_ID},            /**< LYEXT_SUBSTMT_BASE */
    {"belongs-to", "module", SUBST_FLAG_ID},    /**< LYEXT_SUBSTMT_BELONGSTO */
    {"contact", "text", SUBST_FLAG_YIN},        /**< LYEXT_SUBSTMT_CONTACT */
    {"default", "value", 0},                    /**< LYEXT_SUBSTMT_DEFAULT */
    {"description", "text", SUBST_FLAG_YIN},    /**< LYEXT_SUBSTMT_DESCRIPTION */
    {"error-app-tag", "value", 0},              /**< LYEXT_SUBSTMT_ERRTAG */
    {"error-message", "value", SUBST_FLAG_YIN}, /**< LYEXT_SUBSTMT_ERRMSG */
    {"key", "value", 0},                        /**< LYEXT_SUBSTMT_KEY */
    {"namespace", "uri", 0},                    /**< LYEXT_SUBSTMT_NAMESPACE */
    {"organization", "text", SUBST_FLAG_YIN},   /**< LYEXT_SUBSTMT_ORGANIZATION */
    {"path", "value", 0},                       /**< LYEXT_SUBSTMT_PATH */
    {"prefix", "value", SUBST_FLAG_ID},         /**< LYEXT_SUBSTMT_PREFIX */
    {"presence", "value", 0},                   /**< LYEXT_SUBSTMT_PRESENCE */
    {"reference", "text", SUBST_FLAG_YIN},      /**< LYEXT_SUBSTMT_REFERENCE */
    {"revision-date", "date", SUBST_FLAG_ID},   /**< LYEXT_SUBSTMT_REVISIONDATE */
    {"units", "name", 0},                       /**< LYEXT_SUBSTMT_UNITS */
    {"value", "value", SUBST_FLAG_ID},          /**< LYEXT_SUBSTMT_VALUE */
    {"yang-version", "value", SUBST_FLAG_ID},   /**< LYEXT_SUBSTMT_VERSION */
    {"modifier", "value", SUBST_FLAG_ID},       /**< LYEXT_SUBSTMT_MODIFIER */
    {"require-instance", "value", SUBST_FLAG_ID}, /**< LYEXT_SUBSTMT_REQINST */
    {"yin-element", "value", SUBST_FLAG_ID},    /**< LYEXT_SUBSTMT_YINELEM */
    {"config", "value", SUBST_FLAG_ID},         /**< LYEXT_SUBSTMT_CONFIG */
    {"mandatory", "value", SUBST_FLAG_ID},      /**< LYEXT_SUBSTMT_MANDATORY */
    {"ordered-by", "value", SUBST_FLAG_ID},     /**< LYEXT_SUBSTMT_ORDEREDBY */
    {"status", "value", SUBST_FLAG_ID},         /**< LYEXT_SUBSTMT_STATUS */
    {"fraction-digits", "value", SUBST_FLAG_ID}, /**< LYEXT_SUBSTMT_DIGITS */
    {"max-elements", "value", SUBST_FLAG_ID},   /**< LYEXT_SUBSTMT_MAX */
    {"min-elements", "value", SUBST_FLAG_ID},   /**< LYEXT_SUBSTMT_MIN */
    {"position", "value", SUBST_FLAG_ID},       /**< LYEXT_SUBSTMT_POSITION */
    {"unique", "tag", 0},                       /**< LYEXT_SUBSTMT_UNIQUE */
};

ly_bool
ly_should_print(const struct lyd_node *node, uint32_t options)
{
    const struct lyd_node *elem;

    if (options & LYD_PRINT_WD_TRIM) {
        /* do not print default nodes */
        if (node->flags & LYD_DEFAULT) {
            /* implicit default node/NP container with only default nodes */
            return 0;
        } else if (node->schema->nodetype & LYD_NODE_TERM) {
            if (lyd_is_default(node)) {
                /* explicit default node */
                return 0;
            }
        }
    } else if ((node->flags & LYD_DEFAULT) && !(options & LYD_PRINT_WD_MASK) && !(node->schema->flags & LYS_CONFIG_R)) {
        /* LYDP_WD_EXPLICIT
         * - print only if it contains status data in its subtree */
        LYD_TREE_DFS_BEGIN(node, elem) {
            if ((elem->schema->nodetype != LYS_CONTAINER) || (elem->schema->flags & LYS_PRESENCE)) {
                if (elem->schema->flags & LYS_CONFIG_R) {
                    return 1;
                }
            }
            LYD_TREE_DFS_END(node, elem)
        }
        return 0;
    } else if ((node->flags & LYD_DEFAULT) && (node->schema->nodetype == LYS_CONTAINER) && !(options & LYD_PRINT_KEEPEMPTYCONT)) {
        /* avoid empty default containers */
        LYD_TREE_DFS_BEGIN(node, elem) {
            if (elem->schema->nodetype != LYS_CONTAINER) {
                return 1;
            }
            assert(elem->flags & LYD_DEFAULT);
            LYD_TREE_DFS_END(node, elem)
        }
        return 0;
    }

    return 1;
}

API LY_OUT_TYPE
ly_out_type(const struct ly_out *out)
{
    LY_CHECK_ARG_RET(NULL, out, LY_OUT_ERROR);
    return out->type;
}

API LY_ERR
ly_out_new_clb(ly_write_clb writeclb, void *user_data, struct ly_out **out)
{
    LY_CHECK_ARG_RET(NULL, out, writeclb, LY_EINVAL);

    *out = calloc(1, sizeof **out);
    LY_CHECK_ERR_RET(!*out, LOGMEM(NULL), LY_EMEM);

    (*out)->type = LY_OUT_CALLBACK;
    (*out)->method.clb.func = writeclb;
    (*out)->method.clb.arg = user_data;

    return LY_SUCCESS;
}

API ly_write_clb
ly_out_clb(struct ly_out *out, ly_write_clb writeclb)
{
    void *prev_clb;

    LY_CHECK_ARG_RET(NULL, out, out->type == LY_OUT_CALLBACK, NULL);

    prev_clb = out->method.clb.func;

    if (writeclb) {
        out->method.clb.func = writeclb;
    }

    return prev_clb;
}

API void *
ly_out_clb_arg(struct ly_out *out, void *arg)
{
    void *prev_arg;

    LY_CHECK_ARG_RET(NULL, out, out->type == LY_OUT_CALLBACK, NULL);

    prev_arg = out->method.clb.arg;

    if (arg) {
        out->method.clb.arg = arg;
    }

    return prev_arg;
}

API LY_ERR
ly_out_new_fd(int fd, struct ly_out **out)
{
    LY_CHECK_ARG_RET(NULL, out, fd != -1, LY_EINVAL);

    *out = calloc(1, sizeof **out);
    LY_CHECK_ERR_RET(!*out, LOGMEM(NULL), LY_EMEM);
    (*out)->type = LY_OUT_FD;
    (*out)->method.fd = fd;

    return LY_SUCCESS;
}

API int
ly_out_fd(struct ly_out *out, int fd)
{
    int prev_fd;

    LY_CHECK_ARG_RET(NULL, out, out->type <= LY_OUT_FDSTREAM, -1);

    if (out->type == LY_OUT_FDSTREAM) {
        prev_fd = out->method.fdstream.fd;
    } else { /* LY_OUT_FD */
        prev_fd = out->method.fd;
    }

    if (fd != -1) {
        /* replace output stream */
        if (out->type == LY_OUT_FDSTREAM) {
            int streamfd;
            FILE *stream;

            streamfd = dup(fd);
            if (streamfd < 0) {
                LOGERR(NULL, LY_ESYS, "Unable to duplicate provided file descriptor (%d) for printing the output (%s).", fd, strerror(errno));
                return -1;
            }
            stream = fdopen(streamfd, "a");
            if (!stream) {
                LOGERR(NULL, LY_ESYS, "Unable to open provided file descriptor (%d) for printing the output (%s).", fd, strerror(errno));
                close(streamfd);
                return -1;
            }
            /* close only the internally created stream, file descriptor is returned and supposed to be closed by the caller */
            fclose(out->method.fdstream.f);
            out->method.fdstream.f = stream;
            out->method.fdstream.fd = streamfd;
        } else { /* LY_OUT_FD */
            out->method.fd = fd;
        }
    }

    return prev_fd;
}

API LY_ERR
ly_out_new_file(FILE *f, struct ly_out **out)
{
    LY_CHECK_ARG_RET(NULL, out, f, LY_EINVAL);

    *out = calloc(1, sizeof **out);
    LY_CHECK_ERR_RET(!*out, LOGMEM(NULL), LY_EMEM);

    (*out)->type = LY_OUT_FILE;
    (*out)->method.f = f;

    return LY_SUCCESS;
}

API FILE *
ly_out_file(struct ly_out *out, FILE *f)
{
    FILE *prev_f;

    LY_CHECK_ARG_RET(NULL, out, out->type == LY_OUT_FILE, NULL);

    prev_f = out->method.f;

    if (f) {
        out->method.f = f;
    }

    return prev_f;
}

API LY_ERR
ly_out_new_memory(char **strp, size_t size, struct ly_out **out)
{
    LY_CHECK_ARG_RET(NULL, out, strp, LY_EINVAL);

    *out = calloc(1, sizeof **out);
    LY_CHECK_ERR_RET(!*out, LOGMEM(NULL), LY_EMEM);

    (*out)->type = LY_OUT_MEMORY;
    (*out)->method.mem.buf = strp;
    if (!size) {
        /* buffer is supposed to be allocated */
        *strp = NULL;
    } else if (*strp) {
        /* there is already buffer to use */
        (*out)->method.mem.size = size;
    }

    return LY_SUCCESS;
}

char *
ly_out_memory(struct ly_out *out, char **strp, size_t size)
{
    char *data;

    LY_CHECK_ARG_RET(NULL, out, out->type == LY_OUT_MEMORY, NULL);

    data = *out->method.mem.buf;

    if (strp) {
        out->method.mem.buf = strp;
        out->method.mem.len = out->method.mem.size = 0;
        out->printed = 0;
        if (!size) {
            /* buffer is supposed to be allocated */
            *strp = NULL;
        } else if (*strp) {
            /* there is already buffer to use */
            out->method.mem.size = size;
        }
    }

    return data;
}

API LY_ERR
ly_out_reset(struct ly_out *out)
{
    LY_CHECK_ARG_RET(NULL, out, LY_EINVAL);

    switch (out->type) {
    case LY_OUT_ERROR:
        LOGINT(NULL);
        return LY_EINT;
    case LY_OUT_FD:
        if ((lseek(out->method.fd, 0, SEEK_SET) == -1) && (errno != ESPIPE)) {
            LOGERR(NULL, LY_ESYS, "Seeking output file descriptor failed (%s).", strerror(errno));
            return LY_ESYS;
        }
        if ((errno != ESPIPE) && (ftruncate(out->method.fd, 0) == -1)) {
            LOGERR(NULL, LY_ESYS, "Truncating output file failed (%s).", strerror(errno));
            return LY_ESYS;
        }
        break;
    case LY_OUT_FDSTREAM:
    case LY_OUT_FILE:
    case LY_OUT_FILEPATH:
        if ((fseek(out->method.f, 0, SEEK_SET) == -1) && (errno != ESPIPE)) {
            LOGERR(NULL, LY_ESYS, "Seeking output file stream failed (%s).", strerror(errno));
            return LY_ESYS;
        }
        if ((errno != ESPIPE) && (ftruncate(fileno(out->method.f), 0) == -1)) {
            LOGERR(NULL, LY_ESYS, "Truncating output file failed (%s).", strerror(errno));
            return LY_ESYS;
        }
        break;
    case LY_OUT_MEMORY:
        if (out->method.mem.buf && *out->method.mem.buf) {
            memset(*out->method.mem.buf, 0, out->method.mem.len);
        }
        out->printed = 0;
        out->method.mem.len = 0;
        break;
    case LY_OUT_CALLBACK:
        /* nothing to do (not seekable) */
        break;
    }

    return LY_SUCCESS;
}

API LY_ERR
ly_out_new_filepath(const char *filepath, struct ly_out **out)
{
    LY_CHECK_ARG_RET(NULL, out, filepath, LY_EINVAL);

    *out = calloc(1, sizeof **out);
    LY_CHECK_ERR_RET(!*out, LOGMEM(NULL), LY_EMEM);

    (*out)->type = LY_OUT_FILEPATH;
    (*out)->method.fpath.f = fopen(filepath, "w");
    if (!(*out)->method.fpath.f) {
        LOGERR(NULL, LY_ESYS, "Failed to open file \"%s\" (%s).", filepath, strerror(errno));
        free(*out);
        *out = NULL;
        return LY_ESYS;
    }
    (*out)->method.fpath.filepath = strdup(filepath);
    return LY_SUCCESS;
}

API const char *
ly_out_filepath(struct ly_out *out, const char *filepath)
{
    FILE *f;

    LY_CHECK_ARG_RET(NULL, out, out->type == LY_OUT_FILEPATH, filepath ? NULL : ((void *)-1));

    if (!filepath) {
        return out->method.fpath.filepath;
    }

    /* replace filepath */
    f = out->method.fpath.f;
    out->method.fpath.f = fopen(filepath, "w");
    if (!out->method.fpath.f) {
        LOGERR(NULL, LY_ESYS, "Failed to open file \"%s\" (%s).", filepath, strerror(errno));
        out->method.fpath.f = f;
        return (void *)-1;
    }
    fclose(f);
    free(out->method.fpath.filepath);
    out->method.fpath.filepath = strdup(filepath);

    return NULL;
}

API void
ly_out_free(struct ly_out *out, void (*clb_arg_destructor)(void *arg), ly_bool destroy)
{
    if (!out) {
        return;
    }

    switch (out->type) {
    case LY_OUT_CALLBACK:
        if (clb_arg_destructor) {
            clb_arg_destructor(out->method.clb.arg);
        }
        break;
    case LY_OUT_FDSTREAM:
        fclose(out->method.fdstream.f);
        if (destroy) {
            close(out->method.fdstream.fd);
        }
        break;
    case LY_OUT_FD:
        if (destroy) {
            close(out->method.fd);
        }
        break;
    case LY_OUT_FILE:
        if (destroy) {
            fclose(out->method.f);
        }
        break;
    case LY_OUT_MEMORY:
        if (destroy) {
            free(*out->method.mem.buf);
        }
        break;
    case LY_OUT_FILEPATH:
        free(out->method.fpath.filepath);
        fclose(out->method.fpath.f);
        break;
    case LY_OUT_ERROR:
        LOGINT(NULL);
    }

    free(out->buffered);
    free(out);
}

static LY_ERR
ly_vprint_(struct ly_out *out, const char *format, va_list ap)
{
    LY_ERR ret;
    int written = 0;
    char *msg = NULL, *aux;

    switch (out->type) {
    case LY_OUT_FD:
        written = vdprintf(out->method.fd, format, ap);
        break;
    case LY_OUT_FDSTREAM:
    case LY_OUT_FILEPATH:
    case LY_OUT_FILE:
        written = vfprintf(out->method.f, format, ap);
        break;
    case LY_OUT_MEMORY:
        if ((written = vasprintf(&msg, format, ap)) < 0) {
            break;
        }
        if (out->method.mem.len + written + 1 > out->method.mem.size) {
            aux = ly_realloc(*out->method.mem.buf, out->method.mem.len + written + 1);
            if (!aux) {
                out->method.mem.buf = NULL;
                out->method.mem.len = 0;
                out->method.mem.size = 0;
                LOGMEM(NULL);
                return LY_EMEM;
            }
            *out->method.mem.buf = aux;
            out->method.mem.size = out->method.mem.len + written + 1;
        }
        memcpy(&(*out->method.mem.buf)[out->method.mem.len], msg, written);
        out->method.mem.len += written;
        (*out->method.mem.buf)[out->method.mem.len] = '\0';
        free(msg);
        break;
    case LY_OUT_CALLBACK:
        if ((written = vasprintf(&msg, format, ap)) < 0) {
            break;
        }
        written = out->method.clb.func(out->method.clb.arg, msg, written);
        free(msg);
        break;
    case LY_OUT_ERROR:
        LOGINT(NULL);
        return LY_EINT;
    }

    if (written < 0) {
        LOGERR(NULL, LY_ESYS, "%s: writing data failed (%s).", __func__, strerror(errno));
        written = 0;
        ret = LY_ESYS;
    } else {
        if (out->type == LY_OUT_FDSTREAM) {
            /* move the original file descriptor to the end of the output file */
            lseek(out->method.fdstream.fd, 0, SEEK_END);
        }
        ret = LY_SUCCESS;
    }

    out->printed += written;
    out->func_printed += written;
    return ret;
}

LY_ERR
ly_print_(struct ly_out *out, const char *format, ...)
{
    LY_ERR ret;
    va_list ap;

    va_start(ap, format);
    ret = ly_vprint_(out, format, ap);
    va_end(ap);

    return ret;
}

API LY_ERR
ly_print(struct ly_out *out, const char *format, ...)
{
    LY_ERR ret;
    va_list ap;

    out->func_printed = 0;

    va_start(ap, format);
    ret = ly_vprint_(out, format, ap);
    va_end(ap);

    return ret;
}

API void
ly_print_flush(struct ly_out *out)
{
    switch (out->type) {
    case LY_OUT_FDSTREAM:
        /* move the original file descriptor to the end of the output file */
        lseek(out->method.fdstream.fd, 0, SEEK_END);
        fflush(out->method.fdstream.f);
        break;
    case LY_OUT_FILEPATH:
    case LY_OUT_FILE:
        fflush(out->method.f);
        break;
    case LY_OUT_FD:
        fsync(out->method.fd);
        break;
    case LY_OUT_MEMORY:
    case LY_OUT_CALLBACK:
        /* nothing to do */
        break;
    case LY_OUT_ERROR:
        LOGINT(NULL);
    }

    free(out->buffered);
    out->buf_size = out->buf_len = 0;
}

LY_ERR
ly_write_(struct ly_out *out, const char *buf, size_t len)
{
    LY_ERR ret = LY_SUCCESS;
    size_t written = 0;

    if (out->hole_count) {
        /* we are buffering data after a hole */
        if (out->buf_len + len > out->buf_size) {
            out->buffered = ly_realloc(out->buffered, out->buf_len + len);
            if (!out->buffered) {
                out->buf_len = 0;
                out->buf_size = 0;
                LOGMEM(NULL);
                return LY_EMEM;
            }
            out->buf_size = out->buf_len + len;
        }

        memcpy(&out->buffered[out->buf_len], buf, len);
        out->buf_len += len;

        out->printed += len;
        out->func_printed += len;
        return LY_SUCCESS;
    }

repeat:
    switch (out->type) {
    case LY_OUT_MEMORY:
        if (out->method.mem.len + len + 1 > out->method.mem.size) {
            *out->method.mem.buf = ly_realloc(*out->method.mem.buf, out->method.mem.len + len + 1);
            if (!*out->method.mem.buf) {
                out->method.mem.len = 0;
                out->method.mem.size = 0;
                LOGMEM(NULL);
                return LY_EMEM;
            }
            out->method.mem.size = out->method.mem.len + len + 1;
        }
        memcpy(&(*out->method.mem.buf)[out->method.mem.len], buf, len);
        out->method.mem.len += len;
        (*out->method.mem.buf)[out->method.mem.len] = '\0';

        written = len;
        break;
    case LY_OUT_FD: {
        ssize_t r;
        r = write(out->method.fd, buf, len);
        if (r < 0) {
            ret = LY_ESYS;
        } else {
            written = (size_t)r;
        }
        break;
    }
    case LY_OUT_FDSTREAM:
    case LY_OUT_FILEPATH:
    case LY_OUT_FILE:
        written = fwrite(buf, sizeof *buf, len, out->method.f);
        if (written != len) {
            ret = LY_ESYS;
        }
        break;
    case LY_OUT_CALLBACK: {
        ssize_t r;
        r = out->method.clb.func(out->method.clb.arg, buf, len);
        if (r < 0) {
            ret = LY_ESYS;
        } else {
            written = (size_t)r;
        }
        break;
    }
    case LY_OUT_ERROR:
        LOGINT(NULL);
        return LY_EINT;
    }

    if (ret) {
        if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
            ret = LY_SUCCESS;
            goto repeat;
        }
        LOGERR(NULL, LY_ESYS, "%s: writing data failed (%s).", __func__, strerror(errno));
        written = 0;
    } else if ((size_t)written != len) {
        LOGERR(NULL, LY_ESYS, "%s: writing data failed (unable to write %u from %u data).", __func__,
                len - (size_t)written, len);
        ret = LY_ESYS;
    } else {
        if (out->type == LY_OUT_FDSTREAM) {
            /* move the original file descriptor to the end of the output file */
            lseek(out->method.fdstream.fd, 0, SEEK_END);
        }
        ret = LY_SUCCESS;
    }

    out->printed += written;
    out->func_printed += written;
    return ret;
}

API LY_ERR
ly_write(struct ly_out *out, const char *buf, size_t len)
{
    out->func_printed = 0;

    return ly_write_(out, buf, len);
}

API size_t
ly_out_printed(const struct ly_out *out)
{
    return out->func_printed;
}

LY_ERR
ly_write_skip(struct ly_out *out, size_t count, size_t *position)
{
    switch (out->type) {
    case LY_OUT_MEMORY:
        if (out->method.mem.len + count > out->method.mem.size) {
            *out->method.mem.buf = ly_realloc(*out->method.mem.buf, out->method.mem.len + count);
            if (!(*out->method.mem.buf)) {
                out->method.mem.len = 0;
                out->method.mem.size = 0;
                LOGMEM(NULL);
                return LY_EMEM;
            }
            out->method.mem.size = out->method.mem.len + count;
        }

        /* save the current position */
        *position = out->method.mem.len;

        /* skip the memory */
        out->method.mem.len += count;
        break;
    case LY_OUT_FD:
    case LY_OUT_FDSTREAM:
    case LY_OUT_FILEPATH:
    case LY_OUT_FILE:
    case LY_OUT_CALLBACK:
        /* buffer the hole */
        if (out->buf_len + count > out->buf_size) {
            out->buffered = ly_realloc(out->buffered, out->buf_len + count);
            if (!out->buffered) {
                out->buf_len = 0;
                out->buf_size = 0;
                LOGMEM(NULL);
                return LY_EMEM;
            }
            out->buf_size = out->buf_len + count;
        }

        /* save the current position */
        *position = out->buf_len;

        /* skip the memory */
        out->buf_len += count;

        /* increase hole counter */
        ++out->hole_count;
        break;
    case LY_OUT_ERROR:
        LOGINT(NULL);
        return LY_EINT;
    }

    /* update printed bytes counter despite we actually printed just a hole */
    out->printed += count;
    out->func_printed += count;
    return LY_SUCCESS;
}

LY_ERR
ly_write_skipped(struct ly_out *out, size_t position, const char *buf, size_t count)
{
    LY_ERR ret = LY_SUCCESS;

    switch (out->type) {
    case LY_OUT_MEMORY:
        /* write */
        memcpy(&(*out->method.mem.buf)[position], buf, count);
        break;
    case LY_OUT_FD:
    case LY_OUT_FDSTREAM:
    case LY_OUT_FILEPATH:
    case LY_OUT_FILE:
    case LY_OUT_CALLBACK:
        if (out->buf_len < position + count) {
            LOGMEM(NULL);
            return LY_EMEM;
        }

        /* write into the hole */
        memcpy(&out->buffered[position], buf, count);

        /* decrease hole counter */
        --out->hole_count;

        if (!out->hole_count) {
            /* all holes filled, we can write the buffer,
             * printed bytes counter is updated by ly_write_() */
            ret = ly_write_(out, out->buffered, out->buf_len);
            out->buf_len = 0;
        }
        break;
    case LY_OUT_ERROR:
        LOGINT(NULL);
        return LY_EINT;
    }

    if (out->type == LY_OUT_FILEPATH) {
        /* move the original file descriptor to the end of the output file */
        lseek(out->method.fdstream.fd, 0, SEEK_END);
    }
    return ret;
}
