distributedlife

passionate about everything

Vanilla C with Sprinkles – file reading reading a UTF-8 file Published by Ryan Boucher @ 11:55 pm

Time to write some posts on doing regular Service Testing things in Vanilla C and the added benefit of HP Service Test C; which adds a few handy functions. If you’re just using Vanilla C you can replace lr_set and lr_get with functions that set and get char* strings respectively.

First up are some file related functions and today is reading a UTF-8 file. We care little for the file size so you better have enough memory. If you are trying to load in a large file then you need to consider techniques like paging the data in.


void ReadFileUTF8 (const char* const Filename, const char* TargetParameter)
{

The TargetParameter is the string name of a HP Parameter where we will store the contents of the file.


    const unsigned int SEEK_END = 2 ;

    long FileHandle = 0 ;
    long FileSizeInBytes = 0 ;

    char * DataBuffer = 0;

    int shifted = 0 ;

    size_t result = 0;
    long index = 0 ;

    //Set our TargetParameter to Failed incase we don't make it
    lr_set("FAILED", TargetParameter);

    FileHandle = fopen (Filename, "rb" );
    if (!FileHandle)
    {
        lr_error_message ("Failed to open the file \"%s\"", Filename) ;
        return ;
    }

    //Get the file size. We use this to allocate our data buffer.
    fseek (FileHandle , 0 , SEEK_END);
    FileSizeInBytes = ftell (FileHandle);
    rewind (FileHandle);

    // allocate memory to contain the whole file
    DataBuffer = (char*) malloc ((sizeof(char) * FileSizeInBytes) + 1) ;
    if (!DataBuffer)
    {
        lr_error_message ("Could not allocate memory for buffer") ;
        return ;
    }

    // copy the file into the DataBuffer:
    result = fread (DataBuffer, sizeof(char), FileSizeInBytes, FileHandle) ;
    if (result != FileSizeInBytes)
    {
        lr_error_message ("Could not copy file data into buffer") ;
        if (DataBuffer)
        {
            free (DataBuffer) ;
        }
    }

    //add null-terminating char
    DataBuffer[FileSizeInBytes] = '\0' ;

    //Skip BOM (if there is one)
    if (DataBuffer[0] == '\xff' && DataBuffer[1] == '\xfe')
    {
        DataBuffer++ ;
        DataBuffer++ ;
        shifted = 1 ;
    }

If you don’t have HP Service Test then you can change this next line and at the end of the function return your DataBuffer pointer to the caller without freeing it. I prefer to use HP Service Test parameters where possible because they allow you to do away with memory management for strings.


    lr_set (DataBuffer, TargetParameter);

    //Move back to start of string before freeing memory
    if (shifted == 1)
    {
        DataBuffer-- ;
        DataBuffer-- ;
    }

    fclose (FileHandle) ;
    free (DataBuffer) ;
}
My Mug Ryan Boucher is a Software Inquisitor and is passionate about it. You can find a whole raft of articles and anecdotes about software testing and other topics he gets excited about.
Tags , , , , ,