我的朋友和我刚刚做过这个。它适用于js-ctypes。在Linux中,有一些宏用于处理向字节数组添加文件描述符(uint32)的列表:FD_SET
和FD_IS_SET
。文档在这里 - http://linux.die.net/man/2/select
我想知道是否有人能够检查我是否做得对,或者有人知道在javascript中做过的任何人吗?我需要为大端和小端完成32位/ 64位支持,但如果它已经存在,我很乐意看到它,因为当我们处理这个时,我们有很多不确定因素。
以下是代码,fd_set_get_idx
是完全基于的辅助函数。
var MACROS = {
fd_set_set: function(fdset, fd) {
let { elem8, bitpos8 } = MACROS.fd_set_get_idx(fd);
console.info('elem8:', elem8.toString());
console.info('bitpos8:', bitpos8.toString());
fdset[elem8] = 1 << bitpos8;
},
fd_set_isset: function(fdset, fd) {
let { elem8, bitpos8 } = MACROS.fd_set_get_idx(fd);
console.info('elem8:', elem8.toString());
console.info('bitpos8:', bitpos8.toString());
return !!(fdset[elem8] & (1 << bitpos8));
},
fd_set_get_idx: function(fd) {
if (osname == 'darwin' /*is_mac*/) {
// We have an array of int32. This should hopefully work on Darwin
// 32 and 64 bit.
let elem32 = Math.floor(fd / 32);
let bitpos32 = fd % 32;
let elem8 = elem32 * 8;
let bitpos8 = bitpos32;
if (bitpos8 >= 8) { // 8
bitpos8 -= 8;
elem8++;
}
if (bitpos8 >= 8) { // 16
bitpos8 -= 8;
elem8++;
}
if (bitpos8 >= 8) { // 24
bitpos8 -= 8;
elem8++;
}
return {'elem8': elem8, 'bitpos8': bitpos8};
} else { // else if (osname == 'linux' /*is_linux*/) { // removed the else if so this supports bsd and solaris now
// :todo: add 32bit support
// Unfortunately, we actually have an array of long ints, which is
// a) platform dependent and b) not handled by typed arrays. We manually
// figure out which byte we should be in. We assume a 64-bit platform
// that is little endian (aka x86_64 linux).
let elem64 = Math.floor(fd / 64);
let bitpos64 = fd % 64;
let elem8 = elem64 * 8;
let bitpos8 = bitpos64;
if (bitpos8 >= 8) { // 8
bitpos8 -= 8;
elem8++;
}
if (bitpos8 >= 8) { // 16
bitpos8 -= 8;
elem8++;
}
if (bitpos8 >= 8) { // 24
bitpos8 -= 8;
elem8++;
}
if (bitpos8 >= 8) { // 32
bitpos8 -= 8;
elem8++;
}
if (bitpos8 >= 8) { // 40
bitpos8 -= 8;
elem8++;
}
if (bitpos8 >= 8) { // 48
bitpos8 -= 8;
elem8++;
}
if (bitpos8 >= 8) { // 56
bitpos8 -= 8;
elem8++;
}
return {'elem8': elem8, 'bitpos8': bitpos8};
}
}
};
答案 0 :(得分:1)
我给你留下了识别字节序和字大小的负担 下面的代码模拟了 FD_XXX 函数,并允许您指定字节序和大小。
<!doctype>
<html>
<head>
<script>
var SIZE_32 = 4
var SIZE_64 = 8
var LITTLE_ENDIAN = [0, 1, 2, 3, 4, 5, 6, 7];
var BIG_ENDIAN = [7, 6, 5, 4, 3, 2, 1, 0];
function fdset(setSize, endianness, size)
{
var buffer = new Uint8Array(div(setSize + 7, 8));
function div(a, b)
{
return Math.floor(a / b);
}
function make_index(index)
{
return div(index, 8 * size) * size + endianness[div(index % (8 * size), 8)] % size;
}
buffer.set_bit = function(index)
{
buffer[make_index(index)] |= 1 << (index % 8);
};
buffer.clear_bit = function(index)
{
buffer[make_index(index)] &= ~(index % 8);
};
buffer.get_bit = function(index)
{
return buffer[make_index(index)] & 1 << (index % 8);
};
buffer.zero = function()
{
buffer.fill(0);
}
return buffer;
}
function FD_SET(fd, fdset)
{
fdset.set_bit(fd);
}
function FD_ISSET(fd, fdset)
{
return !!fdset.get_bit(fd);
}
function FD_CLR(fd, fdset)
{
return fdset.clear_bit(fd);
}
function FD_ZERO(fdset)
{
return fdset.zero();
}
</script>
</head>
<body>
<script>
var s = fdset(128, LITTLE_ENDIAN, SIZE_64);
//s in an Uint8Array
console.log(s);
FD_SET(0, s); //Byte 0 = 1
FD_SET(9, s); //Byte 1 = 2
FD_SET(18, s); //Byte 2 = 4
FD_SET(27, s); //Byte 3 = 8
FD_SET(36, s); //Byte 4 = 16
FD_SET(45, s); //Byte 5 = 32
FD_SET(54, s); //Byte 6 = 64
FD_SET(63, s); //Byte 7 = 128
FD_SET(120, s); //Byte 15 = 1
FD_SET(113, s); //Byte 14 = 2
FD_SET(106, s); //Byte 13 = 4
FD_SET(99, s); //Byte 12 = 8
FD_SET(92, s); //Byte 11 = 16
FD_SET(85, s); //Byte 10 = 32
FD_SET(78, s); //Byte 9 = 64
FD_SET(71, s); //Byte 8 = 128
console.log(s);
//64 bits, BE: [128, 64, 32, 16, 8, 4, 2, 1, 1, 2, 4, 8, 16, 32, 64, 128]
//64 bits, LE: [1, 2, 4, 8, 16, 32, 64, 128, 128, 64, 32, 16, 8, 4, 2, 1]
//32 bits, BE: [8, 4, 2, 1, 128, 64, 32, 16, 16, 32, 64, 128, 1, 2, 4, 8]
//32 bits, LE: [1, 2, 4, 8, 16, 32, 64, 128, 128, 64, 32, 16, 8, 4, 2, 1]
</script>
</body>
</html>
fdset
函数返回Uint8Array
,您可以将其传递给本机函数或进一步详细说明。
setSize
设置支持的最大文件描述符。
请注意, js ctypes 已经有一个数组类型和本机字节序中常用的[U]intXX_t
类型,唉,没有一种类型可以映射到32/64位整数,基于平台并且没有sizeof
运算符 2 ,因此您仍需要执行外部检查以检测字大小。
使用 ctypes 会更自然 出于参考目的,here是 FD_XXX 函数的官方实现。
您可以使用struct array类型的单个字段定义uint32/64_t。
然后模仿C源代码的行为,在需要的时候小心使用UInt64 1 并避免使用shifts。
1 JS只有双数,这些数字有53位尾数,10位指数和1位符号。当使用位运算符时,双数被转换为整数,因为它是指定精度的尾数(指数只是一个标度,只是一个反转符号),这个数字最多可以携带53位的信息数。
2 我知道,我不是 js ctypes 的专家。