-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
330 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
export function strencode(str) { | ||
var byteArray = new ByteArray(str.length * 3); | ||
var offset = 0; | ||
for (var i = 0; i < str.length; i++) { | ||
var charCode = str.charCodeAt(i); | ||
var codes = null; | ||
if (charCode <= 0x7f) { | ||
codes = [charCode]; | ||
} else if (charCode <= 0x7ff) { | ||
codes = [0xc0 | (charCode >> 6), 0x80 | (charCode & 0x3f)]; | ||
} else { | ||
codes = [0xe0 | (charCode >> 12), 0x80 | ((charCode & 0xfc0) >> 6), 0x80 | (charCode & 0x3f)]; | ||
} | ||
for (var j = 0; j < codes.length; j++) { | ||
byteArray[offset] = codes[j]; | ||
++offset; | ||
} | ||
} | ||
var _buffer = new ByteArray(offset); | ||
copyArray(_buffer, 0, byteArray, 0, offset); | ||
return _buffer; | ||
}; | ||
|
||
export function strdecode(buffer) { | ||
var bytes = new ByteArray(buffer); | ||
var array = []; | ||
var offset = 0; | ||
var charCode = 0; | ||
var end = bytes.length; | ||
while (offset < end) { | ||
if (bytes[offset] < 128) { | ||
charCode = bytes[offset]; | ||
offset += 1; | ||
} else if (bytes[offset] < 224) { | ||
charCode = ((bytes[offset] & 0x3f) << 6) + (bytes[offset + 1] & 0x3f); | ||
offset += 2; | ||
} else { | ||
charCode = ((bytes[offset] & 0x0f) << 12) + ((bytes[offset + 1] & 0x3f) << 6) + (bytes[offset + 2] & 0x3f); | ||
offset += 3; | ||
} | ||
array.push(charCode); | ||
} | ||
return String.fromCharCode.apply(null, array); | ||
}; | ||
|
||
export function copyArray(dest, doffset, src, soffset, length) { | ||
if ('function' === typeof src.copy) { | ||
// Buffer | ||
src.copy(dest, doffset, soffset, soffset + length); | ||
return dest; | ||
} else { | ||
// Uint8Array | ||
var result = dest; | ||
if (dest.length < (doffset + length)) { | ||
result = new ByteArray(doffset + length); | ||
} | ||
|
||
for (var i = 0; i < dest.length; i++) { | ||
result[i] = dest[i]; | ||
} | ||
|
||
for (var index = 0; index < length; index++) { | ||
result[doffset++] = src[soffset++]; | ||
} | ||
|
||
return result; | ||
} | ||
} | ||
|
||
export class ByteArray extends Uint8Array { | ||
private woffset = 0; | ||
private roffset = 0; | ||
|
||
public writeUint8 (val) { | ||
this[this.woffset++] = val & 0xff; | ||
return this; | ||
} | ||
|
||
public writeUint16 (val) { | ||
this[this.woffset++] = (val >> 8) & 0xff; | ||
this[this.woffset++] = val & 0xff; | ||
return this; | ||
} | ||
|
||
public writeUint32 (val) { | ||
this[this.woffset++] = (val >> 24) & 0xff; | ||
this[this.woffset++] = (val >> 16) & 0xff; | ||
this[this.woffset++] = (val >> 8) & 0xff; | ||
this[this.woffset++] = val & 0xff; | ||
return this; | ||
} | ||
|
||
public writeString (val) { | ||
if (!val || val.length <= 0) return this; | ||
|
||
var bytes = strencode(val); | ||
// console.log(val, bytes, bytes.length); | ||
var result = copyArray(this, this.woffset, bytes, 0, bytes.length); | ||
result.woffset = this.woffset + bytes.length; | ||
return result; | ||
} | ||
|
||
public writeBytes (data) { | ||
if (!data || !data.length) return this; | ||
|
||
var result = copyArray(this, this.length, data, 0, data.length); | ||
result.woffset = this.woffset + data.length; | ||
return result; | ||
} | ||
|
||
public hasReadSize (len) { | ||
return len <= this.length - this.roffset; | ||
} | ||
|
||
public readUint8 () { | ||
if (this.roffset + 1 > this.length) return undefined; | ||
|
||
var val = this[this.roffset] & 0xff; | ||
this.roffset += 1; | ||
return val; | ||
} | ||
|
||
public readUint16 () { | ||
var h = this.readUint8(); | ||
var l = this.readUint8(); | ||
if (h == undefined || l == undefined) return undefined; | ||
|
||
return h << 8 | l; | ||
} | ||
|
||
public readUint32 () { | ||
var h = this.readUint16(); | ||
var l = this.readUint16(); | ||
if (h == undefined || l == undefined) return undefined; | ||
|
||
return h << 16 | l; | ||
} | ||
|
||
public readBytes (len) { | ||
if (len <= 0) return undefined; | ||
|
||
if (this.roffset + len > this.length) return undefined; | ||
|
||
var bytes = this.slice(this.roffset, this.roffset + len); | ||
// console.log(bytes, bytes.length, len); | ||
this.roffset += len; | ||
return bytes; | ||
} | ||
|
||
public readString (len) { | ||
var bytes = this.readBytes(len); | ||
if (bytes == undefined) return ""; | ||
|
||
return strdecode(bytes); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
export default class Emitter { | ||
private _callbacks = {}; | ||
|
||
/** | ||
* Listen on the given `event` with `fn`. | ||
* | ||
* @param {String} event | ||
* @param {Function} fn | ||
* @return {Emitter} | ||
* @api public | ||
*/ | ||
public on = this.addEventListener; | ||
public addListener = this.addEventListener; | ||
public addEventListener(event, fn) { | ||
(this._callbacks[event] = this._callbacks[event] || []).push(fn); | ||
return this; | ||
} | ||
|
||
/** | ||
* Adds an `event` listener that will be invoked a single | ||
* time then automatically removed. | ||
* | ||
* @param {String} event | ||
* @param {Function} fn | ||
* @return {Emitter} | ||
* @api public | ||
*/ | ||
public once = this.addEventListenerOnce; | ||
public addListenerOnce = this.addEventListenerOnce; | ||
public addEventListenerOnce(event, fn) { | ||
var self = this; | ||
|
||
function on() { | ||
self.off(event, on); | ||
fn.apply(this, arguments); | ||
} | ||
|
||
on.fn = fn; | ||
this.on(event, on); | ||
return this; | ||
} | ||
|
||
/** | ||
* Remove the given callback for `event` or all | ||
* registered callbacks. | ||
* | ||
* @param {String} event | ||
* @param {Function} fn | ||
* @return {Emitter} | ||
* @api public | ||
*/ | ||
public off = this.removeEventListener; | ||
public removeListener = this.removeEventListener; | ||
public removeEventListener(event, fn) { | ||
// specific event | ||
var callbacks = this._callbacks[event]; | ||
if (!callbacks) return this; | ||
|
||
// remove all handlers | ||
if (1 == arguments.length) { | ||
delete this._callbacks[event]; | ||
return this; | ||
} | ||
|
||
// remove specific handler | ||
var cb; | ||
for (var i = 0; i < callbacks.length; i++) { | ||
cb = callbacks[i]; | ||
if (cb === fn || cb.fn === fn) { | ||
callbacks.splice(i, 1); | ||
break; | ||
} | ||
} | ||
return this; | ||
} | ||
|
||
public removeAllListeners() { | ||
this._callbacks = {}; | ||
return this; | ||
} | ||
|
||
/** | ||
* Emit `event` with the given args. | ||
* | ||
* @param {String} event | ||
* @param {Mixed} ... | ||
* @return {Emitter} | ||
*/ | ||
public emit(event) { | ||
var args = [].slice.call(arguments, 1), | ||
callbacks = this._callbacks[event]; | ||
|
||
if (callbacks) { | ||
callbacks = callbacks.slice(0); | ||
for (var i = 0, len = callbacks.length; i < len; ++i) { | ||
callbacks[i].apply(this, args); | ||
} | ||
} | ||
|
||
return this; | ||
}; | ||
|
||
/** | ||
* Return array of callbacks for `event`. | ||
* | ||
* @param {String} event | ||
* @return {Array} | ||
* @api public | ||
*/ | ||
public listeners(event) { | ||
return this._callbacks[event] || []; | ||
}; | ||
|
||
/** | ||
* Check if this emitter has `event` handlers. | ||
* | ||
* @param {String} event | ||
* @return {Boolean} | ||
* @api public | ||
*/ | ||
public hasListeners(event) { | ||
return !!this.listeners(event).length; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
export default class IdGen { | ||
private id: number; | ||
private max: number; | ||
|
||
public constructor(max: number) { | ||
this.max = max; | ||
} | ||
|
||
public next(): number { | ||
if (this.id++ > this.max) { | ||
this.id = 0; | ||
} | ||
|
||
return this.id; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters