
--file.lua
--last change:2022-10-10
file = {}

local FA_OPEN_EXISTING = 0x00
local FA_READ          = 0x01 --读
local FA_WRITE         = 0x02 --写
local FA_CREATE_NEW    = 0x04 --创建新文件
local FA_CREATE_ALWAYS = 0x08 --覆盖创建新文件
local FA_OPEN_ALWAYS   = 0x10 --打开

local WriteOnceSize = 2048

add_write  = FA_WRITE|FA_READ
over_write = FA_CREATE_ALWAYS|FA_WRITE

--get the type and length of the variable
--@data: 'string' or 'table'
--@return: len and type of data
function getParamLenAndType(data)

    local datalen = -1
    --获取数据类型
    local data_type = type(data)

    --计算数据长度
    if data_type == 'string'
    then
        datalen = string.len(data)
    elseif data_type == 'table'
    then
        datalen = #(data)
    end

    print('getParamLenAndType: '..data_type..' / '..datalen)

    return datalen,data_type
end

--read file data
--@file:file path
function file.read(file)
    print('file.read -> '..file)

    local count    = 0
    local read_cnt = 0
    local offset    = 0
    local all_byte = 0

    local read_byte_Tb = {}
    local read_char_Tb = {}

    local read_str     = ''
    local open_state = file_open(file, FA_READ)
    if open_state == true
    then
        --获取当前文件大小
        all_byte = file_size()
        if all_byte > 0
        then
            read_cnt =  math.modf(all_byte/WriteOnceSize)
            if all_byte % WriteOnceSize > 0
            then
                read_cnt = read_cnt + 1
            end
            print('need read allcnt -> '..read_cnt)

            for i = 1, read_cnt
            do
                --复位读字节数组
                read_byte_Tb = {}
                read_char_Tb = {}
                
                --计算读取的偏移位置
                offset = (i - 1) * WriteOnceSize
                local offst_result = file_seek(offset)
                --文件偏移失败
                if offst_result == false 
                then
                    break
                end
                print('cur offset  -> '.. offset)

                --计算本次读的个数
                count = WriteOnceSize
                if i == read_cnt
                then
                    if all_byte % WriteOnceSize > 0
                    then
                        count = all_byte % WriteOnceSize
                    end
                end
                print('cur read  -> '..i..'th / wrire count '..count)
                
                --读取字节转换为字符并拼接成字符串
                read_byte_Tb = file_read(count)
                if #(read_byte_Tb) > 0
                then
                    for j = 0, #(read_byte_Tb)
                    do
                        read_char_Tb[j + 1] = string.char(read_byte_Tb[j])
                    end
                    read_str = read_str..table.concat(read_char_Tb)
                    
                elseif read_byte_Tb ==nil
                then
                    change_child_screen(sc_prompt)
                    break;
                end
            end
        end
    else
        --关闭文件
        file_close()
    end
    return read_str
end

--Write data to the end of the file
--@file:file path
--@data:The type of '@data' only be [string] or [byte array]
--@open_mode:open file mode
function file.write(file, data, open_mode)

    print('file.write -> '..file..' / data -> '..type(data)..' / open_mode -> '..open_mode)

    local count     = 0
    local write_cnt = 0
    local seek_ops  = 0
    local all_byte  = 0
    local fileWriteState = 0

    --获取待写入数据的数据类型和长度
    local wrire_len, data_type = getParamLenAndType(data)

    local write_byte_Tb = {}
    local open_state = file_open(file, open_mode)

    if open_state == true
    then
        --获取当前文件大小,仅在追加文件末尾写入执行
        if open_mode == add_write
        then
            all_byte = file_size()
        end

        if wrire_len > 0
        then
            --计算'@data'要写多少次
            write_cnt =  math.modf(wrire_len / WriteOnceSize)
            if wrire_len % WriteOnceSize > 0
            then
                write_cnt = write_cnt + 1
            end
            print('need write allcnt -> '..write_cnt)

            for i = 1, write_cnt
            do
                --复位写字节数组
                write_byte_Tb = {}

                --计算写的位置
                seek_ops = (i - 1) * WriteOnceSize + all_byte
                file_seek(seek_ops)
                --文件偏移失败
                if offst_result == false 
                then
                    break
                end
                print('cur seek_ops  -> '..seek_ops)

                --计算本次写的个数
                count = WriteOnceSize
                if i == write_cnt
                then
                    if wrire_len % WriteOnceSize > 0
                    then
                        count = wrire_len % WriteOnceSize
                    end
                end
                print('cur write  -> '..write_cnt..'th / wrire count '..count)

                --填充写入flash的字节数组
                for j = 1, count 
                do
                    if data_type == 'string'
                    then
                        --字符串类型，将每个字符转换为字节数组
                        write_byte_Tb[j - 1] = tonumber(string.byte(data, ((i - 1) * WriteOnceSize + j), ((i - 1) * WriteOnceSize + j)))
                        
                    elseif data_type == 'table'
                    then
                        --数组类型，字节赋值
                        write_byte_Tb[j - 1] = data[((i - 1) * WriteOnceSize + j)]
                    end
                end

                fileWriteState = file_write(write_byte_Tb)
                if fileWriteState == false
                then
                    i = i - 1
                end    
            end
        end
    else
        print('The file don`t exist, please check! ! !')
    end

    --关闭文件
    file_close()
    return fileWriteState
end
