/*
 *
 *  Output procedures.
 *
 */

#include "resconv.h"
#include "extdef.h"

#include <stdio.h>


HANDLE   dst_fnum;                       /* output file handle */
uchar   dst_buffer [max_buffer_bytes];  /* output data buffer */
ushort  dst_bytes;                      /* # bytes in data buffer */


/**************************************************************************
 *                                                                        *
 *  WRITE_DATA                                                            *
 *                                                                        *
 *  This procedure is called to write some data to a file.                *
 *                                                                        *
 **************************************************************************/

static flag write_data (HFILE fnum, void ptr buf, ushort count)
{
ushort error;
DWORD written;

/*  Write the data, and die if we get an error. */

error = WriteFile (fnum, buf, count, &written, NULL);
if ((error == 0) || count != written) {
    printf ("I/O error %ld while writing to data file.\n", GetLastError());
    close_destination_file ();
    terminate_input ();
    exit(1);
    }

/*  Success is ours. */

return TRUE;
}


/**************************************************************************
 *                                                                        *
 *  OUTPUT_CONTROL_LINE                                                   *
 *                                                                        *
 *  This procedure is called to output a the current line as a control    *
 *  line.                                                                 *
 *                                                                        *
 **************************************************************************/

void output_control_line (uchar ptr string)
{
char    ch;

/*
 *  If there isn't enough room in the output buffer for 256 bytes, write
 *  the buffer data out to file.
 */

output_newline ();
if (dst_bytes + 256 >= max_buffer_bytes) {
    write_data (dst_fnum, dst_buffer, dst_bytes);
    dst_bytes = 0;
    }

/*
 *  Get characters transferring them to the destination buffer until
 *  we see the carriage return. Get the line feed and finish the line.
 */

dst_buffer [dst_bytes++] = char_pound_sign;
_fstrncpy (&dst_buffer [dst_bytes], string, string_length (string));
dst_bytes += string_length (string);

while ((ch = get_char ()) != 0x0D)
    dst_buffer [dst_bytes++] = ch;
get_char ();
}


/**************************************************************************
 *                                                                        *
 *  OUTPUT_NEWLINE                                                        *
 *                                                                        *
 *  This procedure is called to output a CR/LF.                           *
 *                                                                        *
 **************************************************************************/

void output_newline (void)
{

if (dst_bytes + 2 >= max_buffer_bytes) {
    write_data (dst_fnum, dst_buffer, dst_bytes);
    dst_bytes = 0;
    }

if (get_comment_string() != NULL) {
    output_token(get_comment_string());
    clear_comment_string();
}

dst_buffer [dst_bytes++] = 0x0D;
dst_buffer [dst_bytes++] = 0x0A;
}


/**************************************************************************
 *                                                                        *
 *  OUTPUT_TAB                                                            *
 *                                                                        *
 *  This procedure is called to output the specified number of tab        *
 *  characters.                                                           *
 *                                                                        *
 **************************************************************************/

void output_tab (ushort count)
{
int i;

if (dst_bytes + (count * 4) >= max_buffer_bytes) {
    write_data (dst_fnum, dst_buffer, dst_bytes);
    dst_bytes = 0;
    }

for (i = 0; i < count * 4; i++)
    dst_buffer [dst_bytes++] = ' ';
}


/**************************************************************************
 *                                                                        *
 *  OUTPUT_STRING                                                         *
 *                                                                        *
 *  This procedure is called to output a quoted string.                   *
 *                                                                        *
 **************************************************************************/

void output_string (uchar ptr string)
{
ushort  length;

/*  See if there's enough room left in the output buffer for this string. */

length = string_length (string);
if (dst_bytes + length + 3 >= max_buffer_bytes) {
    write_data (dst_fnum, dst_buffer, dst_bytes);
    dst_bytes = 0;
    }

/*
 *  Put the string surrounded by double-quotes in the output buffer and
 *  insert a space at the end.
 */

dst_buffer [dst_bytes++] = '"';
_fstrncpy (&dst_buffer [dst_bytes], string, length);
dst_bytes += length;
dst_buffer [dst_bytes++] = '"';
dst_buffer [dst_bytes++] = ' ';
}


/**************************************************************************
 *                                                                        *
 *  OUTPUT_TOKEN                                                          *
 *                                                                        *
 *  This procedure is called to output a token string.                    *
 *                                                                        *
 **************************************************************************/

void output_token (uchar ptr string)
{
ushort  length;

/*  See if there's enough room left in the output buffer for this string. */

length = string_length (string);
if (dst_bytes + length + 1 >= max_buffer_bytes) {
    write_data (dst_fnum, dst_buffer, dst_bytes);
    dst_bytes = 0;
    }

/*  Put the string in the output buffer and insert a space at the end. */

_fstrncpy (&dst_buffer [dst_bytes], string, length);
dst_bytes += length;
dst_buffer [dst_bytes++] = ' ';
}


/**************************************************************************
 *                                                                        *
 *  OUTPUT_VALUE                                                          *
 *                                                                        *
 *  This procedure is called to output a value as a string.               *
 *                                                                        *
 **************************************************************************/

void output_value (long value)
{
uchar   buffer [40];

/*
 *  Convert the value to a string and insert the string in the output
 *  buffer.
 */

ltoa (value, buffer, 10);
output_token (buffer);
}


/**************************************************************************
 *                                                                        *
 *  OPEN_DESTINATION_FILE                                                 *
 *                                                                        *
 *  This procedure is called to open the destination file.                *
 *                                                                        *
 **************************************************************************/

flag open_destination_file (uchar ptr dst_fname)
{

/*  Open the destination file. */

printf ("Opening  %s\n", dst_fname);
dst_fnum = CreateFile(dst_fname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL, NULL);
if (dst_fnum == NULL)
{
    printf ("Unable to create: %s, error %ld\n", dst_fname, GetLastError());
    close_destination_file ();
    terminate_input ();
    exit(1);
}
/*  Success. */

return TRUE;
}


/**************************************************************************
 *                                                                        *
 *  CLOSE_DESTINATION_FILE                                                *
 *                                                                        *
 *  This procedure writes out any remaining bytes in the destination      *
 *  file and closes it.                                                   *
 *                                                                        *
 **************************************************************************/

void close_destination_file (void)
{
DWORD written;
int error;

error = WriteFile (dst_fnum, dst_buffer, dst_bytes, &written, NULL);
if ((error == 0) || dst_bytes != written) {
    printf ("I/O error %ld while writing to data file.\n", GetLastError());
    terminate_input ();
    exit(1);
    }
CloseHandle(dst_fnum);
}
