1#include "node.h" 2#include "string_bytes.h" 3#include "util-inl.h" 4#include "v8.h" 5 6namespace node { 7 8using v8::HandleScope; 9using v8::Isolate; 10using v8::Local; 11using v8::Value; 12 13enum 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 113enum 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 126Local<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 136Local<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 143ssize_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. 152ssize_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