0
0
mirror of https://github.com/nodejs/node.git synced 2024-12-01 16:10:02 +01:00

Add accessor File#encoding

This commit is contained in:
Ryan 2009-05-07 16:15:07 +02:00
parent 103a8800c7
commit ba17940551
5 changed files with 119 additions and 68 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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 {

View File

@ -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);

View File

@ -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);