mirror of
https://github.com/nodejs/node.git
synced 2024-11-29 07:00:59 +01:00
Add accessor File#encoding
This commit is contained in:
parent
103a8800c7
commit
ba17940551
125
src/file.cc
125
src/file.cc
@ -10,49 +10,85 @@
|
||||
#include <assert.h>
|
||||
|
||||
using namespace v8;
|
||||
using namespace node;
|
||||
|
||||
#define FD_SYMBOL v8::String::NewSymbol("fd")
|
||||
#define ACTION_QUEUE_SYMBOL v8::String::NewSymbol("_actionQueue")
|
||||
#define ENCODING_SYMBOL v8::String::NewSymbol("encoding")
|
||||
|
||||
#define UTF8_SYMBOL v8::String::NewSymbol("utf8")
|
||||
#define RAW_SYMBOL v8::String::NewSymbol("raw")
|
||||
|
||||
static void
|
||||
InitActionQueue (Handle<Object> handle)
|
||||
{
|
||||
handle->Set(ACTION_QUEUE_SYMBOL, Array::New());
|
||||
}
|
||||
|
||||
// This is the file system object which contains methods
|
||||
// for accessing the file system (like rename, mkdir, etC).
|
||||
// In javascript it is called "File".
|
||||
static Persistent<Object> fs;
|
||||
|
||||
class FileSystem {
|
||||
public:
|
||||
static Handle<Value> Rename (const Arguments& args);
|
||||
static int AfterRename (eio_req *req);
|
||||
void
|
||||
File::Initialize (Handle<Object> target)
|
||||
{
|
||||
if (!fs.IsEmpty())
|
||||
return;
|
||||
|
||||
static Handle<Value> Stat (const Arguments& args);
|
||||
static int AfterStat (eio_req *req);
|
||||
HandleScope scope;
|
||||
|
||||
static Handle<Value> StrError (const Arguments& args);
|
||||
};
|
||||
Local<FunctionTemplate> file_template = FunctionTemplate::New(File::New);
|
||||
file_template->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
|
||||
class File : node::ObjectWrap {
|
||||
public:
|
||||
File (Handle<Object> handle);
|
||||
~File ();
|
||||
// file methods
|
||||
NODE_SET_METHOD(file_template->InstanceTemplate(), "_ffi_open", File::Open);
|
||||
NODE_SET_METHOD(file_template->InstanceTemplate(), "_ffi_close", File::Close);
|
||||
NODE_SET_METHOD(file_template->InstanceTemplate(), "_ffi_write", File::Write);
|
||||
NODE_SET_METHOD(file_template->InstanceTemplate(), "_ffi_read", File::Read);
|
||||
|
||||
static Handle<Value> New (const Arguments& args);
|
||||
file_template->InstanceTemplate()->SetAccessor(ENCODING_SYMBOL, File::GetEncoding, File::SetEncoding);
|
||||
|
||||
static Handle<Value> Open (const Arguments& args);
|
||||
static int AfterOpen (eio_req *req);
|
||||
fs = Persistent<Object>::New(file_template->GetFunction());
|
||||
InitActionQueue(fs);
|
||||
|
||||
static Handle<Value> Close (const Arguments& args);
|
||||
static int AfterClose (eio_req *req);
|
||||
target->Set(String::NewSymbol("File"), fs);
|
||||
|
||||
static Handle<Value> Write (const Arguments& args);
|
||||
static int AfterWrite (eio_req *req);
|
||||
// file system methods
|
||||
NODE_SET_METHOD(fs, "_ffi_rename", FileSystem::Rename);
|
||||
NODE_SET_METHOD(fs, "_ffi_stat", FileSystem::Stat);
|
||||
NODE_SET_METHOD(fs, "strerror", FileSystem::StrError);
|
||||
fs->Set(String::NewSymbol("STDIN_FILENO"), Integer::New(STDIN_FILENO));
|
||||
fs->Set(String::NewSymbol("STDOUT_FILENO"), Integer::New(STDOUT_FILENO));
|
||||
fs->Set(String::NewSymbol("STDERR_FILENO"), Integer::New(STDERR_FILENO));
|
||||
}
|
||||
|
||||
static Handle<Value> Read (const Arguments& args);
|
||||
static int AfterRead (eio_req *req);
|
||||
Handle<Value>
|
||||
File::GetEncoding (Local<String> property, const AccessorInfo& info)
|
||||
{
|
||||
File *file = NODE_UNWRAP(File, info.This());
|
||||
|
||||
private:
|
||||
bool HasUtf8Encoding (void);
|
||||
int GetFD (void);
|
||||
};
|
||||
if (file->encoding_ == UTF8)
|
||||
return UTF8_SYMBOL;
|
||||
else
|
||||
return RAW_SYMBOL;
|
||||
}
|
||||
|
||||
void
|
||||
File::SetEncoding (Local<String> property, Local<Value> value, const AccessorInfo& info)
|
||||
{
|
||||
File *file = NODE_UNWRAP(File, info.This());
|
||||
|
||||
if (value->IsString()) {
|
||||
Local<String> encoding_string = value->ToString();
|
||||
char buf[5]; // need enough room for "utf8" or "raw"
|
||||
encoding_string->WriteAscii(buf, 0, 4);
|
||||
buf[4] = '\0';
|
||||
file->encoding_ = strcasecmp(buf, "utf8") == 0 ? UTF8 : RAW;
|
||||
} else {
|
||||
file->encoding_ = RAW;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CallTopCallback (Handle<Object> handle, const int argc, Handle<Value> argv[])
|
||||
@ -87,12 +123,6 @@ CallTopCallback (Handle<Object> handle, const int argc, Handle<Value> argv[])
|
||||
poll_actions->Call(handle, 0, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
InitActionQueue (Handle<Object> handle)
|
||||
{
|
||||
handle->Set(ACTION_QUEUE_SYMBOL, Array::New());
|
||||
}
|
||||
|
||||
Handle<Value>
|
||||
FileSystem::Rename (const Arguments& args)
|
||||
{
|
||||
@ -206,6 +236,7 @@ File::File (Handle<Object> handle)
|
||||
: ObjectWrap(handle)
|
||||
{
|
||||
HandleScope scope;
|
||||
encoding_ = RAW;
|
||||
InitActionQueue(handle);
|
||||
}
|
||||
|
||||
@ -434,7 +465,7 @@ File::AfterRead (eio_req *req)
|
||||
argv[1] = Local<Value>::New(Null());
|
||||
} else {
|
||||
size_t length = req->result;
|
||||
if (file->HasUtf8Encoding()) {
|
||||
if (file->encoding_ == UTF8) {
|
||||
// utf8 encoding
|
||||
argv[1] = String::New(buf, req->result);
|
||||
} else {
|
||||
@ -460,33 +491,3 @@ File::New(const Arguments& args)
|
||||
return args.This();
|
||||
}
|
||||
|
||||
void
|
||||
node::Init_file (Handle<Object> target)
|
||||
{
|
||||
if (!fs.IsEmpty())
|
||||
return;
|
||||
|
||||
HandleScope scope;
|
||||
|
||||
Local<FunctionTemplate> file_template = FunctionTemplate::New(File::New);
|
||||
file_template->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
|
||||
fs = Persistent<Object>::New(file_template->GetFunction());
|
||||
InitActionQueue(fs);
|
||||
|
||||
target->Set(String::NewSymbol("File"), fs);
|
||||
|
||||
// file system methods
|
||||
NODE_SET_METHOD(fs, "_ffi_rename", FileSystem::Rename);
|
||||
NODE_SET_METHOD(fs, "_ffi_stat", FileSystem::Stat);
|
||||
NODE_SET_METHOD(fs, "strerror", FileSystem::StrError);
|
||||
fs->Set(String::NewSymbol("STDIN_FILENO"), Integer::New(STDIN_FILENO));
|
||||
fs->Set(String::NewSymbol("STDOUT_FILENO"), Integer::New(STDOUT_FILENO));
|
||||
fs->Set(String::NewSymbol("STDERR_FILENO"), Integer::New(STDERR_FILENO));
|
||||
|
||||
// file methods
|
||||
NODE_SET_METHOD(file_template->InstanceTemplate(), "_ffi_open", File::Open);
|
||||
NODE_SET_METHOD(file_template->InstanceTemplate(), "_ffi_close", File::Close);
|
||||
NODE_SET_METHOD(file_template->InstanceTemplate(), "_ffi_write", File::Write);
|
||||
NODE_SET_METHOD(file_template->InstanceTemplate(), "_ffi_read", File::Read);
|
||||
}
|
||||
|
45
src/file.h
45
src/file.h
@ -5,7 +5,50 @@
|
||||
|
||||
namespace node {
|
||||
|
||||
void Init_file (v8::Handle<v8::Object> target);
|
||||
class FileSystem {
|
||||
public:
|
||||
static v8::Handle<v8::Value> Rename (const v8::Arguments& args);
|
||||
static int AfterRename (eio_req *req);
|
||||
|
||||
static v8::Handle<v8::Value> Stat (const v8::Arguments& args);
|
||||
static int AfterStat (eio_req *req);
|
||||
|
||||
static v8::Handle<v8::Value> StrError (const v8::Arguments& args);
|
||||
};
|
||||
|
||||
class File : ObjectWrap {
|
||||
public:
|
||||
static void Initialize (v8::Handle<v8::Object> target);
|
||||
|
||||
protected:
|
||||
File (v8::Handle<v8::Object> handle);
|
||||
~File ();
|
||||
|
||||
static v8::Handle<v8::Value> New (const v8::Arguments& args);
|
||||
|
||||
static v8::Handle<v8::Value> Open (const v8::Arguments& args);
|
||||
static int AfterOpen (eio_req *req);
|
||||
|
||||
static v8::Handle<v8::Value> Close (const v8::Arguments& args);
|
||||
static int AfterClose (eio_req *req);
|
||||
|
||||
static v8::Handle<v8::Value> Write (const v8::Arguments& args);
|
||||
static int AfterWrite (eio_req *req);
|
||||
|
||||
static v8::Handle<v8::Value> Read (const v8::Arguments& args);
|
||||
static int AfterRead (eio_req *req);
|
||||
|
||||
static v8::Handle<v8::Value> GetEncoding (v8::Local<v8::String> property,
|
||||
const v8::AccessorInfo& info);
|
||||
static void SetEncoding (v8::Local<v8::String> property,
|
||||
v8::Local<v8::Value> value,
|
||||
const v8::AccessorInfo& info);
|
||||
|
||||
bool HasUtf8Encoding (void);
|
||||
int GetFD (void);
|
||||
|
||||
enum encoding encoding_;
|
||||
};
|
||||
|
||||
} // namespace node
|
||||
#endif // node_file_h
|
||||
|
12
src/file.js
12
src/file.js
@ -12,16 +12,22 @@ File.exists = function (path, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
File.cat = function (path, callback) {
|
||||
File.cat = function (path, encoding, callback) {
|
||||
var content = "";
|
||||
var file = new File;
|
||||
var file = new File();
|
||||
file.encoding = "utf8";
|
||||
var pos = 0;
|
||||
var chunkSize = 10*1024;
|
||||
|
||||
function readChunk () {
|
||||
file.read(chunkSize, pos, function (status, chunk) {
|
||||
if (chunk) {
|
||||
content += chunk.encodeUtf8();
|
||||
|
||||
if (chunk.constructor == String)
|
||||
content += chunk;
|
||||
else
|
||||
content = content.concat(chunk);
|
||||
|
||||
pos += chunk.length;
|
||||
readChunk();
|
||||
} else {
|
||||
|
@ -134,7 +134,7 @@ clearInterval = clearTimeout;
|
||||
}
|
||||
|
||||
function loadScript (filename, target, callback) {
|
||||
File.cat(filename, function (status, content) {
|
||||
File.cat(filename, "utf8", function (status, content) {
|
||||
if (status != 0) {
|
||||
stderr.puts("Error reading " + filename + ": " + File.strerror(status));
|
||||
exit(1);
|
||||
|
@ -265,7 +265,8 @@ main (int argc, char *argv[])
|
||||
|
||||
// BUILT-IN MODULES
|
||||
node::Init_timer(g);
|
||||
node::Init_file(g);
|
||||
|
||||
File::Initialize(g);
|
||||
|
||||
Acceptor::Initialize(g);
|
||||
Connection::Initialize(g);
|
||||
|
Loading…
Reference in New Issue
Block a user