1 #include "node.h"
2 #include "string_bytes.h"
3 #include "util-inl.h"
4 #include "v8.h"
5
6 namespace node {
7
8 using v8::HandleScope;
9 using v8::Isolate;
10 using v8::Local;
11 using v8::Value;
12
ParseEncoding(const char * encoding,enum encoding default_encoding)13 enum encoding ParseEncoding(const char* encoding,
14 enum encoding default_encoding) {
15 switch (encoding[0]) {
16 case 'u':
17 case 'U':
18 // utf8, utf16le
19 if (encoding[1] == 't' && encoding[2] == 'f') {
20 // Skip `-`
21 const size_t skip = encoding[3] == '-' ? 4 : 3;
22 if (encoding[skip] == '8' && encoding[skip + 1] == '\0')
23 return UTF8;
24 if (strncmp(encoding + skip, "16le", 5) == 0)
25 return UCS2;
26 // ucs2
27 } else if (encoding[1] == 'c' && encoding[2] == 's') {
28 const size_t skip = encoding[3] == '-' ? 4 : 3;
29 if (encoding[skip] == '2' && encoding[skip + 1] == '\0')
30 return UCS2;
31 }
32 if (StringEqualNoCase(encoding, "utf8"))
33 return UTF8;
34 if (StringEqualNoCase(encoding, "utf-8"))
35 return UTF8;
36 if (StringEqualNoCase(encoding, "ucs2"))
37 return UCS2;
38 if (StringEqualNoCase(encoding, "ucs-2"))
39 return UCS2;
40 if (StringEqualNoCase(encoding, "utf16le"))
41 return UCS2;
42 if (StringEqualNoCase(encoding, "utf-16le"))
43 return UCS2;
44 break;
45
46 case 'l':
47 case 'L':
48 // latin1
49 if (encoding[1] == 'a') {
50 if (strncmp(encoding + 2, "tin1", 5) == 0)
51 return LATIN1;
52 }
53 if (StringEqualNoCase(encoding, "latin1"))
54 return LATIN1;
55 break;
56
57 case 'b':
58 case 'B':
59 // binary is a deprecated alias of latin1
60 if (encoding[1] == 'i') {
61 if (strncmp(encoding + 2, "nary", 5) == 0)
62 return LATIN1;
63 // buffer
64 } else if (encoding[1] == 'u') {
65 if (strncmp(encoding + 2, "ffer", 5) == 0)
66 return BUFFER;
67 // base64
68 } else if (encoding[1] == 'a') {
69 if (strncmp(encoding + 2, "se64", 5) == 0)
70 return BASE64;
71 if (strncmp(encoding + 2, "se64url", 8) == 0)
72 return BASE64URL;
73 }
74 if (StringEqualNoCase(encoding, "binary"))
75 return LATIN1; // BINARY is a deprecated alias of LATIN1.
76 if (StringEqualNoCase(encoding, "buffer"))
77 return BUFFER;
78 if (StringEqualNoCase(encoding, "base64"))
79 return BASE64;
80 if (StringEqualNoCase(encoding, "base64url"))
81 return BASE64URL;
82 break;
83
84 case 'a':
85 case 'A':
86 // ascii
87 if (encoding[1] == 's') {
88 if (strncmp(encoding + 2, "cii", 4) == 0)
89 return ASCII;
90 }
91 if (StringEqualNoCase(encoding, "ascii"))
92 return ASCII;
93 break;
94
95 case 'h':
96 case 'H':
97 // hex
98 if (encoding[1] == 'e')
99 if (encoding[2] == 'x' && encoding[3] == '\0')
100 return HEX;
101 if (StringEqualNoCase(encoding, "hex"))
102 return HEX;
103 break;
104 }
105 return default_encoding;
106 }
107
108
ParseEncoding(Isolate * isolate,Local<Value> encoding_v,enum encoding default_encoding)109 enum encoding ParseEncoding(Isolate* isolate,
110 Local<Value> encoding_v,
111 enum encoding default_encoding) {
112 CHECK(!encoding_v.IsEmpty());
113
114 if (!encoding_v->IsString())
115 return default_encoding;
116
117 Utf8Value encoding(isolate, encoding_v);
118
119 return ParseEncoding(*encoding, default_encoding);
120 }
121
Encode(Isolate * isolate,const char * buf,size_t len,enum encoding encoding)122 Local<Value> Encode(Isolate* isolate,
123 const char* buf,
124 size_t len,
125 enum encoding encoding) {
126 CHECK_NE(encoding, UCS2);
127 Local<Value> error;
128 return StringBytes::Encode(isolate, buf, len, encoding, &error)
129 .ToLocalChecked();
130 }
131
Encode(Isolate * isolate,const uint16_t * buf,size_t len)132 Local<Value> Encode(Isolate* isolate, const uint16_t* buf, size_t len) {
133 Local<Value> error;
134 return StringBytes::Encode(isolate, buf, len, &error)
135 .ToLocalChecked();
136 }
137
138 // Returns -1 if the handle was not valid for decoding
DecodeBytes(Isolate * isolate,Local<Value> val,enum encoding encoding)139 ssize_t DecodeBytes(Isolate* isolate,
140 Local<Value> val,
141 enum encoding encoding) {
142 HandleScope scope(isolate);
143
144 return StringBytes::Size(isolate, val, encoding).FromMaybe(-1);
145 }
146
147 // Returns number of bytes written.
DecodeWrite(Isolate * isolate,char * buf,size_t buflen,Local<Value> val,enum encoding encoding)148 ssize_t DecodeWrite(Isolate* isolate,
149 char* buf,
150 size_t buflen,
151 Local<Value> val,
152 enum encoding encoding) {
153 return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr);
154 }
155
156 } // namespace node
157