You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					169 lines
				
				3.7 KiB
			
		
		
			
		
	
	
					169 lines
				
				3.7 KiB
			| 
								 
											11 years ago
										 
									 | 
							
								function BinaryString(source) {
							 | 
						||
| 
								 | 
							
									this._source = null;
							 | 
						||
| 
								 | 
							
									this._bytes  = [];
							 | 
						||
| 
								 | 
							
									this._pos    = 0;
							 | 
						||
| 
								 | 
							
									this._length = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this._init = function(source) {
							 | 
						||
| 
								 | 
							
										this._source = source;
							 | 
						||
| 
								 | 
							
										this._bytes  = this._stringToBytes(this._source);
							 | 
						||
| 
								 | 
							
										this._length = this._bytes.length;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.current = function() {return this._pos;}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.rewind  = function() {return this.jump(0);}
							 | 
						||
| 
								 | 
							
									this.end     = function() {return this.jump(this.length()  - 1);}
							 | 
						||
| 
								 | 
							
									this.next    = function() {return this.jump(this.current() + 1);}
							 | 
						||
| 
								 | 
							
									this.prev    = function() {return this.jump(this.current() - 1);}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.jump = function(pos) {
							 | 
						||
| 
								 | 
							
										if (pos < 0 || pos >= this.length()) return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this._pos = pos;
							 | 
						||
| 
								 | 
							
										return true;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.readByte = function(pos) {
							 | 
						||
| 
								 | 
							
										pos = (typeof pos == 'number') ? pos : this.current();
							 | 
						||
| 
								 | 
							
										return this.readBytes(1, pos)[0];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.readBytes = function(length, pos) {
							 | 
						||
| 
								 | 
							
										length = length || 1;
							 | 
						||
| 
								 | 
							
										pos    = (typeof pos == 'number') ? pos : this.current();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (pos          >  this.length() ||
							 | 
						||
| 
								 | 
							
										    pos          <  0             ||
							 | 
						||
| 
								 | 
							
										    length       <= 0             ||
							 | 
						||
| 
								 | 
							
										    pos + length >  this.length() ||
							 | 
						||
| 
								 | 
							
										    pos + length <  0
							 | 
						||
| 
								 | 
							
										) {
							 | 
						||
| 
								 | 
							
											return false;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										var bytes = [];
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										for (var i = pos; i < pos + length; i++) {
							 | 
						||
| 
								 | 
							
											bytes.push(this._bytes[i]);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return bytes;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.length = function() {return this._length;}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.toString = function() {
							 | 
						||
| 
								 | 
							
										var string = '',
							 | 
						||
| 
								 | 
							
										    length = this.length();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for (var i = 0; i < length; i++) {
							 | 
						||
| 
								 | 
							
											string += String.fromCharCode(this.readByte(i));
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return string;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.toUtf8 = function() {
							 | 
						||
| 
								 | 
							
										var inc    = 0,
							 | 
						||
| 
								 | 
							
										    string = '',
							 | 
						||
| 
								 | 
							
										    length = this.length();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// determine if first 3 characters are the BOM
							 | 
						||
| 
								 | 
							
										// then skip them in output if so
							 | 
						||
| 
								 | 
							
										if (length >= 3               &&
							 | 
						||
| 
								 | 
							
										    this.readByte(0) === 0xEF &&
							 | 
						||
| 
								 | 
							
										    this.readByte(1) === 0xBB &&
							 | 
						||
| 
								 | 
							
										    this.readByte(2) === 0xBF
							 | 
						||
| 
								 | 
							
										) {
							 | 
						||
| 
								 | 
							
											inc = 3;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for (; inc < length; inc++) {
							 | 
						||
| 
								 | 
							
											var byte1 = this.readByte(inc),
							 | 
						||
| 
								 | 
							
											    byte2 = 0,
							 | 
						||
| 
								 | 
							
											    byte3 = 0,
							 | 
						||
| 
								 | 
							
											    byte4 = 0,
							 | 
						||
| 
								 | 
							
											    code1 = 0,
							 | 
						||
| 
								 | 
							
											    code2 = 0,
							 | 
						||
| 
								 | 
							
											    point = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											switch (true) {
							 | 
						||
| 
								 | 
							
												// single byte character; same as ascii
							 | 
						||
| 
								 | 
							
												case (byte1 < 0x80):
							 | 
						||
| 
								 | 
							
													code1 = byte1;
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												// 2 byte character
							 | 
						||
| 
								 | 
							
												case (byte1 >= 0xC2 && byte1 < 0xE0):
							 | 
						||
| 
								 | 
							
													byte2 = this.readByte(++inc);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													code1 = ((byte1 & 0x1F) << 6) +
							 | 
						||
| 
								 | 
							
													         (byte2 & 0x3F);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												// 3 byte character
							 | 
						||
| 
								 | 
							
												case (byte1 >= 0xE0 && byte1 < 0xF0):
							 | 
						||
| 
								 | 
							
													byte2 = this.readByte(++inc);
							 | 
						||
| 
								 | 
							
													byte3 = this.readByte(++inc);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													code1 = ((byte1 & 0xFF) << 12) +
							 | 
						||
| 
								 | 
							
													        ((byte2 & 0x3F) <<  6) +
							 | 
						||
| 
								 | 
							
													         (byte3 & 0x3F);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												// 4 byte character
							 | 
						||
| 
								 | 
							
												case (byte1 >= 0xF0 && byte1 < 0xF5):
							 | 
						||
| 
								 | 
							
													byte2 = this.readByte(++inc);
							 | 
						||
| 
								 | 
							
													byte3 = this.readByte(++inc);
							 | 
						||
| 
								 | 
							
													byte4 = this.readByte(++inc);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													point = ((byte1 & 0x07) << 18) +
							 | 
						||
| 
								 | 
							
													        ((byte2 & 0x3F) << 12) +
							 | 
						||
| 
								 | 
							
													        ((byte3 & 0x3F) <<  6) +
							 | 
						||
| 
								 | 
							
													         (byte4 & 0x3F)
							 | 
						||
| 
								 | 
							
													point -= 0x10000;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													code1 = (point >> 10)    + 0xD800;
							 | 
						||
| 
								 | 
							
													code2 = (point &  0x3FF) + 0xDC00;
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												default:
							 | 
						||
| 
								 | 
							
													throw 'Invalid byte ' + this._byteToString(byte1) + ' whilst converting to UTF-8';
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											string += (code2) ? String.fromCharCode(code1, code2)
							 | 
						||
| 
								 | 
							
											                  : String.fromCharCode(code1);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return string;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.toArray  = function() {return this.readBytes(this.length() - 1, 0);} 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this._stringToBytes = function(str) {
							 | 
						||
| 
								 | 
							
										var bytes = [],
							 | 
						||
| 
								 | 
							
										    chr   = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for (var i = 0; i < str.length; i++) {
							 | 
						||
| 
								 | 
							
											chr = str.charCodeAt(i);
							 | 
						||
| 
								 | 
							
											bytes.push(chr & 0xFF);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return bytes;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this._byteToString = function(byte) {
							 | 
						||
| 
								 | 
							
										var asString = byte.toString(16).toUpperCase();
							 | 
						||
| 
								 | 
							
										while (asString.length < 2) {
							 | 
						||
| 
								 | 
							
											asString = '0' + asString;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return '0x' + asString;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this._init(source);
							 | 
						||
| 
								 | 
							
								}
							 |