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 }
72 if (StringEqualNoCase(encoding, "binary"))
73 return LATIN1; // BINARY is a deprecated alias of LATIN1.
74 if (StringEqualNoCase(encoding, "buffer"))
75 return BUFFER;
76 if (StringEqualNoCase(encoding, "base64"))
77 return BASE64;
78 break;
79
80 case 'a':
81 case 'A':
82 // ascii
83 if (encoding[1] == 's') {
84 if (strncmp(encoding + 2, "cii", 4) == 0)
85 return ASCII;
86 }
87 if (StringEqualNoCase(encoding, "ascii"))
88 return ASCII;
89 break;
90
91 case 'h':
92 case 'H':
93 // hex
94 if (encoding[1] == 'e')
95 if (encoding[2] == 'x' && encoding[3] == '\0')
96 return HEX;
97 if (StringEqualNoCase(encoding, "hex"))
98 return HEX;
99 break;
100 }
101 return default_encoding;
102 }
103
104
ParseEncoding(Isolate * isolate,Local<Value> encoding_v,enum encoding default_encoding)105 enum encoding ParseEncoding(Isolate* isolate,
106 Local<Value> encoding_v,
107 enum encoding default_encoding) {
108 CHECK(!encoding_v.IsEmpty());
109
110 if (!encoding_v->IsString())
111 return default_encoding;
112
113 Utf8Value encoding(isolate, encoding_v);
114
115 return ParseEncoding(*encoding, default_encoding);
116 }
117
Encode(Isolate * isolate,const char * buf,size_t len,enum encoding encoding)118 Local<Value> Encode(Isolate* isolate,
119 const char* buf,
120 size_t len,
121 enum encoding encoding) {
122 CHECK_NE(encoding, UCS2);
123 Local<Value> error;
124 return StringBytes::Encode(isolate, buf, len, encoding, &error)
125 .ToLocalChecked();
126 }
127
Encode(Isolate * isolate,const uint16_t * buf,size_t len)128 Local<Value> Encode(Isolate* isolate, const uint16_t* buf, size_t len) {
129 Local<Value> error;
130 return StringBytes::Encode(isolate, buf, len, &error)
131 .ToLocalChecked();
132 }
133
134 // Returns -1 if the handle was not valid for decoding
DecodeBytes(Isolate * isolate,Local<Value> val,enum encoding encoding)135 ssize_t DecodeBytes(Isolate* isolate,
136 Local<Value> val,
137 enum encoding encoding) {
138 HandleScope scope(isolate);
139
140 return StringBytes::Size(isolate, val, encoding).FromMaybe(-1);
141 }
142
143 // Returns number of bytes written.
DecodeWrite(Isolate * isolate,char * buf,size_t buflen,Local<Value> val,enum encoding encoding)144 ssize_t DecodeWrite(Isolate* isolate,
145 char* buf,
146 size_t buflen,
147 Local<Value> val,
148 enum encoding encoding) {
149 return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr);
150 }
151
152 } // namespace node
153