started on node.js
started on node.js

Reputation: 607

Rendering files from C++ Node.js addon

I would like to render files in node.js from C++ addon. I want to apply some file processing and render the output to the browser via node.js

Here is my C++ Code

    std::ifstream in(filename, std::ios::binary);

    in.seekg (0, in.end);
    int length = in.tellg();
    in.seekg (0, in.beg);

    char * buffer = new char [length];
    in.read (buffer,length);
    in.close();

    return buffer;

Following is the V8 code to add bindings for node.js, here buffer is the output from the above c++ code.

    Local<Function> cb = Local<Function>::Cast(args[1]);
    const unsigned argc = 1;
    Local<Value> argv[argc] = {Local<Value>::New(String::New(buffer))};
    cb->Call(Context::GetCurrent()->Global(), argc, argv);

This code works well for normal text files. I'm getting problem when reading text files which are having unicode characters. For eg,

Original text file

test start
Billél
last

When receiving in node, I will get

test start
Bill�l
last

Similarly when reading a jpg, png files the output file is different than the original file. Please help.

Upvotes: 2

Views: 1053

Answers (1)

flukey
flukey

Reputation: 187

I was having problems with this as well. I found an implementation in the V8 examples from Google. The example I found that properly handles UTF8 encoded files is found here:

https://code.google.com/p/v8/source/browse/trunk/samples/shell.cc#218

I adapted the source to this:

const char* ReadFile(const char* fileName, int* fileSize)
{
    // reference to c-string version of file
    char *fileBuffer = 0;

    // attempt to open the file
    FILE* fd = fopen(fileName, "rb");

    // clear file size
    *fileSize = 0;

    // file was valid
    if(fd != 0)
    {
       // get size of file
       fseek(fd, 0, SEEK_END);
       *fileSize = ftell(fd);
       rewind(fd);

       // allocate file buffer for file contents
       fileBuffer = (char*)malloc(*fileSize + 1);
       fileBuffer[*fileSize] = 0;

       // copy file contents
       for (int charCount = 0; charCount < *fileSize;)
       {
           int charRead = static_cast<int>(fread(&fileBuffer[charCount], 1, *fileSize - charCount, fd));
           charCount += charRead;
       }

       // close the file
       fclose(fd);
    }

    return fileBuffer;
}

Also, make sure when you create a V8 string that you create a String::Utf8Value.

String::Utf8Value v8Utf8String(...);

Then to use the String::Utf8Value as a char* use the following function:

https://code.google.com/p/v8/source/browse/trunk/samples/shell.cc#91

Upvotes: 1

Related Questions