diff options
author | James M Snell <jasnell@gmail.com> | 2016-03-08 20:58:45 -0800 |
---|---|---|
committer | James M Snell <jasnell@gmail.com> | 2016-03-25 14:21:27 -0700 |
commit | 060e5f0c0064e578c2150f13e3f91ac15fdeed92 (patch) | |
tree | 50783508a123991a024a9a85a2994d5ef2a83c5d /src/util.cc | |
parent | 4d4f3535a9fd7486d7a94d825ac8e92a65bf9121 (diff) | |
download | node-new-060e5f0c0064e578c2150f13e3f91ac15fdeed92.tar.gz |
fs: Buffer and encoding enhancements to fs API
This makes several changes:
1. Allow path/filename to be passed in as a Buffer on fs methods
2. Add `options.encoding` to fs.readdir, fs.readdirSync, fs.readlink,
fs.readlinkSync and fs.watch.
3. Documentation updates
For 1... it's now possible to do:
```js
fs.open(Buffer('/fs/foo/bar'), 'w+', (err, fd) => { });
```
For 2...
```js
fs.readdir('/fs/foo/bar', {encoding:'hex'}, (err,list) => { });
fs.readdir('/fs/foo/bar', {encoding:'buffer'}, (err, list) => { });
```
encoding can also be passed as a string
```js
fs.readdir('/fs/foo/bar', 'hex', (err,list) => { });
```
The default encoding is set to UTF8 so this addresses the
discrepency that existed previously between fs.readdir and
fs.watch handling filenames differently.
Fixes: https://github.com/nodejs/node/issues/2088
Refs: https://github.com/nodejs/node/issues/3519
PR-URL: https://github.com/nodejs/node/pull/5616
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Diffstat (limited to 'src/util.cc')
-rw-r--r-- | src/util.cc | 69 |
1 files changed, 51 insertions, 18 deletions
diff --git a/src/util.cc b/src/util.cc index 095e5582db..3b0278ceda 100644 --- a/src/util.cc +++ b/src/util.cc @@ -1,37 +1,48 @@ #include "util.h" #include "string_bytes.h" +#include "node_buffer.h" +#include <stdio.h> namespace node { -Utf8Value::Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> value) - : length_(0), str_(str_st_) { - if (value.IsEmpty()) - return; +using v8::Isolate; +using v8::String; +using v8::Local; +using v8::Value; - v8::Local<v8::String> string = value->ToString(isolate); +static int MakeUtf8String(Isolate* isolate, + Local<Value> value, + char** dst, + const size_t size) { + Local<String> string = value->ToString(isolate); if (string.IsEmpty()) - return; - - // Allocate enough space to include the null terminator + return 0; size_t len = StringBytes::StorageSize(isolate, string, UTF8) + 1; - if (len > sizeof(str_st_)) { - str_ = static_cast<char*>(malloc(len)); - CHECK_NE(str_, nullptr); + if (len > size) { + *dst = static_cast<char*>(malloc(len)); + CHECK_NE(*dst, nullptr); } - const int flags = - v8::String::NO_NULL_TERMINATION | v8::String::REPLACE_INVALID_UTF8; - length_ = string->WriteUtf8(str_, len, 0, flags); - str_[length_] = '\0'; + String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8; + const int length = string->WriteUtf8(*dst, len, 0, flags); + (*dst)[length] = '\0'; + return length; +} + +Utf8Value::Utf8Value(Isolate* isolate, Local<Value> value) + : length_(0), str_(str_st_) { + if (value.IsEmpty()) + return; + length_ = MakeUtf8String(isolate, value, &str_, sizeof(str_st_)); } -TwoByteValue::TwoByteValue(v8::Isolate* isolate, v8::Local<v8::Value> value) +TwoByteValue::TwoByteValue(Isolate* isolate, Local<Value> value) : length_(0), str_(str_st_) { if (value.IsEmpty()) return; - v8::Local<v8::String> string = value->ToString(isolate); + Local<String> string = value->ToString(isolate); if (string.IsEmpty()) return; @@ -43,9 +54,31 @@ TwoByteValue::TwoByteValue(v8::Isolate* isolate, v8::Local<v8::Value> value) } const int flags = - v8::String::NO_NULL_TERMINATION | v8::String::REPLACE_INVALID_UTF8; + String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8; length_ = string->Write(str_, 0, len, flags); str_[length_] = '\0'; } +BufferValue::BufferValue(Isolate* isolate, Local<Value> value) + : str_(str_st_), fail_(true) { + // Slightly different take on Utf8Value. If value is a String, + // it will return a Utf8 encoded string. If value is a Buffer, + // it will copy the data out of the Buffer as is. + if (value.IsEmpty()) + return; + if (value->IsString()) { + MakeUtf8String(isolate, value, &str_, sizeof(str_st_)); + fail_ = false; + } else if (Buffer::HasInstance(value)) { + size_t len = Buffer::Length(value) + 1; + if (len > sizeof(str_st_)) { + str_ = static_cast<char*>(malloc(len)); + CHECK_NE(str_, nullptr); + } + memcpy(str_, Buffer::Data(value), len); + str_[len - 1] = '\0'; + fail_ = false; + } +} + } // namespace node |