// Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef NODE_BUFFER_H_ #define NODE_BUFFER_H_ #include "node.h" #include "node_object_wrap.h" #include "v8.h" #include namespace node { /* A buffer is a chunk of memory stored outside the V8 heap, mirrored by an * object in javascript. The object is not totally opaque, one can access * individual bytes with [] and slice it into substrings or sub-buffers * without copying memory. */ /* The C++ API for Buffer changed radically between v0.2 and v0.3, in fact it was the reason for bumping the version. In v0.2 JavaScript Buffers and C++ Buffers were in one-to-one correspondence via ObjectWrap. We found that it was faster to expose the C++ Buffers to JavaScript as a "SlowBuffer" which is used as a private backend to pure JavaScript "Buffer" objects - a 'Buffer' in v0.3 might look like this: { _parent: s, _offset: 520, length: 5 } Migrating code C++ Buffer code from v0.2 to v0.3 is difficult. Here are some tips: - buffer->data() calls should become Buffer::Data(buffer) calls. - buffer->length() calls should become Buffer::Length(buffer) calls. - There should not be any ObjectWrap::Unwrap() calls. You should not be storing pointers to Buffer objects at all - as they are now considered internal structures. Instead consider making a JavaScript reference to the buffer. See the source code node-png as an example of a module which successfully compiles on both v0.2 and v0.3 while making heavy use of the C++ Buffer API. */ class NODE_EXTERN Buffer: public ObjectWrap { public: // mirrors deps/v8/src/objects.h static const unsigned int kMaxLength = 0x3fffffff; static v8::Persistent constructor_template; static bool HasInstance(v8::Handle val); static inline char* Data(v8::Handle val) { assert(val->IsObject()); void* data = val.As()->GetIndexedPropertiesExternalArrayData(); return static_cast(data); } static inline char* Data(Buffer *b) { return Buffer::Data(b->handle_); } static inline size_t Length(v8::Handle val) { assert(val->IsObject()); int len = val.As() ->GetIndexedPropertiesExternalArrayDataLength(); return static_cast(len); } static inline size_t Length(Buffer *b) { return Buffer::Length(b->handle_); } ~Buffer(); typedef void (*free_callback)(char *data, void *hint); // C++ API for constructing fast buffer static v8::Handle New(v8::Handle string); static void Initialize(v8::Handle target); // public constructor static Buffer* New(size_t length); // public constructor - data is copied static Buffer* New(const char *data, size_t len); // public constructor static Buffer* New(char *data, size_t length, free_callback callback, void *hint); private: static v8::Handle New(const v8::Arguments &args); template static v8::Handle StringSlice(const v8::Arguments &args); static v8::Handle BinarySlice(const v8::Arguments &args); static v8::Handle AsciiSlice(const v8::Arguments &args); static v8::Handle Base64Slice(const v8::Arguments &args); static v8::Handle Utf8Slice(const v8::Arguments &args); static v8::Handle Ucs2Slice(const v8::Arguments &args); static v8::Handle HexSlice(const v8::Arguments &args); template static v8::Handle StringWrite(const v8::Arguments &args); static v8::Handle BinaryWrite(const v8::Arguments &args); static v8::Handle Base64Write(const v8::Arguments &args); static v8::Handle AsciiWrite(const v8::Arguments &args); static v8::Handle Utf8Write(const v8::Arguments &args); static v8::Handle Ucs2Write(const v8::Arguments &args); static v8::Handle HexWrite(const v8::Arguments &args); static v8::Handle ReadFloatLE(const v8::Arguments &args); static v8::Handle ReadFloatBE(const v8::Arguments &args); static v8::Handle ReadDoubleLE(const v8::Arguments &args); static v8::Handle ReadDoubleBE(const v8::Arguments &args); static v8::Handle WriteFloatLE(const v8::Arguments &args); static v8::Handle WriteFloatBE(const v8::Arguments &args); static v8::Handle WriteDoubleLE(const v8::Arguments &args); static v8::Handle WriteDoubleBE(const v8::Arguments &args); static v8::Handle ByteLength(const v8::Arguments &args); static v8::Handle MakeFastBuffer(const v8::Arguments &args); static v8::Handle Fill(const v8::Arguments &args); static v8::Handle Copy(const v8::Arguments &args); Buffer(v8::Handle wrapper, size_t length); void Replace(char *data, size_t length, free_callback callback, void *hint); size_t length_; char* data_; free_callback callback_; void* callback_hint_; }; } // namespace node buffer #endif // NODE_BUFFER_H_