UNPKG

4.61 kBJavaScriptView Raw
1// write-type.js
2
3exports.type = {
4 "boolean": bool,
5 "function": nil,
6 "number": number,
7 "object": object,
8 "string": string,
9 "symbol": nil,
10 "undefined": nil
11};
12
13var BufferLite = require("./buffer-lite");
14var token = require("./write-token").token;
15var encode = require("./write-core").encode;
16var uint8 = require("./write-uint8").uint8;
17var codec = require("./ext-preset").preset;
18var ExtBuffer = require("./ext-buffer").ExtBuffer;
19
20var IS_BUFFER_SHIM = ("TYPED_ARRAY_SUPPORT" in Buffer);
21var IS_ARRAY = Array.isArray || isArray;
22
23function bool(encoder, value) {
24 // false -- 0xc2
25 // true -- 0xc3
26 var type = value ? 0xc3 : 0xc2;
27 token[type](encoder, value);
28}
29
30function number(encoder, value) {
31 var ivalue = value | 0;
32 var type;
33 if (value !== ivalue) {
34 // float 64 -- 0xcb
35 type = 0xcb;
36 token[type](encoder, value);
37 return;
38 } else if (-0x20 <= ivalue && ivalue <= 0x7F) {
39 // positive fixint -- 0x00 - 0x7f
40 // negative fixint -- 0xe0 - 0xff
41 type = ivalue & 0xFF;
42 } else if (0 <= ivalue) {
43 // uint 8 -- 0xcc
44 // uint 16 -- 0xcd
45 // uint 32 -- 0xce
46 // uint 64 -- 0xcf
47 type = (ivalue <= 0xFF) ? 0xcc : (ivalue <= 0xFFFF) ? 0xcd : 0xce;
48 } else {
49 // int 8 -- 0xd0
50 // int 16 -- 0xd1
51 // int 32 -- 0xd2
52 // int 64 -- 0xd3
53 type = (-0x80 <= ivalue) ? 0xd0 : (-0x8000 <= ivalue) ? 0xd1 : 0xd2;
54 }
55 token[type](encoder, ivalue);
56}
57
58function string(encoder, value) {
59 // str 8 -- 0xd9
60 // str 16 -- 0xda
61 // str 32 -- 0xdb
62 // fixstr -- 0xa0 - 0xbf
63
64 // prepare buffer
65 var length = value.length;
66 var maxsize = 5 + length * 3;
67 encoder.reserve(maxsize);
68
69 // expected header size
70 var expected = (length < 32) ? 1 : (length <= 0xFF) ? 2 : (length <= 0xFFFF) ? 3 : 5;
71
72 // expected start point
73 var start = encoder.offset + expected;
74
75 // write string
76 length = BufferLite.writeString.call(encoder.buffer, value, start);
77
78 // actual header size
79 var actual = (length < 32) ? 1 : (length <= 0xFF) ? 2 : (length <= 0xFFFF) ? 3 : 5;
80
81 // move content when needed
82 if (expected !== actual) {
83 var targetStart = encoder.offset + actual;
84 var end = start + length;
85 if (IS_BUFFER_SHIM) {
86 BufferLite.copy.call(encoder.buffer, encoder.buffer, targetStart, start, end);
87 } else {
88 encoder.buffer.copy(encoder.buffer, targetStart, start, end);
89 }
90 }
91
92 // write header
93 var type = (actual === 1) ? (0xa0 + length) : (actual <= 3) ? 0xd7 + actual : 0xdb;
94 token[type](encoder, length);
95
96 // move cursor
97 encoder.offset += length;
98}
99
100var extmap = [];
101extmap[1] = 0xd4;
102extmap[2] = 0xd5;
103extmap[4] = 0xd6;
104extmap[8] = 0xd7;
105extmap[16] = 0xd8;
106
107function object(encoder, value) {
108 if (IS_ARRAY(value)) return array(encoder, value);
109 if (value === null) return nil(encoder, value);
110 var packer = codec.getExtPacker(value);
111 if (packer) value = packer(value);
112 if (value instanceof ExtBuffer) return ext(encoder, value);
113 if (Buffer.isBuffer(value)) return bin(encoder, value);
114 map(encoder, value);
115}
116
117function nil(encoder, value) {
118 // nil -- 0xc0
119 var type = 0xc0;
120 token[type](encoder, value);
121}
122
123function array(encoder, value) {
124 // fixarray -- 0x90 - 0x9f
125 // array 16 -- 0xdc
126 // array 32 -- 0xdd
127 var length = value.length;
128 var type = (length < 16) ? (0x90 + length) : (length <= 0xFFFF) ? 0xdc : 0xdd;
129 token[type](encoder, length);
130 for (var i = 0; i < length; i++) {
131 encode(encoder, value[i]);
132 }
133}
134
135function bin(encoder, value) {
136 // bin 8 -- 0xc4
137 // bin 16 -- 0xc5
138 // bin 32 -- 0xc6
139 var length = value.length;
140 var type = (length < 0xFF) ? 0xc4 : (length <= 0xFFFF) ? 0xc5 : 0xc6;
141 token[type](encoder, length);
142 encoder.send(value);
143}
144
145function ext(encoder, value) {
146 // fixext 1 -- 0xd4
147 // fixext 2 -- 0xd5
148 // fixext 4 -- 0xd6
149 // fixext 8 -- 0xd7
150 // fixext 16 -- 0xd8
151 // ext 8 -- 0xc7
152 // ext 16 -- 0xc8
153 // ext 32 -- 0xc9
154 var buffer = value.buffer;
155 var length = buffer.length;
156 var type = extmap[length] || ((length < 0xFF) ? 0xc7 : (length <= 0xFFFF) ? 0xc8 : 0xc9);
157 token[type](encoder, length);
158 uint8[value.type](encoder);
159 encoder.send(buffer);
160}
161
162function map(encoder, value) {
163 // fixmap -- 0x80 - 0x8f
164 // map 16 -- 0xde
165 // map 32 -- 0xdf
166 var keys = Object.keys(value);
167 var length = keys.length;
168 var type = (length < 16) ? (0x80 + length) : (length <= 0xFFFF) ? 0xde : 0xdf;
169 token[type](encoder, length);
170 keys.forEach(function(key) {
171 encode(encoder, key);
172 encode(encoder, value[key]);
173 });
174}
175
176function isArray(array) {
177 return "[object Array]" === Object.prototype.toString.call(array);
178}