#include "File.h" #include "Task.h" #include #include #include #include #ifdef _WIN32 #include #else #include #include #endif void File::configure(v8::Isolate* isolate, v8::Handle global) { v8::Local fileTemplate = v8::ObjectTemplate::New(isolate); fileTemplate->Set(v8::String::NewFromUtf8(isolate, "readFile"), v8::FunctionTemplate::New(isolate, readFile)); fileTemplate->Set(v8::String::NewFromUtf8(isolate, "readDirectory"), v8::FunctionTemplate::New(isolate, readDirectory)); fileTemplate->Set(v8::String::NewFromUtf8(isolate, "makeDirectory"), v8::FunctionTemplate::New(isolate, makeDirectory)); fileTemplate->Set(v8::String::NewFromUtf8(isolate, "writeFile"), v8::FunctionTemplate::New(isolate, writeFile)); fileTemplate->Set(v8::String::NewFromUtf8(isolate, "renameFile"), v8::FunctionTemplate::New(isolate, renameFile)); fileTemplate->Set(v8::String::NewFromUtf8(isolate, "unlinkFile"), v8::FunctionTemplate::New(isolate, unlinkFile)); global->Set(v8::String::NewFromUtf8(isolate, "File"), fileTemplate); } void File::readFile(const v8::FunctionCallbackInfo& args) { v8::HandleScope scope(args.GetIsolate()); v8::Handle fileName = args[0]->ToString(); v8::String::Utf8Value utf8FileName(fileName); std::ifstream file(*utf8FileName, std::ios_base::in | std::ios_base::binary | std::ios_base::ate); std::streampos fileSize = file.tellg(); if (fileSize >= 0 && fileSize < 4 * 1024 * 1024) { file.seekg(0, std::ios_base::beg); v8::Handle buffer = v8::ArrayBuffer::New(args.GetIsolate(), fileSize); file.read(reinterpret_cast(buffer->GetContents().Data()), fileSize); v8::Handle array = v8::Uint8Array::New(buffer, 0, fileSize); args.GetReturnValue().Set(array); } } void File::writeFile(const v8::FunctionCallbackInfo& args) { v8::HandleScope scope(args.GetIsolate()); v8::Handle fileName = args[0]->ToString(); v8::Handle value = args[1]; v8::String::Utf8Value utf8FileName(fileName); std::ofstream file(*utf8FileName, std::ios_base::out | std::ios_base::binary); if (value->IsArrayBufferView()) { v8::Handle array = v8::Handle::Cast(value); if (!file.write(reinterpret_cast(array->Buffer()->GetContents().Data()), array->Buffer()->GetContents().ByteLength())) { args.GetReturnValue().Set(v8::Integer::New(args.GetIsolate(), -1)); } } else if (value->IsString()) { v8::Handle stringValue = v8::Handle::Cast(value); if (stringValue->ContainsOnlyOneByte()) { std::vector bytes(stringValue->Length()); stringValue->WriteOneByte(bytes.data(), 0, bytes.size(), v8::String::NO_NULL_TERMINATION); if (!file.write(reinterpret_cast(bytes.data()), bytes.size())) { args.GetReturnValue().Set(v8::Integer::New(args.GetIsolate(), -1)); } } else { v8::String::Utf8Value utf8Contents(stringValue); if (!file.write(*utf8Contents, utf8Contents.length())) { args.GetReturnValue().Set(v8::Integer::New(args.GetIsolate(), -1)); } } } } void File::renameFile(const v8::FunctionCallbackInfo& args) { Task* task = reinterpret_cast(args.GetIsolate()->GetData(0)); v8::HandleScope scope(args.GetIsolate()); v8::String::Utf8Value oldName(args[0]->ToString()); v8::String::Utf8Value newName(args[1]->ToString()); uv_fs_t req; int result = uv_fs_rename(task->getLoop(), &req, *oldName, *newName, 0); args.GetReturnValue().Set(v8::Integer::New(args.GetIsolate(), result)); } void File::unlinkFile(const v8::FunctionCallbackInfo& args) { Task* task = reinterpret_cast(args.GetIsolate()->GetData(0)); v8::HandleScope scope(args.GetIsolate()); v8::String::Utf8Value fileName(args[0]->ToString()); uv_fs_t req; int result = uv_fs_unlink(task->getLoop(), &req, *fileName, 0); args.GetReturnValue().Set(v8::Integer::New(args.GetIsolate(), result)); } void File::readDirectory(const v8::FunctionCallbackInfo& args) { v8::HandleScope scope(args.GetIsolate()); v8::Handle directory = args[0]->ToString(); v8::Handle array = v8::Array::New(args.GetIsolate(), 0); #ifdef _WIN32 WIN32_FIND_DATA find; std::string pattern = *v8::String::Utf8Value(directory); pattern += "\\*"; HANDLE handle = FindFirstFile(pattern.c_str(), &find); if (handle != INVALID_HANDLE_VALUE) { int index = 0; do { array->Set(v8::Integer::New(args.GetIsolate(), index++), v8::String::NewFromUtf8(args.GetIsolate(), find.cFileName)); } while (FindNextFile(handle, &find) != 0); FindClose(handle); } #else if (DIR* dir = opendir(*v8::String::Utf8Value(directory))) { int index = 0; while (struct dirent* entry = readdir(dir)) { array->Set(v8::Integer::New(args.GetIsolate(), index++), v8::String::NewFromUtf8(args.GetIsolate(), entry->d_name)); } closedir(dir); } #endif args.GetReturnValue().Set(array); } void File::makeDirectory(const v8::FunctionCallbackInfo& args) { Task* task = Task::get(args.GetIsolate()); v8::HandleScope scope(args.GetIsolate()); v8::Handle directory = args[0]->ToString(); uv_fs_t req; int result = uv_fs_mkdir(task->getLoop(), &req, *v8::String::Utf8Value(directory), 0755, 0); args.GetReturnValue().Set(result); }