javascript
window.addEventListener('load', () => {
var rowNumberElem = document.getElementById('main_row-number');
var binElem = document.getElementById('main_bin');
var strElem = document.getElementById('main_string');
Krbin.init();
//Krbin.loadByURI('./sample.dat', update);
document.getElementById('file-select').addEventListener('change', (event) => {
if (event.target.files[0] !== undefined) {
var file = event.target.files[0];
if (file.size > 65536) {
alert('65536バイト以上のファイルです。読み込みに失敗しました。');
} else {
Krbin.loadByFile(file, update);
}
}
});
binElem.addEventListener('keydown', (event) => {
if ((event.keyCode < 37 || 40 < event.keyCode) // !arrow
&& event.keyCode != 9 // !tab
) {
event.preventDefault();
}
});
binElem.addEventListener('keyup', (event) => {
var pos = binElem.selectionStart;
if (/^[0-9a-fA-F]$/.test(event.key)) {
var index = ~~(pos / 3);
var surplus = pos % 3;
var digits;
if (surplus === 0) {
digits = 2;
} else if (surplus === 1) {
digits = 1;
} else if (surplus === 2) {
digits = 2;
index += 1;
pos += 1;
}
Krbin.put(index, digits, event.key);
pos += (surplus === 1) ? 2 : 1;
} else {
Krbin.clearTmpInput();
}
update();
binElem.setSelectionRange(pos, pos);
});
binElem.addEventListener('blur', (event) => {
Krbin.clearTmpInput();
update();
});
binElem.addEventListener('scroll', (event) => {
rowNumberElem.scrollTop = event.target.scrollTop;
strElem.scrollTop = event.target.scrollTop;
});
document.getElementById('download-button').addEventListener('click', (event) => {
var elem = event.target;
var blob = Krbin.exportToBlob();
if (!blob) {
event.preventDefault();
return;
}
elem.href = window.URL.createObjectURL(blob);
elem.download = Krbin.getSaveFileName();
});
function update() {
var pos = binElem.selectionStart;
rowNumberElem.innerHTML = Krbin.getRowNumberString();
binElem.value = Krbin.getDataString();
strElem.innerHTML = Krbin.getHTMLString();
binElem.setSelectionRange(pos, pos);
}
});
var Krbin = (function() {
function Krbin() {}
Krbin._filename;
Krbin._data;
Krbin._tmpInput;
Krbin.init = function() {
Krbin._filename = 'noname';
Krbin._data = [];
Krbin._tmpInput = '';
};
Krbin.loadByFile = function(file, onload) {
Krbin._filename = file.name;
var reader = new FileReader();
reader.addEventListener('load', function(event) {
Krbin._data = Array.prototype.slice.call(new Uint8Array(event.target.result));
if (onload) {
onload();
}
});
reader.readAsArrayBuffer(file);
};
Krbin.loadByBinaryString = function(binStr) {
binStr = binStr.replace(/\s/g, '');
Krbin._data = binaryStringToArray(binStr);
};
Krbin.put = function(index, digits, value) {
if (digits < 1 || 2 < digits) {
return false;
}
value = parseInt(value, 16);
if (Krbin._data[index] === undefined) {
Krbin._tmpInput += value;
if (digits === 1) {
Krbin._data.push(parseInt(Krbin._tmpInput, 16));
Krbin.clearTmpInput();
}
} else {
Krbin.clearTmpInput();
var orgValue = Krbin._data[index];
var newValue = orgValue;
if (digits === 1) {
newValue = value + (orgValue & 0xf0);
} else if (digits === 2) {
newValue = (value * 16) + (orgValue & 0x0f);
}
Krbin._data[index] = newValue;
}
};
Krbin.clearTmpInput = function() {
Krbin._tmpInput = '';
};
Krbin.getRowNumberString = function() {
var str = '';
var num = 0;
for (var i = 0, len = Krbin._data.length; i < len; ++i) {
if ((i > 0 && i % 16 == 0) || i == len - 1) {
str += padLineNumber(num.toString(16)) +'\n';
num += 16;
}
}
return str;
};
function padLineNumber(num) {
var str = num + '';
switch (str.length) {
case 1: return '000'+ str;
case 2: return '00'+ str;
case 3: return '0'+ str;
default: return str;
}
}
Krbin.getDataString = function() {
var str = '';
for (var i = 0, len = Krbin._data.length; i <= len; ++i) {
if (i > 0) {
if (i % 16 == 0) {
str += '\n';
} else {
str += ' ';
}
}
if (i === len) {
str += Krbin._tmpInput;
} else {
var charCode = Krbin._data[i];
var hex = charCode.toString(16);
str += padHex(hex);
}
}
return str;
};
Krbin.getHTMLString = function() {
var str = '';
for (var i = 0, len = Krbin._data.length; i < len; ++i) {
if (i > 0 && i % 16 == 0) {
str += '\n';
}
var charCode = Krbin._data[i];
str += isPrintable(charCode) ? escape(String.fromCharCode(charCode)) : '<span class="non-printable">.</span>';
}
return str;
};
function escape(c) {
switch (c) {
case '"': return '"';
case '&': return '&';
case "'": return ''';
case '<': return '<';
case '>': return '>';
default: return c;
}
}
Krbin.exportToBlob = function() {
if (Krbin._data.length <= 0) {
return false;
}
return new Blob([new Uint8Array(Krbin._data)]);
};
Krbin.getSaveFileName = function() {
return new Date().getTime() +'_'+ Krbin._filename;
};
function padHex(str) {
switch (str.length) {
case 0: return '00';
case 1: return '0'+ str;
case 2: return str;
default: throw new Error('invalid hex string: '+ str);
}
}
function binaryStringToArray(binStr) {
var arr = [];
var binStrArr = binStr.split('');
var hex = '';
for (var i = 0, len = binStrArr.length; i < len; ++i) {
if (i > 0 && i % 2 === 0) {
arr.push(parseInt(hex, 16));
hex = '';
}
hex += binStrArr[i];
}
if (hex !== '') {
arr.push(parseInt(padHex(hex), 16));
}
return arr;
}
function isPrintable(charCode) {
return 0x20 <= charCode && charCode <= 0x7e;
}
return Krbin;
})();