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