aboutsummaryrefslogblamecommitdiff
path: root/io/param.c
blob: a57b183530f9811f66f9e1b0af033021a687dd4c (plain) (tree)
1
2
3

                  
                   



















                                                                  


                     














                                                                   
                                           


                




























                                                                    




                                                                           

                                                                      










                                                                         












                                                                            

                                                              
                         
                                                                     





                                                             

             
 
                                                             








                                                                     















                                                                            
                                        



                                                               
                                                                 


                                                            


















                                                                   










                                                             
                                                                          

                                 










                                                    





                                                            
                                       
                    

                                                            

 












                                                                   
                        
                                 
                               
                                                              
                         

                                                                  
                  








                                                     


                                                 
                        
                                            



                                                               

                                      



                                                     

                                                              


                                                        


























                                                                             
                                                          
                                       
















                                                                    
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "../common.h"
#include "param.h"

#define INVALID_FORMAT_ERROR(fn) \
    nerv_error(L, "Invalid param file: %s", fn)
#define CHECK_FORMAT(exp, ret, fname) \
    do { \
        if ((exp) != (ret)) INVALID_FORMAT_ERROR(fn); \
    } while (0)

const char *nerv_param_file_tname = "nerv.ParamFile";
const char *nerv_param_file_handle_tname = "nerv.ParamFileHandle";
const char *nerv_param_chunk_info_tname = "nerv.ParamChunkInfo";
const char *nerv_param_chunk_data_tname = "nerv.ParamChunkData";

#define PARAM_HEADER_SIZE 16

enum {
    NORMAL,
    INVALID_FORMAT,
    END_OF_FILE,
    SECTION_OVERFLOW,
    WRITE_ERROR
};

size_t read_param_header_plain(FILE *fp, int *status) {
    static char buff[PARAM_HEADER_SIZE];
    int i;
    size_t size = 0;
    *status = NORMAL;
    if (fread(buff, 1, PARAM_HEADER_SIZE, fp) != PARAM_HEADER_SIZE)
    {
        if (feof(fp)) *status = END_OF_FILE;
        else *status = INVALID_FORMAT;
    }
    for (i = 0; i < PARAM_HEADER_SIZE; i++)
        if (isdigit(buff[i]))
            size = size * 10 + buff[i] - '0';
    fprintf(stderr, "header: %lu\n", size);
    return size;
}

#define CHECK_WRITE(status) \
    do { \
        if (status == SECTION_OVERFLOW) \
            nerv_error(L, "section overflowed"); \
        else if (status == WRITE_ERROR) \
            nerv_error(L, "error while writing"); \
    } while (0)

void write_param_header_plain(FILE *fp, size_t size, int *status) {
    static char buff[PARAM_HEADER_SIZE];
    int i;
    *status = NORMAL;
    for (i = PARAM_HEADER_SIZE - 3; i > 0; i--, size /= 10)
        buff[i] = size % 10 + '0';
    if (size)
    {
        *status = SECTION_OVERFLOW;
        return;
    }
    buff[0] = '[';
    buff[PARAM_HEADER_SIZE - 2] = ']';
    buff[PARAM_HEADER_SIZE - 1] = '\n';
    if (fwrite(buff, 1, PARAM_HEADER_SIZE, fp) != PARAM_HEADER_SIZE)
    {
        *status = WRITE_ERROR;
        return;
    }
}

ParamChunkData *get_param_chunk_data(FILE *fp, ParamChunkInfo *info) {
    ParamChunkData *pcd = (ParamChunkData *)malloc(sizeof(ParamChunkData));
    pcd->data = (char *)malloc(info->length);
    pcd->fp = fmemopen(pcd->data, info->length, "r");
    assert(fseeko(fp, info->offset, SEEK_SET) == 0);
    if (fread(pcd->data, 1, info->length, fp) != (size_t)info->length)
        return NULL;
    return pcd;
}

const char *read_param_metadata(lua_State *L, FILE *fp, const char *fn) {
#define LINEBUFF_SIZE 1024
    static char buff[7 + LINEBUFF_SIZE] = "return ";
    CHECK_FORMAT(fgets(buff + 7, LINEBUFF_SIZE, fp), buff + 7, fn);
    fprintf(stderr, "metadata: %s\n", buff);
    return buff;
}

void write_param_metadata(FILE *fp, const char *metadata_str, int *status) {
    size_t size = strlen(metadata_str);
    *status = NORMAL;
    if (fwrite(metadata_str, 1, size, fp) != size ||
        fprintf(fp, "\n") < 0)
    {
        *status = WRITE_ERROR;
        return;
    }
    fprintf(stderr, "metadata: %s\n", metadata_str);
}


int nerv_param_file_open_write(lua_State *L, const char *fn) {
    FILE *fp = fopen(fn, "w");
    ParamFileHandle *lfp;
    if (