1 |
|
2 |
|
3 | var exports = module.exports = Ext;
|
4 | var encoders = exports.encoders = {};
|
5 | var decoders = exports.decoders = [];
|
6 |
|
7 | exports.Error = {name: 1, message: 1, stack: 1, columnNumber: 1, fileName: 1, lineNumber: 1};
|
8 |
|
9 | var encode = require("./encode").encode;
|
10 | var decode = require("./decode").decode;
|
11 | var SuperExtBuffer = require("./ext-buffer").ExtBuffer;
|
12 | var extBufferPrototype = new SuperExtBuffer();
|
13 |
|
14 | function Ext(type, className) {
|
15 | if (!(this instanceof Ext)) return new Ext(type, className);
|
16 | if ("string" === typeof type) type = type.charCodeAt(0);
|
17 | this._type = type;
|
18 | decoders[type] = this;
|
19 | encoders[className] = this;
|
20 | }
|
21 |
|
22 | Ext.prototype.type = function() {
|
23 | return this._type;
|
24 | };
|
25 |
|
26 | Ext.prototype.encoder = function(encoder) {
|
27 | this.encode = Array.prototype.reduce.call(arguments, join);
|
28 | return this;
|
29 | };
|
30 |
|
31 | Ext.prototype.decoder = function(decoder) {
|
32 | this.decode = Array.prototype.reduce.call(arguments, join);
|
33 | return this;
|
34 | };
|
35 |
|
36 | Ext.prototype.parser = function(parse) {
|
37 | this.parse = Array.prototype.reduce.call(arguments, join);
|
38 | return this;
|
39 | };
|
40 |
|
41 | Ext.prototype.builder = function(build) {
|
42 | this.build = Array.prototype.reduce.call(arguments, join);
|
43 | return this;
|
44 | };
|
45 |
|
46 | Ext.prototype.parse = function(value) {
|
47 | return (value).valueOf();
|
48 | };
|
49 |
|
50 | Ext.prototype.build = function(value) {
|
51 |
|
52 | var Class = global[this.type];
|
53 | return new Class(value);
|
54 | };
|
55 |
|
56 | Ext.prototype.encode = function(value) {
|
57 | return encode(this.parse(value));
|
58 | };
|
59 |
|
60 | Ext.prototype.decode = function(value) {
|
61 | return this.build(decode(value));
|
62 | };
|
63 |
|
64 | function join(prev, current) {
|
65 | return function(value) {
|
66 | return current(prev(value));
|
67 | };
|
68 | }
|
69 |
|
70 | init();
|
71 |
|
72 | function init() {
|
73 |
|
74 | for (var i = 255; i >= 0; i--) {
|
75 | var e = Ext(i, "ExtBuffer").encoder(encodeExtBuffer).decoder(createExtBuffer(i));
|
76 | e.type = getType;
|
77 | }
|
78 |
|
79 |
|
80 | Ext(0x01, "EvalError").parser(map(exports.Error)).builder(buildError);
|
81 | Ext(0x02, "RangeError").parser(map(exports.Error)).builder(buildError);
|
82 | Ext(0x03, "ReferenceError").parser(map(exports.Error)).builder(buildError);
|
83 | Ext(0x04, "SyntaxError").parser(map(exports.Error)).builder(buildError);
|
84 | Ext(0x05, "TypeError").parser(map(exports.Error)).builder(buildError);
|
85 | Ext(0x06, "URIError").parser(map(exports.Error)).builder(buildError);
|
86 |
|
87 | Ext(0x0A, "RegExp").parser(parseRegExp).builder(buildRegExp);
|
88 | Ext(0x0B, "Boolean").parser(Number).builder(create(Boolean));
|
89 | Ext(0x0C, "String").builder(create(String));
|
90 | Ext(0x0D, "Date").parser(Number).builder(create(Date));
|
91 | Ext(0x0E, "Error").parser(map(exports.Error)).builder(buildError);
|
92 | Ext(0x0F, "Number").builder(create(Number));
|
93 |
|
94 | if ("undefined" === typeof Uint8Array) return;
|
95 |
|
96 | Ext(0x11, "Int8Array").encoder(Buffer).decoder(create(Int8Array));
|
97 | Ext(0x12, "Uint8Array").encoder(Buffer).decoder(create(Uint8Array));
|
98 | Ext(0x13, "Int16Array").encoder(encodeTypedArray).decoder(decodeArrayBuffer, create(Int16Array));
|
99 | Ext(0x14, "Uint16Array").encoder(encodeTypedArray).decoder(decodeArrayBuffer, create(Uint16Array));
|
100 | Ext(0x15, "Int32Array").encoder(encodeTypedArray).decoder(decodeArrayBuffer, create(Int32Array));
|
101 | Ext(0x16, "Uint32Array").encoder(encodeTypedArray).decoder(decodeArrayBuffer, create(Uint32Array));
|
102 | Ext(0x17, "Float32Array").encoder(encodeTypedArray).decoder(decodeArrayBuffer, create(Float32Array));
|
103 | Ext(0x18, "Float64Array").encoder(encodeTypedArray).decoder(decodeArrayBuffer, create(Float64Array));
|
104 | Ext(0x19, "Uint8ClampedArray").encoder(Buffer).decoder(create(Uint8ClampedArray));
|
105 | Ext(0x1A, "ArrayBuffer").encoder(encodeArrayBuffer).decoder(decodeArrayBuffer);
|
106 | Ext(0x1D, "DataView").encoder(encodeTypedArray).decoder(decodeArrayBuffer, create(DataView));
|
107 | }
|
108 |
|
109 | function buildError(value) {
|
110 | var out = new Error();
|
111 | for (var key in exports.Error) {
|
112 | out[key] = value[key];
|
113 | }
|
114 | return out;
|
115 | }
|
116 |
|
117 | function parseRegExp(value) {
|
118 | return RegExp.prototype.toString.call(value).split("/").slice(1);
|
119 | }
|
120 |
|
121 | function buildRegExp(value) {
|
122 | return RegExp.apply(null, value);
|
123 | }
|
124 |
|
125 | function encodeTypedArray(value) {
|
126 | return Buffer(new Uint8Array(value.buffer));
|
127 | }
|
128 |
|
129 | function encodeArrayBuffer(value) {
|
130 | return Buffer(new Uint8Array(value));
|
131 | }
|
132 |
|
133 | function decodeArrayBuffer(value) {
|
134 | return (new Uint8Array(value)).buffer;
|
135 | }
|
136 |
|
137 | function create(Class) {
|
138 | return function(value) {
|
139 | return new Class(value);
|
140 | };
|
141 | }
|
142 |
|
143 | function map(fields) {
|
144 | return function(value) {
|
145 | var out = {};
|
146 | for (var key in fields) {
|
147 | out[key] = value[key];
|
148 | }
|
149 | return out;
|
150 | };
|
151 | }
|
152 |
|
153 | function createExtBuffer(type) {
|
154 | ExtBuffer.prototype = extBufferPrototype;
|
155 | return ExtBuffer;
|
156 |
|
157 | function ExtBuffer(buffer) {
|
158 | if (!(this instanceof ExtBuffer)) return new ExtBuffer(buffer);
|
159 | SuperExtBuffer.call(this, buffer);
|
160 | this.type = type;
|
161 | }
|
162 | }
|
163 |
|
164 | function encodeExtBuffer(value) {
|
165 | return value.buffer;
|
166 | }
|
167 |
|
168 | function getType(value) {
|
169 | return value.type;
|
170 | }
|