This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

More bindings, beginning tcp server code in js

  • Loading branch information...
ry committed Dec 15, 2009
1 parent c819abc commit 469e2648e59c19154fd67ae1df17487f673fe9fc
Showing with 506 additions and 96 deletions.
  1. +12 −33 src/node_buffer.cc
  2. +45 −0 src/node_buffer.h
  3. +394 −63 src/node_net2.cc
  4. +55 −0 tcp.js
View
@@ -1,14 +1,15 @@
+#include <node_buffer.h>
+
#include <assert.h>
#include <stdlib.h> // malloc, free
#include <v8.h>
+
#include <node.h>
namespace node {
using namespace v8;
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-
#define SLICE_ARGS(start_arg, end_arg) \
if (!start_arg->IsInt32() || !end_arg->IsInt32()) { \
return ThrowException(Exception::TypeError( \
@@ -24,33 +25,11 @@ using namespace v8;
static Persistent<String> length_symbol;
static Persistent<FunctionTemplate> constructor_template;
-/* 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.
- *
- * // return an ascii encoded string - no memory iscopied
- * buffer.asciiSlide(0, 3)
- *
- * // returns another buffer - no memory is copied
- * buffer.slice(0, 3)
- *
- * Interally, each javascript buffer object is backed by a "struct buffer"
- * object. These "struct buffer" objects are either a root buffer (in the
- * case that buffer->root == NULL) or slice objects (in which case
- * buffer->root != NULL). A root buffer is only GCed once all its slices
- * are GCed.
- */
-
-struct buffer {
- Persistent<Object> handle; // both
- bool weak; // both
- struct buffer *root; // both (NULL for root)
- size_t offset; // both (0 for root)
- size_t length; // both
- unsigned int refs; // root only
- char bytes[1]; // root only
-};
+bool IsBuffer(v8::Handle<v8::Value> val) {
+ if (!val->IsObject()) return false;
+ Local<Object> obj = val->ToObject();
+ return constructor_template->HasInstance(obj);
+}
static inline struct buffer* buffer_root(buffer *buffer) {
@@ -79,7 +58,7 @@ static inline void buffer_unref(struct buffer *buffer) {
}
-static inline struct buffer* Unwrap(Handle<Value> val) {
+struct buffer* BufferUnwrap(v8::Handle<v8::Value> val) {
assert(val->IsObject());
HandleScope scope;
Local<Object> obj = val->ToObject();
@@ -123,7 +102,7 @@ static Handle<Value> Constructor(const Arguments &args) {
// slice slice
SLICE_ARGS(args[1], args[2])
- struct buffer *parent = Unwrap(args[0]);
+ struct buffer *parent = BufferUnwrap(args[0]);
size_t start_abs = buffer_abs_off(parent, start);
size_t end_abs = buffer_abs_off(parent, end);
@@ -230,7 +209,7 @@ static Handle<Value> AsciiSlice(const Arguments &args) {
SLICE_ARGS(args[0], args[1])
assert(args.This()->InternalFieldCount() == 1);
- struct buffer *parent = Unwrap(args.This());
+ struct buffer *parent = BufferUnwrap(args.This());
size_t start_abs = buffer_abs_off(parent, start);
size_t end_abs = buffer_abs_off(parent, end);
@@ -251,7 +230,7 @@ static Handle<Value> Utf8Slice(const Arguments &args) {
SLICE_ARGS(args[0], args[1])
- struct buffer *parent = Unwrap(args.This());
+ struct buffer *parent = BufferUnwrap(args.This());
size_t start_abs = buffer_abs_off(parent, start);
size_t end_abs = buffer_abs_off(parent, end);
assert(start_abs <= end_abs);
View
@@ -5,8 +5,53 @@
namespace node {
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+/* 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.
+ *
+ * // return an ascii encoded string - no memory iscopied
+ * buffer.asciiSlide(0, 3)
+ *
+ * // returns another buffer - no memory is copied
+ * buffer.slice(0, 3)
+ *
+ * Interally, each javascript buffer object is backed by a "struct buffer"
+ * object. These "struct buffer" objects are either a root buffer (in the
+ * case that buffer->root == NULL) or slice objects (in which case
+ * buffer->root != NULL). A root buffer is only GCed once all its slices
+ * are GCed.
+ */
+
+struct buffer {
+ v8::Persistent<v8::Object> handle; // both
+ bool weak; // both
+ struct buffer *root; // both (NULL for root)
+ size_t offset; // both (0 for root)
+ size_t length; // both
+ unsigned int refs; // root only
+ char bytes[1]; // root only
+};
+
void InitBuffer(v8::Handle<v8::Object> target);
+struct buffer* BufferUnwrap(v8::Handle<v8::Value> val);
+bool IsBuffer(v8::Handle<v8::Value> val);
+
+static inline char * buffer_p(struct buffer *buffer, size_t off) {
+ struct buffer *root = buffer->root ? buffer->root : buffer;
+ if (buffer->offset + off >= root->length) return NULL;
+ return reinterpret_cast<char*>(&(root->bytes) + buffer->offset + off);
+}
+
+static inline size_t buffer_remaining(struct buffer *buffer, size_t off) {
+ struct buffer *root = buffer->root ? buffer->root : buffer;
+ char *end = reinterpret_cast<char*>(&(root->bytes) + root->length);
+ return end - buffer_p(buffer, off);
+}
+
}
#endif // NODE_BUFFER
Oops, something went wrong.

0 comments on commit 469e264

Please sign in to comment.