Skip to content

Commit 469e264

Browse files
committed
More bindings, beginning tcp server code in js
1 parent c819abc commit 469e264

4 files changed

Lines changed: 506 additions & 96 deletions

File tree

src/node_buffer.cc

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1+
#include <node_buffer.h>
2+
13
#include <assert.h>
24
#include <stdlib.h> // malloc, free
35
#include <v8.h>
6+
47
#include <node.h>
58

69
namespace node {
710

811
using namespace v8;
912

10-
#define MIN(a,b) ((a) < (b) ? (a) : (b))
11-
1213
#define SLICE_ARGS(start_arg, end_arg) \
1314
if (!start_arg->IsInt32() || !end_arg->IsInt32()) { \
1415
return ThrowException(Exception::TypeError( \
@@ -24,33 +25,11 @@ using namespace v8;
2425
static Persistent<String> length_symbol;
2526
static Persistent<FunctionTemplate> constructor_template;
2627

27-
/* A buffer is a chunk of memory stored outside the V8 heap, mirrored by an
28-
* object in javascript. The object is not totally opaque, one can access
29-
* individual bytes with [] and slice it into substrings or sub-buffers
30-
* without copying memory.
31-
*
32-
* // return an ascii encoded string - no memory iscopied
33-
* buffer.asciiSlide(0, 3)
34-
*
35-
* // returns another buffer - no memory is copied
36-
* buffer.slice(0, 3)
37-
*
38-
* Interally, each javascript buffer object is backed by a "struct buffer"
39-
* object. These "struct buffer" objects are either a root buffer (in the
40-
* case that buffer->root == NULL) or slice objects (in which case
41-
* buffer->root != NULL). A root buffer is only GCed once all its slices
42-
* are GCed.
43-
*/
44-
45-
struct buffer {
46-
Persistent<Object> handle; // both
47-
bool weak; // both
48-
struct buffer *root; // both (NULL for root)
49-
size_t offset; // both (0 for root)
50-
size_t length; // both
51-
unsigned int refs; // root only
52-
char bytes[1]; // root only
53-
};
28+
bool IsBuffer(v8::Handle<v8::Value> val) {
29+
if (!val->IsObject()) return false;
30+
Local<Object> obj = val->ToObject();
31+
return constructor_template->HasInstance(obj);
32+
}
5433

5534

5635
static inline struct buffer* buffer_root(buffer *buffer) {
@@ -79,7 +58,7 @@ static inline void buffer_unref(struct buffer *buffer) {
7958
}
8059

8160

82-
static inline struct buffer* Unwrap(Handle<Value> val) {
61+
struct buffer* BufferUnwrap(v8::Handle<v8::Value> val) {
8362
assert(val->IsObject());
8463
HandleScope scope;
8564
Local<Object> obj = val->ToObject();
@@ -123,7 +102,7 @@ static Handle<Value> Constructor(const Arguments &args) {
123102
// slice slice
124103
SLICE_ARGS(args[1], args[2])
125104

126-
struct buffer *parent = Unwrap(args[0]);
105+
struct buffer *parent = BufferUnwrap(args[0]);
127106

128107
size_t start_abs = buffer_abs_off(parent, start);
129108
size_t end_abs = buffer_abs_off(parent, end);
@@ -230,7 +209,7 @@ static Handle<Value> AsciiSlice(const Arguments &args) {
230209
SLICE_ARGS(args[0], args[1])
231210

232211
assert(args.This()->InternalFieldCount() == 1);
233-
struct buffer *parent = Unwrap(args.This());
212+
struct buffer *parent = BufferUnwrap(args.This());
234213

235214
size_t start_abs = buffer_abs_off(parent, start);
236215
size_t end_abs = buffer_abs_off(parent, end);
@@ -251,7 +230,7 @@ static Handle<Value> Utf8Slice(const Arguments &args) {
251230

252231
SLICE_ARGS(args[0], args[1])
253232

254-
struct buffer *parent = Unwrap(args.This());
233+
struct buffer *parent = BufferUnwrap(args.This());
255234
size_t start_abs = buffer_abs_off(parent, start);
256235
size_t end_abs = buffer_abs_off(parent, end);
257236
assert(start_abs <= end_abs);

src/node_buffer.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,53 @@
55

66
namespace node {
77

8+
#define MIN(a,b) ((a) < (b) ? (a) : (b))
9+
10+
/* A buffer is a chunk of memory stored outside the V8 heap, mirrored by an
11+
* object in javascript. The object is not totally opaque, one can access
12+
* individual bytes with [] and slice it into substrings or sub-buffers
13+
* without copying memory.
14+
*
15+
* // return an ascii encoded string - no memory iscopied
16+
* buffer.asciiSlide(0, 3)
17+
*
18+
* // returns another buffer - no memory is copied
19+
* buffer.slice(0, 3)
20+
*
21+
* Interally, each javascript buffer object is backed by a "struct buffer"
22+
* object. These "struct buffer" objects are either a root buffer (in the
23+
* case that buffer->root == NULL) or slice objects (in which case
24+
* buffer->root != NULL). A root buffer is only GCed once all its slices
25+
* are GCed.
26+
*/
27+
28+
struct buffer {
29+
v8::Persistent<v8::Object> handle; // both
30+
bool weak; // both
31+
struct buffer *root; // both (NULL for root)
32+
size_t offset; // both (0 for root)
33+
size_t length; // both
34+
unsigned int refs; // root only
35+
char bytes[1]; // root only
36+
};
37+
838
void InitBuffer(v8::Handle<v8::Object> target);
939

40+
struct buffer* BufferUnwrap(v8::Handle<v8::Value> val);
41+
bool IsBuffer(v8::Handle<v8::Value> val);
42+
43+
static inline char * buffer_p(struct buffer *buffer, size_t off) {
44+
struct buffer *root = buffer->root ? buffer->root : buffer;
45+
if (buffer->offset + off >= root->length) return NULL;
46+
return reinterpret_cast<char*>(&(root->bytes) + buffer->offset + off);
47+
}
48+
49+
static inline size_t buffer_remaining(struct buffer *buffer, size_t off) {
50+
struct buffer *root = buffer->root ? buffer->root : buffer;
51+
char *end = reinterpret_cast<char*>(&(root->bytes) + root->length);
52+
return end - buffer_p(buffer, off);
53+
}
54+
1055
}
1156

1257
#endif // NODE_BUFFER

0 commit comments

Comments
 (0)