// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
**********************************************************************
* Copyright (c) 2004,2011 International Business Machines
* Corporation and others.  All Rights Reserved.
**********************************************************************
* Author: Alan Liu
* Created: March 19 2004
* Since: ICU 3.0
**********************************************************************
*/
#include "textfile.h"
#include "cmemory.h"
#include "cstring.h"
#include "intltest.h"
#include "util.h"

// If the symbol CCP is defined, then the 'name' and 'encoding'
// constructor parameters are copied.  Otherwise they are aliased.
// #define CCP

TextFile::TextFile(const char* _name, const char* _encoding, UErrorCode& ec) :
    file(0),
    name(0), encoding(0),
    buffer(0),
    capacity(0),
    lineNo(0)
{
    if (U_FAILURE(ec) || _name == 0 || _encoding == 0) {
        if (U_SUCCESS(ec)) {
            ec = U_ILLEGAL_ARGUMENT_ERROR; 
        }
        return;
    }

#ifdef CCP
    name = uprv_malloc(uprv_strlen(_name) + 1);
    encoding = uprv_malloc(uprv_strlen(_encoding) + 1);
    if (name == 0 || encoding == 0) {
        ec = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    uprv_strcpy(name, _name);
    uprv_strcpy(encoding, _encoding);
#else
    name = (char*) _name;
    encoding = (char*) _encoding;
#endif

    const char* testDir = IntlTest::getSourceTestData(ec);
    if (U_FAILURE(ec)) {
        return;
    }
    if (!ensureCapacity((int32_t)(uprv_strlen(testDir) + uprv_strlen(name) + 1))) {
        ec = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    uprv_strcpy(buffer, testDir);
    uprv_strcat(buffer, name);

    file = T_FileStream_open(buffer, "rb");
    if (file == 0) {
        ec = U_ILLEGAL_ARGUMENT_ERROR; 
        return;        
    }
}

TextFile::~TextFile() {
    if (file != 0) T_FileStream_close(file);
    if (buffer != 0) uprv_free(buffer);
#ifdef CCP
    uprv_free(name);
    uprv_free(encoding);
#endif
}

UBool TextFile::readLine(UnicodeString& line, UErrorCode& ec) {
    if (T_FileStream_eof(file)) {
        return FALSE;
    }
    // Note: 'buffer' may change after ensureCapacity() is called,
    // so don't use 
    //   p=buffer; *p++=c;
    // but rather
    //   i=; buffer[i++]=c;
    int32_t n = 0;
    for (;;) {
        int c = T_FileStream_getc(file); // sic: int, not int32_t
        if (c < 0 || c == 0xD || c == 0xA) {
            // consume 0xA following 0xD
            if (c == 0xD) {
                c = T_FileStream_getc(file);
                if (c != 0xA && c >= 0) {
                    T_FileStream_ungetc(c, file);
                }
            }
            break;
        }
        if (!setBuffer(n++, c, ec)) return FALSE;
    }
    if (!setBuffer(n++, 0, ec)) return FALSE;
    UnicodeString str(buffer, encoding);
    // Remove BOM in first line, if present
    if (lineNo == 0 && str[0] == 0xFEFF) {
        str.remove(0, 1);
    }
    ++lineNo;
    line = str.unescape();
    return TRUE;
}

UBool TextFile::readLineSkippingComments(UnicodeString& line, UErrorCode& ec,
                                         UBool trim) {
    for (;;) {
        if (!readLine(line, ec)) return FALSE;
        // Skip over white space
        int32_t pos = 0;
        ICU_Utility::skipWhitespace(line, pos, TRUE);
        // Ignore blank lines and comment lines
        if (pos == line.length() || line.charAt(pos) == 0x23/*'#'*/) {
            continue;
        }
        // Process line
        if (trim) line.remove(0, pos);
        return TRUE;
    }
}

/**
 * Set buffer[index] to c, growing buffer if necessary. Return TRUE if
 * successful.
 */
UBool TextFile::setBuffer(int32_t index, char c, UErrorCode& ec) {
    if (capacity <= index) {
        if (!ensureCapacity(index+1)) {
            ec = U_MEMORY_ALLOCATION_ERROR;
            return FALSE;
        }
    }
    buffer[index] = c;
    return TRUE;
}

/**
 * Make sure that 'buffer' has at least 'mincapacity' bytes.
 * Return TRUE upon success. Upon return, 'buffer' may change
 * value. In any case, previous contents are preserved.
 */
 #define LOWEST_MIN_CAPACITY 64
UBool TextFile::ensureCapacity(int32_t mincapacity) {
    if (capacity >= mincapacity) {
        return TRUE;
    }

    // Grow by factor of 2 to prevent frequent allocation
    // Note: 'capacity' may be 0
    int32_t i = (capacity < LOWEST_MIN_CAPACITY)? LOWEST_MIN_CAPACITY: capacity;
    while (i < mincapacity) {
        i <<= 1;
        if (i < 0) {
            i = 0x7FFFFFFF;
            break;
        }
    }
    mincapacity = i;

    // Simple realloc() no good; contents not preserved
    // Note: 'buffer' may be 0
    char* newbuffer = (char*) uprv_malloc(mincapacity);
    if (newbuffer == 0) {
        return FALSE;
    }
    if (buffer != 0) {
        uprv_strncpy(newbuffer, buffer, capacity);
        uprv_free(buffer);
    }
    buffer = newbuffer;
    capacity = mincapacity;
    return TRUE;
}

