Browse files

Add accessor File#encoding

  • Loading branch information...
1 parent 103a880 commit ba179405519e64a2dd60d6b7722de02e36ea2e8b @ry ry committed May 7, 2009
Showing with 119 additions and 68 deletions.
  1. +63 −62 src/file.cc
  2. +44 −1 src/file.h
  3. +9 −3 src/file.js
  4. +1 −1 src/main.js
  5. +2 −1 src/node.cc
View
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);
-}
View
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
View
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 {
View
2 src/main.js
@@ -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
3 src/node.cc
@@ -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);

0 comments on commit ba17940

Please sign in to comment.