• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Contents of this file are snippets from node.cc
3  * see http://www.nodejs.org/
4  *
5  * Node's license follows:
6  *
7  * Copyright 2009, 2010 Ryan Lienhart Dahl. All rights reserved.
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to
10  * deal in the Software without restriction, including without limitation the
11  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12  * sell copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  */
15 #include <v8.h>
16 #include <string.h>
17 
18 #include "logging.h"
19 #include "node_object_wrap.h"
20 
21 #include "node_util.h"
22 
ParseEncoding(v8::Handle<v8::Value> encoding_v,enum encoding _default)23 enum encoding ParseEncoding(v8::Handle<v8::Value> encoding_v, enum encoding _default) {
24   v8::HandleScope scope;
25 
26   if (!encoding_v->IsString()) return _default;
27 
28   v8::String::Utf8Value encoding(encoding_v->ToString());
29 
30   if (strcasecmp(*encoding, "utf8") == 0) {
31     return UTF8;
32   } else if (strcasecmp(*encoding, "utf-8") == 0) {
33     return UTF8;
34   } else if (strcasecmp(*encoding, "ascii") == 0) {
35     return ASCII;
36   } else if (strcasecmp(*encoding, "binary") == 0) {
37     return BINARY;
38   } else if (strcasecmp(*encoding, "raw") == 0) {
39     fprintf(stderr, "'raw' (array of integers) has been removed. "
40                     "Use 'binary'.\n");
41     return BINARY;
42   } else if (strcasecmp(*encoding, "raws") == 0) {
43     fprintf(stderr, "'raws' encoding has been renamed to 'binary'. "
44                     "Please update your code.\n");
45     return BINARY;
46   } else {
47     return _default;
48   }
49 }
50 
Encode(const void * buf,size_t len,enum encoding encoding)51 v8::Local<v8::Value> Encode(const void *buf, size_t len, enum encoding encoding) {
52   v8::HandleScope scope;
53 
54   if (!len) return scope.Close(v8::String::Empty());
55 
56   if (encoding == BINARY) {
57     const unsigned char *cbuf = static_cast<const unsigned char*>(buf);
58     uint16_t * twobytebuf = new uint16_t[len];
59     for (size_t i = 0; i < len; i++) {
60       // XXX is the following line platform independent?
61       twobytebuf[i] = cbuf[i];
62     }
63     v8::Local<v8::String> chunk = v8::String::New(twobytebuf, len);
64     delete [] twobytebuf; // TODO use ExternalTwoBytev8::String?
65     return scope.Close(chunk);
66   }
67 
68   // utf8 or ascii encoding
69   v8::Local<v8::String> chunk = v8::String::New((const char*)buf, len);
70   return scope.Close(chunk);
71 }
72 
73 // Returns -1 if the handle was not valid for decoding
DecodeBytes(v8::Handle<v8::Value> val,enum encoding encoding)74 ssize_t DecodeBytes(v8::Handle<v8::Value> val, enum encoding encoding) {
75   v8::HandleScope scope;
76 
77   if (val->IsArray()) {
78     fprintf(stderr, "'raw' encoding (array of integers) has been removed. "
79                     "Use 'binary'.\n");
80     assert(0);
81     return -1;
82   }
83 
84   v8::Local<v8::String> str = val->ToString();
85 
86   if (encoding == UTF8) return str->Utf8Length();
87 
88   return str->Length();
89 }
90 
91 #ifndef MIN
92 # define MIN(a, b) ((a) < (b) ? (a) : (b))
93 #endif
94 
95 // Returns number of bytes written.
DecodeWrite(char * buf,size_t buflen,v8::Handle<v8::Value> val,enum encoding encoding)96 ssize_t DecodeWrite(char *buf,
97                     size_t buflen,
98                     v8::Handle<v8::Value> val,
99                     enum encoding encoding) {
100   v8::HandleScope scope;
101 
102   // XXX
103   // A lot of improvement can be made here. See:
104   // http://code.google.com/p/v8/issues/detail?id=270
105   // http://groups.google.com/group/v8-dev/browse_thread/thread/dba28a81d9215291/ece2b50a3b4022c
106   // http://groups.google.com/group/v8-users/browse_thread/thread/1f83b0ba1f0a611
107 
108   if (val->IsArray()) {
109     fprintf(stderr, "'raw' encoding (array of integers) has been removed. "
110                     "Use 'binary'.\n");
111     assert(0);
112     return -1;
113   }
114 
115   v8::Local<v8::String> str = val->ToString();
116 
117   if (encoding == UTF8) {
118     str->WriteUtf8(buf, buflen, NULL, v8::String::HINT_MANY_WRITES_EXPECTED);
119     return buflen;
120   }
121 
122   if (encoding == ASCII) {
123     str->WriteAscii(buf, 0, buflen, v8::String::HINT_MANY_WRITES_EXPECTED);
124     return buflen;
125   }
126 
127   // THIS IS AWFUL!!! FIXME
128 
129   assert(encoding == BINARY);
130 
131   uint16_t * twobytebuf = new uint16_t[buflen];
132 
133   str->Write(twobytebuf, 0, buflen, v8::String::HINT_MANY_WRITES_EXPECTED);
134 
135   for (size_t i = 0; i < buflen; i++) {
136     unsigned char *b = reinterpret_cast<unsigned char*>(&twobytebuf[i]);
137     assert(b[1] == 0);
138     buf[i] = b[0];
139   }
140 
141   delete [] twobytebuf;
142 
143   return buflen;
144 }
145