/** * Contents of this file are snippets from node.cc * see http://www.nodejs.org/ * * Node's license follows: * * Copyright 2009, 2010 Ryan Lienhart Dahl. All rights reserved. * 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: */ #include <v8.h> #include <string.h> #include "logging.h" #include "node_object_wrap.h" #include "node_util.h" enum encoding ParseEncoding(v8::Handle<v8::Value> encoding_v, enum encoding _default) { v8::HandleScope scope; if (!encoding_v->IsString()) return _default; v8::String::Utf8Value encoding(encoding_v->ToString()); if (strcasecmp(*encoding, "utf8") == 0) { return UTF8; } else if (strcasecmp(*encoding, "utf-8") == 0) { return UTF8; } else if (strcasecmp(*encoding, "ascii") == 0) { return ASCII; } else if (strcasecmp(*encoding, "binary") == 0) { return BINARY; } else if (strcasecmp(*encoding, "raw") == 0) { fprintf(stderr, "'raw' (array of integers) has been removed. " "Use 'binary'.\n"); return BINARY; } else if (strcasecmp(*encoding, "raws") == 0) { fprintf(stderr, "'raws' encoding has been renamed to 'binary'. " "Please update your code.\n"); return BINARY; } else { return _default; } } v8::Local<v8::Value> Encode(const void *buf, size_t len, enum encoding encoding) { v8::HandleScope scope; if (!len) return scope.Close(v8::String::Empty()); if (encoding == BINARY) { const unsigned char *cbuf = static_cast<const unsigned char*>(buf); uint16_t * twobytebuf = new uint16_t[len]; for (size_t i = 0; i < len; i++) { // XXX is the following line platform independent? twobytebuf[i] = cbuf[i]; } v8::Local<v8::String> chunk = v8::String::New(twobytebuf, len); delete [] twobytebuf; // TODO use ExternalTwoBytev8::String? return scope.Close(chunk); } // utf8 or ascii encoding v8::Local<v8::String> chunk = v8::String::New((const char*)buf, len); return scope.Close(chunk); } // Returns -1 if the handle was not valid for decoding ssize_t DecodeBytes(v8::Handle<v8::Value> val, enum encoding encoding) { v8::HandleScope scope; if (val->IsArray()) { fprintf(stderr, "'raw' encoding (array of integers) has been removed. " "Use 'binary'.\n"); assert(0); return -1; } v8::Local<v8::String> str = val->ToString(); if (encoding == UTF8) return str->Utf8Length(); return str->Length(); } #ifndef MIN # define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif // Returns number of bytes written. ssize_t DecodeWrite(char *buf, size_t buflen, v8::Handle<v8::Value> val, enum encoding encoding) { v8::HandleScope scope; // XXX // A lot of improvement can be made here. See: // http://code.google.com/p/v8/issues/detail?id=270 // http://groups.google.com/group/v8-dev/browse_thread/thread/dba28a81d9215291/ece2b50a3b4022c // http://groups.google.com/group/v8-users/browse_thread/thread/1f83b0ba1f0a611 if (val->IsArray()) { fprintf(stderr, "'raw' encoding (array of integers) has been removed. " "Use 'binary'.\n"); assert(0); return -1; } v8::Local<v8::String> str = val->ToString(); if (encoding == UTF8) { str->WriteUtf8(buf, buflen); return buflen; } if (encoding == ASCII) { str->WriteAscii(buf, 0, buflen); return buflen; } // THIS IS AWFUL!!! FIXME assert(encoding == BINARY); uint16_t * twobytebuf = new uint16_t[buflen]; str->Write(twobytebuf, 0, buflen); for (size_t i = 0; i < buflen; i++) { unsigned char *b = reinterpret_cast<unsigned char*>(&twobytebuf[i]); assert(b[1] == 0); buf[i] = b[0]; } delete [] twobytebuf; return buflen; }