1.4.x_branch (#1)

Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
2024-07-19 13:03:13 +00:00
parent b0e9f13cbc
commit 80d7ae3516
24 changed files with 2747 additions and 2740 deletions

View File

@@ -1,115 +1,115 @@
import connection from '../networking/connection';
import packet from '../networking/packet';
import Socket from 'net';
test(`connect fails when error occurs during createConnection`, async () => {
const mock_create = (port, host, cb) => {
cb(new Error('mock create error'));
};
jest.spyOn(Socket, 'createConnection').mockImplementation(mock_create);
const conn = new connection('localhost', 20000);
await expect(conn.connect()).rejects.toThrow(Error);
});
test(`socket receive data fails when decryption fails`, async () => {
let cbl = {};
const socket = {
setNoDelay: () => {},
setKeepAlive: () => {},
on: (name, cb) => {
cbl[name] = cb;
},
};
const conn = new connection('', 0, 'b', socket);
let reject;
const mock_reject = jest.fn().mockImplementation((e) => reject(e));
conn.reject = mock_reject;
conn.resolve = jest.fn();
const p = new packet('a');
await p.encrypt();
p.encode_top_ui32(p.buffer.length);
await expect(
new Promise((_, r) => {
reject = r;
cbl['data'](Buffer.from(p.buffer));
})
).rejects.toThrow(Error);
expect(mock_reject.mock.calls.length).toBe(1);
});
test(`disconnect succeeds if an error is thrown`, async () => {
const socket = {
setNoDelay: () => {},
setKeepAlive: () => {},
destroy: () => {
throw new Error('mock destroy error');
},
on: () => {},
};
const conn = new connection('', 0, 'b', socket);
await conn.disconnect();
});
test(`send fails on socket error`, async () => {
let cbl = {};
const socket = {
setNoDelay: () => {},
setKeepAlive: () => {},
on: (name, cb) => {
cbl[name] = cb;
},
};
const conn = new connection('', 0, 'b', socket);
const mock_reject = jest.fn();
conn.reject = mock_reject;
conn.resolve = jest.fn();
cbl['error']('socket error');
expect(mock_reject).toBeCalled();
});
test(`error is thrown when socket is closed`, async () => {
let cbl = {};
const socket = {
setNoDelay: () => {},
setKeepAlive: () => {},
on: (name, cb) => {
cbl[name] = cb;
},
};
const conn = new connection('', 0, 'b', socket);
const mock_reject = jest.fn();
conn.reject = mock_reject;
conn.resolve = jest.fn();
cbl['close']();
expect(mock_reject).toBeCalled();
});
test(`send fails when write error occurs`, async () => {
let cbl = {};
const socket = {
setNoDelay: () => {},
setKeepAlive: () => {},
on: (name, cb) => {
cbl[name] = cb;
},
write: (b, c, cb) => {
cb('mock write error');
},
};
const conn = new connection('', 0, 'b', socket);
try {
await conn.send('c', new packet('b'));
expect('send should fail').toBeNull();
} catch (err) {
expect(err).toBeDefined();
}
});
import connection from '../networking/connection';
import packet from '../networking/packet';
import Socket from 'net';
test(`connect fails when error occurs during createConnection`, async () => {
const mock_create = (port, host, cb) => {
cb(new Error('mock create error'));
};
jest.spyOn(Socket, 'createConnection').mockImplementation(mock_create);
const conn = new connection('localhost', 20000);
await expect(conn.connect()).rejects.toThrow(Error);
});
test(`socket receive data fails when decryption fails`, async () => {
let cbl = {};
const socket = {
setNoDelay: () => {},
setKeepAlive: () => {},
on: (name, cb) => {
cbl[name] = cb;
},
};
const conn = new connection('', 0, 'b', socket);
let reject;
const mock_reject = jest.fn().mockImplementation((e) => reject(e));
conn.reject = mock_reject;
conn.resolve = jest.fn();
const p = new packet('a');
await p.encrypt();
p.encode_top_ui32(p.buffer.length);
await expect(
new Promise((_, r) => {
reject = r;
cbl['data'](Buffer.from(p.buffer));
})
).rejects.toThrow(Error);
expect(mock_reject.mock.calls.length).toBe(1);
});
test(`disconnect succeeds if an error is thrown`, async () => {
const socket = {
setNoDelay: () => {},
setKeepAlive: () => {},
destroy: () => {
throw new Error('mock destroy error');
},
on: () => {},
};
const conn = new connection('', 0, 'b', socket);
await conn.disconnect();
});
test(`send fails on socket error`, async () => {
let cbl = {};
const socket = {
setNoDelay: () => {},
setKeepAlive: () => {},
on: (name, cb) => {
cbl[name] = cb;
},
};
const conn = new connection('', 0, 'b', socket);
const mock_reject = jest.fn();
conn.reject = mock_reject;
conn.resolve = jest.fn();
cbl['error']('socket error');
expect(mock_reject).toBeCalled();
});
test(`error is thrown when socket is closed`, async () => {
let cbl = {};
const socket = {
setNoDelay: () => {},
setKeepAlive: () => {},
on: (name, cb) => {
cbl[name] = cb;
},
};
const conn = new connection('', 0, 'b', socket);
const mock_reject = jest.fn();
conn.reject = mock_reject;
conn.resolve = jest.fn();
cbl['close']();
expect(mock_reject).toBeCalled();
});
test(`send fails when write error occurs`, async () => {
let cbl = {};
const socket = {
setNoDelay: () => {},
setKeepAlive: () => {},
on: (name, cb) => {
cbl[name] = cb;
},
write: (b, c, cb) => {
cb('mock write error');
},
};
const conn = new connection('', 0, 'b', socket);
try {
await conn.send('c', new packet('b'));
expect('send should fail').toBeNull();
} catch (err) {
expect(err).toBeDefined();
}
});

View File

@@ -1,59 +1,59 @@
import connection_pool from '../networking/connection_pool';
import packet from '../networking/packet';
import connection from '../networking/connection';
jest.mock('../networking/connection');
test(`construction fails if pool size is <= 1`, () => {
expect(() => new connection_pool(1)).toThrow(Error);
expect(() => new connection_pool(0)).toThrow(Error);
expect(() => new connection_pool(-1)).toThrow(Error);
});
test(`error on socket release is ignored`, async () => {
const conn = new connection_pool(2, '', 20000);
let invoked = false;
jest.spyOn(conn.pool, 'acquire').mockImplementation(() => {
return {
release: () => {
invoked = true;
throw new Error('mock release error');
},
};
});
const mock_send = jest.fn();
connection.prototype.send = async () => {
return mock_send();
};
mock_send.mockResolvedValue(0);
expect(await conn.send('', new packet())).toEqual(0);
expect(invoked).toBeTruthy();
});
test(`connection pool send fails if socket acquire fails`, async () => {
const conn = new connection_pool(2, '', 20000);
jest.spyOn(conn.pool, 'acquire').mockImplementation(() => {
throw new Error('mock acquire exception');
});
await expect(conn.send('', new packet())).rejects.toThrow(Error);
});
test(`connection pool send fails when connection send fails`, async () => {
const conn = new connection_pool(2, '', 20000);
jest.spyOn(conn.pool, 'acquire').mockImplementation(() => {
return {
release: () => {},
};
});
const mock_send = jest.fn();
connection.prototype.send = async () => {
return mock_send();
};
mock_send.mockRejectedValue(new Error('mock send failed'));
await expect(conn.send('', new packet())).rejects.toThrow(Error);
});
import connection_pool from '../networking/connection_pool';
import packet from '../networking/packet';
import connection from '../networking/connection';
jest.mock('../networking/connection');
test(`construction fails if pool size is <= 1`, () => {
expect(() => new connection_pool(1)).toThrow(Error);
expect(() => new connection_pool(0)).toThrow(Error);
expect(() => new connection_pool(-1)).toThrow(Error);
});
test(`error on socket release is ignored`, async () => {
const conn = new connection_pool(2, '', 20000);
let invoked = false;
jest.spyOn(conn.pool, 'acquire').mockImplementation(() => {
return {
release: () => {
invoked = true;
throw new Error('mock release error');
},
};
});
const mock_send = jest.fn();
connection.prototype.send = async () => {
return mock_send();
};
mock_send.mockResolvedValue(0);
expect(await conn.send('', new packet())).toEqual(0);
expect(invoked).toBeTruthy();
});
test(`connection pool send fails if socket acquire fails`, async () => {
const conn = new connection_pool(2, '', 20000);
jest.spyOn(conn.pool, 'acquire').mockImplementation(() => {
throw new Error('mock acquire exception');
});
await expect(conn.send('', new packet())).rejects.toThrow(Error);
});
test(`connection pool send fails when connection send fails`, async () => {
const conn = new connection_pool(2, '', 20000);
jest.spyOn(conn.pool, 'acquire').mockImplementation(() => {
return {
release: () => {},
};
});
const mock_send = jest.fn();
connection.prototype.send = async () => {
return mock_send();
};
mock_send.mockRejectedValue(new Error('mock send failed'));
await expect(conn.send('', new packet())).rejects.toThrow(Error);
});

View File

@@ -1,18 +1,18 @@
import { get_version, instance_id, package_json } from '../utils/constants';
import * as uuid from 'uuid';
test(`can read 'package.json'`, () => {
console.log(package_json);
expect(package_json).toBeDefined();
});
test(`'instance_id' is valid`, () => {
console.log(instance_id);
expect(instance_id).toBeDefined();
expect(uuid.parse(instance_id)).toBeInstanceOf(Uint8Array);
});
test(`'version' can be read from 'package.json'`, () => {
console.log(get_version());
expect(get_version()).toBe('1.4.0-r1');
});
import { get_version, instance_id, package_json } from '../utils/constants';
import * as uuid from 'uuid';
test(`can read 'package.json'`, () => {
console.log(package_json);
expect(package_json).toBeDefined();
});
test(`'instance_id' is valid`, () => {
console.log(instance_id);
expect(instance_id).toBeDefined();
expect(uuid.parse(instance_id)).toBeInstanceOf(Uint8Array);
});
test(`'version' can be read from 'package.json'`, () => {
console.log(get_version());
expect(get_version()).toBe('1.4.0-r1');
});

View File

@@ -1,47 +1,47 @@
import file from '../io/file';
jest.mock('../ops/index.js', () => ({
...jest.requireActual('../ops/index.js'),
close_file: jest.fn(),
}));
import { close_file } from '../ops/index';
test(`can close a closed file`, async () => {
const f = new file();
expect(await f.close()).toEqual(0);
});
test(`'get_size' fails on closed file`, async () => {
const f = new file();
await expect(f.get_size()).rejects.toThrow(Error);
});
test(`'read' fails on closed file`, async () => {
const f = new file();
await expect(f.read(0, 10)).rejects.toThrow(Error);
});
test(`'truncate' fails on closed file`, async () => {
const f = new file();
await expect(f.truncate(0)).rejects.toThrow(Error);
});
test(`'write' fails on closed file`, async () => {
const f = new file();
await expect(f.write(0, Buffer.alloc(2))).rejects.toThrow(Error);
});
test(`handle is set to null on close`, async () => {
const f = new file(null, 1, '/path');
close_file.mockReturnValue(0);
expect(await f.close()).toEqual(0);
expect(f.handle).toBeNull();
});
test(`handle is not changed on close if return is not 0`, async () => {
const f = new file(null, 1, '/path');
close_file.mockReturnValue(1);
expect(await f.close()).toEqual(1);
expect(f.handle).toBe(1);
});
import file from '../io/file';
jest.mock('../ops/index.js', () => ({
...jest.requireActual('../ops/index.js'),
close_file: jest.fn(),
}));
import { close_file } from '../ops/index';
test(`can close a closed file`, async () => {
const f = new file();
expect(await f.close()).toEqual(0);
});
test(`'get_size' fails on closed file`, async () => {
const f = new file();
await expect(f.get_size()).rejects.toThrow(Error);
});
test(`'read' fails on closed file`, async () => {
const f = new file();
await expect(f.read(0, 10)).rejects.toThrow(Error);
});
test(`'truncate' fails on closed file`, async () => {
const f = new file();
await expect(f.truncate(0)).rejects.toThrow(Error);
});
test(`'write' fails on closed file`, async () => {
const f = new file();
await expect(f.write(0, Buffer.alloc(2))).rejects.toThrow(Error);
});
test(`handle is set to null on close`, async () => {
const f = new file(null, 1, '/path');
close_file.mockReturnValue(0);
expect(await f.close()).toEqual(0);
expect(f.handle).toBeNull();
});
test(`handle is not changed on close if return is not 0`, async () => {
const f = new file(null, 1, '/path');
close_file.mockReturnValue(1);
expect(await f.close()).toEqual(1);
expect(f.handle).toBe(1);
});

View File

@@ -1,19 +1,19 @@
import packet from '../networking/packet';
test('can construct a packet', () => {
const p = new packet('my password');
console.log(p);
expect(p.token).toEqual('my password');
expect(p.buffer).toEqual(new Uint8Array(0));
expect(p.decode_offset).toEqual(0);
});
test('can encrypt and decrypt a packet', async () => {
console.log('testing');
const p = new packet('my password');
p.encode_utf8('moose');
await p.encrypt();
await p.decrypt();
const str = p.decode_utf8();
expect(str).toEqual('moose');
});
import packet from '../networking/packet';
test('can construct a packet', () => {
const p = new packet('my password');
console.log(p);
expect(p.token).toEqual('my password');
expect(p.buffer).toEqual(new Uint8Array(0));
expect(p.decode_offset).toEqual(0);
});
test('can encrypt and decrypt a packet', async () => {
console.log('testing');
const p = new packet('my password');
p.encode_utf8('moose');
await p.encrypt();
await p.decrypt();
const str = p.decode_utf8();
expect(str).toEqual('moose');
});

File diff suppressed because it is too large Load Diff

View File

@@ -1,94 +1,94 @@
import file from './io/file';
import connection from './networking/connection';
import connection_pool from './networking/connection_pool';
import * as ops from './ops';
export * as byte_order from './utils/byte_order';
export { getCustomEncryption, setCustomEncryption } from './utils/constants';
export { default as packet } from './networking/packet';
export const connect = async (host_or_ip, port, password) => {
const conn = new connection(host_or_ip, port, password);
await conn.connect();
return conn;
};
export const create_api = (conn) => {
return {
directory: {
create: async (remote_path) => ops.create_directory(conn, remote_path),
exists: async (remote_path) => {
try {
const info = await ops.get_file_attributes2(conn, remote_path);
return info.directory;
} catch (e) {
if (e.message.split(':')[1].trim() == '-2') {
return false;
}
throw new Error(e.message);
}
},
list: async (remote_path, page_reader_cb) =>
ops.list_directory(conn, remote_path, page_reader_cb),
remove: async (remote_path) => ops.remove_directory(conn, remote_path),
snapshot: async (remote_path) => {
return ops.snapshot_directory(conn, remote_path);
},
},
file: {
create_or_open: async (remote_path) =>
new file(
conn,
await ops.create_or_open_file(conn, remote_path),
remote_path
),
download: async (
remote_path,
local_path,
progress_cb,
overwrite,
resume
) =>
ops.download_file(
conn,
remote_path,
local_path,
progress_cb,
overwrite,
resume
),
exists: async (remote_path) => {
try {
const info = await ops.get_file_attributes2(conn, remote_path);
return !info.directory;
} catch (e) {
if (e.message.split(':')[1].trim() == '-2') {
return false;
}
throw new Error(e.message);
}
},
open: async (remote_path) =>
new file(conn, await ops.open_file(conn, remote_path), remote_path),
remove: async (remote_path) => ops.remove_file(conn, remote_path),
upload: async (local_path, remote_path, progress_cb, overwrite, resume) =>
ops.upload_file(
conn,
local_path,
remote_path,
progress_cb,
overwrite,
resume
),
},
get_drive_information: async () => ops.get_drive_information(conn),
};
};
export const create_pool = async (pool_size, host_or_ip, port, password) => {
if (pool_size <= 1) {
return connect(host_or_ip, port, password);
}
return new connection_pool(pool_size, host_or_ip, port, password);
};
import file from './io/file';
import connection from './networking/connection';
import connection_pool from './networking/connection_pool';
import * as ops from './ops';
export * as byte_order from './utils/byte_order';
export { getCustomEncryption, setCustomEncryption } from './utils/constants';
export { default as packet } from './networking/packet';
export const connect = async (host_or_ip, port, password) => {
const conn = new connection(host_or_ip, port, password);
await conn.connect();
return conn;
};
export const create_api = (conn) => {
return {
directory: {
create: async (remote_path) => ops.create_directory(conn, remote_path),
exists: async (remote_path) => {
try {
const info = await ops.get_file_attributes2(conn, remote_path);
return info.directory;
} catch (e) {
if (e.message.split(':')[1].trim() == '-2') {
return false;
}
throw new Error(e.message);
}
},
list: async (remote_path, page_reader_cb) =>
ops.list_directory(conn, remote_path, page_reader_cb),
remove: async (remote_path) => ops.remove_directory(conn, remote_path),
snapshot: async (remote_path) => {
return ops.snapshot_directory(conn, remote_path);
},
},
file: {
create_or_open: async (remote_path) =>
new file(
conn,
await ops.create_or_open_file(conn, remote_path),
remote_path
),
download: async (
remote_path,
local_path,
progress_cb,
overwrite,
resume
) =>
ops.download_file(
conn,
remote_path,
local_path,
progress_cb,
overwrite,
resume
),
exists: async (remote_path) => {
try {
const info = await ops.get_file_attributes2(conn, remote_path);
return !info.directory;
} catch (e) {
if (e.message.split(':')[1].trim() == '-2') {
return false;
}
throw new Error(e.message);
}
},
open: async (remote_path) =>
new file(conn, await ops.open_file(conn, remote_path), remote_path),
remove: async (remote_path) => ops.remove_file(conn, remote_path),
upload: async (local_path, remote_path, progress_cb, overwrite, resume) =>
ops.upload_file(
conn,
local_path,
remote_path,
progress_cb,
overwrite,
resume
),
},
get_drive_information: async () => ops.get_drive_information(conn),
};
};
export const create_pool = async (pool_size, host_or_ip, port, password) => {
if (pool_size <= 1) {
return connect(host_or_ip, port, password);
}
return new connection_pool(pool_size, host_or_ip, port, password);
};

View File

@@ -1,108 +1,108 @@
import * as ops from '../ops';
let next_thread_id = 1;
export default class file {
constructor(conn, handle, remote_path) {
this.conn = conn;
this.handle = handle || null;
this.remote_path = remote_path;
this.thread_id = next_thread_id++;
}
conn;
handle = null;
thread_id;
remote_path;
async close() {
if (this.handle !== null) {
const result = await ops.close_file(
this.conn,
this.remote_path,
this.handle,
this.thread_id
);
if (result === 0) {
this.handle = null;
}
return result;
}
return 0;
}
async get_size() {
if (this.handle === null) {
return Promise.reject(new Error("'get_size()' failed: invalid handle"));
}
const attrs = await ops.get_file_attributes(
this.conn,
this.handle,
this.remote_path,
this.thread_id
);
return attrs.size;
}
async read(offset, length) {
if (this.handle === null) {
return Promise.reject(new Error("'read()' failed: invalid handle"));
}
return ops.read_file(
this.conn,
this.handle,
this.remote_path,
offset,
length,
this.thread_id
);
}
async truncate(length) {
if (this.handle === null) {
return Promise.reject(new Error("'truncate()' failed: invalid handle"));
}
return ops.truncate_file(
this.conn,
this.handle,
this.remote_path,
length,
this.thread_id
);
}
async write(offset, buffer) {
if (this.handle === null) {
return Promise.reject(new Error("'write()' failed: invalid handle"));
}
return ops.write_file(
this.conn,
this.handle,
this.remote_path,
offset,
buffer,
this.thread_id
);
}
async write_base64(offset, base64_string) {
if (this.handle === null) {
return Promise.reject(
new Error("'write_base64()' failed: invalid handle")
);
}
return ops.write_base64_file(
this.conn,
this.handle,
this.remote_path,
offset,
base64_string,
this.thread_id
);
}
}
import * as ops from '../ops';
let next_thread_id = 1;
export default class file {
constructor(conn, handle, remote_path) {
this.conn = conn;
this.handle = handle || null;
this.remote_path = remote_path;
this.thread_id = next_thread_id++;
}
conn;
handle = null;
thread_id;
remote_path;
async close() {
if (this.handle !== null) {
const result = await ops.close_file(
this.conn,
this.remote_path,
this.handle,
this.thread_id
);
if (result === 0) {
this.handle = null;
}
return result;
}
return 0;
}
async get_size() {
if (this.handle === null) {
return Promise.reject(new Error("'get_size()' failed: invalid handle"));
}
const attrs = await ops.get_file_attributes(
this.conn,
this.handle,
this.remote_path,
this.thread_id
);
return attrs.size;
}
async read(offset, length) {
if (this.handle === null) {
return Promise.reject(new Error("'read()' failed: invalid handle"));
}
return ops.read_file(
this.conn,
this.handle,
this.remote_path,
offset,
length,
this.thread_id
);
}
async truncate(length) {
if (this.handle === null) {
return Promise.reject(new Error("'truncate()' failed: invalid handle"));
}
return ops.truncate_file(
this.conn,
this.handle,
this.remote_path,
length,
this.thread_id
);
}
async write(offset, buffer) {
if (this.handle === null) {
return Promise.reject(new Error("'write()' failed: invalid handle"));
}
return ops.write_file(
this.conn,
this.handle,
this.remote_path,
offset,
buffer,
this.thread_id
);
}
async write_base64(offset, base64_string) {
if (this.handle === null) {
return Promise.reject(
new Error("'write_base64()' failed: invalid handle")
);
}
return ops.write_base64_file(
this.conn,
this.handle,
this.remote_path,
offset,
base64_string,
this.thread_id
);
}
}

View File

@@ -1,172 +1,177 @@
import Socket from 'net';
import * as constants from '../utils/constants';
import packet from './packet';
export default class connection {
constructor(host_or_ip, port, password, socket) {
this.host_or_ip = host_or_ip;
this.port = port;
this.password = password;
if (socket) {
this.socket = socket;
this.connected = true;
this.setup_socket();
}
}
connected = false;
host_or_ip = '';
password = '';
port = 20000;
reject;
resolve;
socket;
cleanup_handlers() {
this.reject = null;
this.resolve = null;
}
async connect() {
if (!this.socket) {
try {
await new Promise((resolve, reject) => {
this.socket = Socket.createConnection(
this.port,
this.host_or_ip,
(err) => {
if (err) {
console.log(err);
return reject(err);
}
return resolve();
}
);
});
} catch (err) {
return Promise.reject(new Error(`'connect()' failed: ${err}`));
}
this.connected = true;
this.setup_socket();
}
}
setup_socket() {
let buffer;
const cleanup = () => {
this.cleanup_handlers();
buffer = null;
};
if (this.socket._socket) {
this.socket._socket.setNoDelay(true);
this.socket._socket.setKeepAlive(true);
} else {
this.socket.setNoDelay(true);
this.socket.setKeepAlive(true);
}
this.socket.on('data', (chunk) => {
buffer = buffer ? Buffer.concat([buffer, chunk]) : chunk;
if (buffer.length > 4) {
const size = buffer.readUInt32BE(0);
if (buffer.length >= size + 4) {
const packet_data = buffer.slice(4, 4 + size);
if (this.resolve) {
const complete = () => {
const reject = this.reject;
const resolve = this.resolve;
cleanup();
return {
reject,
resolve,
};
};
const response = new packet(this.password);
response.buffer = new Uint8Array(packet_data);
response
.decrypt()
.then(() => {
const { resolve } = complete();
if (resolve) {
resolve(response);
}
})
.catch((e) => {
console.log(e);
const { reject } = complete();
if (reject) {
reject(e);
}
});
}
}
}
});
this.socket.on('error', (e) => {
if (this.reject) {
const reject = this.reject;
cleanup();
this.connected = false;
console.log(e);
if (reject) {
reject(e);
}
}
});
this.socket.on('close', () => {
if (this.reject) {
const reject = this.reject;
cleanup();
this.connected = false;
console.log('socket closed');
if (reject) {
reject(new Error('socket closed'));
}
}
});
}
async disconnect() {
try {
if (this.socket) {
this.socket.destroy();
this.socket = null;
this.cleanup_handlers();
this.connected = false;
}
} catch (e) {
console.log(e);
}
}
async send(method_name, packet, optional_thread_id) {
packet.token = this.password;
packet.encode_top_utf8(method_name);
packet.encode_top_ui64(optional_thread_id || 1);
packet.encode_top_utf8(constants.instance_id);
packet.encode_top_ui32(0); // Service flags
packet.encode_top_utf8(constants.get_version());
await packet.encrypt();
packet.encode_top_ui32(packet.buffer.length);
return new Promise((resolve, reject) => {
this.reject = reject;
this.resolve = resolve;
this.socket.write(Buffer.from(packet.buffer), null, (err) => {
if (err) {
this.cleanup_handlers();
reject(err);
}
});
});
}
}
import Socket from 'net';
import * as constants from '../utils/constants';
import packet from './packet';
export default class connection {
constructor(host_or_ip, port, password, socket) {
this.host_or_ip = host_or_ip;
this.port = port;
this.password = password;
if (socket) {
this.socket = socket;
this.connected = true;
this.setup_socket();
}
}
connected = false;
host_or_ip = '';
nonce = '';
password = '';
port = 20000;
reject;
resolve;
socket;
cleanup_handlers() {
this.reject = null;
this.resolve = null;
}
async connect() {
if (!this.socket) {
try {
await new Promise((resolve, reject) => {
this.socket = Socket.createConnection(
this.port,
this.host_or_ip,
(err) => {
if (err) {
console.log(err);
return reject(err);
}
this.reject = reject;
this.resolve = resolve;
}
);
});
} catch (err) {
return Promise.reject(new Error(`'connect()' failed: ${err}`));
}
this.connected = true;
this.setup_socket();
}
}
setup_socket() {
let buffer;
const cleanup = () => {
this.cleanup_handlers();
buffer = null;
};
if (this.socket._socket) {
this.socket._socket.setNoDelay(true);
this.socket._socket.setKeepAlive(true);
} else {
this.socket.setNoDelay(true);
this.socket.setKeepAlive(true);
}
this.socket.on('data', (chunk) => {
buffer = buffer ? Buffer.concat([buffer, chunk]) : chunk;
if (buffer.length > 4) {
const size = buffer.readUInt32BE(0);
if (buffer.length >= size + 4) {
const packet_data = buffer.slice(4, 4 + size);
if (this.resolve) {
const complete = () => {
const reject = this.reject;
const resolve = this.resolve;
cleanup();
return {
reject,
resolve,
};
};
const response = new packet(this.password);
response.buffer = new Uint8Array(packet_data);
response
.decrypt()
.then(() => {
this.nonce = response.decode_utf8();
const { resolve } = complete();
if (resolve) {
resolve(response);
}
})
.catch((e) => {
console.log(e);
const { reject } = complete();
if (reject) {
reject(e);
}
});
}
}
}
});
this.socket.on('error', (e) => {
if (this.reject) {
const reject = this.reject;
cleanup();
this.connected = false;
console.log(e);
if (reject) {
reject(e);
}
}
});
this.socket.on('close', () => {
if (this.reject) {
const reject = this.reject;
cleanup();
this.connected = false;
console.log('socket closed');
if (reject) {
reject(new Error('socket closed'));
}
}
});
}
async disconnect() {
try {
if (this.socket) {
this.socket.destroy();
this.socket = null;
this.cleanup_handlers();
this.connected = false;
}
} catch (e) {
console.log(e);
}
}
async send(method_name, packet, optional_thread_id) {
packet.token = this.password;
packet.encode_top_utf8(method_name);
packet.encode_top_ui64(optional_thread_id || 1);
packet.encode_top_utf8(constants.instance_id);
packet.encode_top_ui32(0); // Service flags
packet.encode_top_utf8(constants.get_version());
packet.encode_top_utf8(nonce);
await packet.encrypt();
packet.encode_top_ui32(packet.buffer.length);
return new Promise((resolve, reject) => {
this.reject = reject;
this.resolve = resolve;
this.socket.write(Buffer.from(packet.buffer), null, (err) => {
if (err) {
this.cleanup_handlers();
reject(err);
}
});
});
}
}

View File

@@ -1,69 +1,69 @@
import Pool from 'socket-pool';
import connection from './connection';
export default class connection_pool {
constructor(pool_size, host_or_ip, port, password) {
this.host_or_ip = host_or_ip;
this.port = port;
this.password = password;
if (pool_size > 1) {
this.pool = new Pool({
connect: { host: host_or_ip, port: port },
connectTimeout: 5000,
pool: { max: pool_size, min: 2 },
});
} else {
throw new Error("'pool_size' must be > 1");
}
}
host_or_ip = '';
next_thread_id = 1;
password = '';
port = 20000;
pool;
shutdown = false;
async disconnect() {
await this.pool._pool.drain();
await this.pool._pool.clear();
this.pool = null;
this.shutdown = true;
}
async send(method_name, packet, optional_thread_id) {
try {
const socket = await this.pool.acquire();
if (!socket.thread_id) {
socket.thread_id = this.next_thread_id++;
}
const cleanup = () => {
try {
socket.release();
} catch (err) {
console.log(`'release()' failed: ${err}`);
}
};
try {
const result = await new connection(
this.host_or_ip,
this.port,
this.password,
socket
).send(method_name, packet, optional_thread_id || socket.thread_id);
cleanup();
return result;
} catch (err) {
cleanup();
return Promise.reject(
new Error(`'send(${method_name})' failed: ${err}`)
);
}
} catch (err) {
return Promise.reject(new Error(`'acquire()' socket failed: ${err}`));
}
}
}
import Pool from 'socket-pool';
import connection from './connection';
export default class connection_pool {
constructor(pool_size, host_or_ip, port, password) {
this.host_or_ip = host_or_ip;
this.port = port;
this.password = password;
if (pool_size > 1) {
this.pool = new Pool({
connect: { host: host_or_ip, port: port },
connectTimeout: 5000,
pool: { max: pool_size, min: 2 },
});
} else {
throw new Error("'pool_size' must be > 1");
}
}
host_or_ip = '';
next_thread_id = 1;
password = '';
port = 20000;
pool;
shutdown = false;
async disconnect() {
await this.pool._pool.drain();
await this.pool._pool.clear();
this.pool = null;
this.shutdown = true;
}
async send(method_name, packet, optional_thread_id) {
try {
const socket = await this.pool.acquire();
if (!socket.thread_id) {
socket.thread_id = this.next_thread_id++;
}
const cleanup = () => {
try {
socket.release();
} catch (err) {
console.log(`'release()' failed: ${err}`);
}
};
try {
const result = await new connection(
this.host_or_ip,
this.port,
this.password,
socket
).send(method_name, packet, optional_thread_id || socket.thread_id);
cleanup();
return result;
} catch (err) {
cleanup();
return Promise.reject(
new Error(`'send(${method_name})' failed: ${err}`)
);
}
} catch (err) {
return Promise.reject(new Error(`'acquire()' socket failed: ${err}`));
}
}
}

View File

@@ -1,330 +1,330 @@
import { randomBytes } from 'crypto';
import { Int64BE, Uint64BE } from 'int64-buffer';
import crypto from 'crypto';
import { TextEncoder } from 'text-encoding';
import { getCustomEncryption } from '../utils/constants';
import {
be_ui8_array_to_i16,
be_ui8_array_to_i32,
be_ui8_array_to_ui16,
be_ui8_array_to_ui32,
i16_to_be_ui8_array,
i32_to_be_ui8_array,
i8_to_ui8_array,
ui16_to_be_ui8_array,
ui32_to_be_ui8_array,
ui8_array_to_i8,
ui8_array_to_ui8,
ui8_to_ui8_array,
} from '../utils/byte_order';
import { XChaCha20Poly1305 } from '@stablelib/xchacha20poly1305';
export default class packet {
constructor(token) {
this.token = token;
}
buffer = new Uint8Array(0);
decode_offset = 0;
token;
append_buffer = (buffer) => {
if (!(buffer instanceof Uint8Array)) {
throw new Error('Buffer must be of type Uint8Array');
}
this.buffer = this.buffer
? new Uint8Array([...this.buffer, ...buffer])
: buffer;
};
clear = () => {
this.buffer = null;
this.decode_offset = 0;
};
decode_buffer = (length) => {
if (!this.buffer) {
throw new Error('Invalid buffer');
}
const ret = this.buffer.slice(
this.decode_offset,
this.decode_offset + length
);
this.decode_offset += length;
return Buffer.from(ret);
};
decode_stat = () => {
const mode = this.decode_ui16();
const nlink = this.decode_ui16();
const uid = this.decode_ui32();
const gid = this.decode_ui32();
const atime = this.decode_ui64();
const mtime = this.decode_ui64();
const ctime = this.decode_ui64();
const birth_time = this.decode_ui64();
const size = this.decode_ui64();
const blocks = this.decode_ui64();
const blksize = this.decode_ui32();
const flags = this.decode_ui32();
const directory = !!this.decode_ui8();
return {
mode,
nlink,
uid,
gid,
atime,
mtime,
ctime,
birth_time,
size,
blocks,
blksize,
flags,
directory,
};
};
decode_utf8 = () => {
if (!this.buffer) {
throw new Error('Invalid buffer');
}
const startIndex = this.decode_offset;
const endIndex = this.buffer.indexOf(0, startIndex);
if (endIndex >= 0) {
let ret = '';
for (let i = startIndex; i < endIndex; i++) {
ret += String.fromCharCode(this.buffer[i]);
}
this.decode_offset = endIndex + 1;
return ret;
}
throw new Error('String not found in buffer');
};
decode_i8 = () => {
return ui8_array_to_i8(this.buffer, this.decode_offset++);
};
decode_ui8 = () => {
return ui8_array_to_ui8(this.buffer, this.decode_offset++);
};
decode_i16 = () => {
const ret = be_ui8_array_to_i16(this.buffer, this.decode_offset);
this.decode_offset += 2;
return ret;
};
decode_ui16 = () => {
const ret = be_ui8_array_to_ui16(this.buffer, this.decode_offset);
this.decode_offset += 2;
return ret;
};
decode_i32 = () => {
const ret = be_ui8_array_to_i32(this.buffer, this.decode_offset);
this.decode_offset += 4;
return ret;
};
decode_ui32 = () => {
const ret = be_ui8_array_to_ui32(this.buffer, this.decode_offset);
this.decode_offset += 4;
return ret;
};
decode_i64 = () => {
const ret = new Int64BE(
this.buffer.slice(this.decode_offset, this.decode_offset + 8)
);
this.decode_offset += 8;
return ret.toString(10);
};
decode_ui64 = () => {
const ret = new Uint64BE(
this.buffer.slice(this.decode_offset, this.decode_offset + 8)
);
this.decode_offset += 8;
return ret.toString(10);
};
decrypt = async () => {
try {
let hash = crypto.createHash('sha256');
hash = hash.update(new TextEncoder().encode(this.token));
const key = Uint8Array.from(hash.digest());
const nonce = this.buffer.slice(0, 24);
const mac = this.buffer.slice(24, 16 + 24);
const customEncryption = getCustomEncryption();
if (customEncryption) {
this.buffer = Buffer.from(
await customEncryption.decrypt(
Buffer.from(key).toString('base64'),
Buffer.from(nonce).toString('base64'),
Buffer.from(mac).toString('base64'),
Buffer.from(this.buffer.slice(40)).toString('base64')
),
'base64'
);
} else {
const aad = ui32_to_be_ui8_array(this.buffer.length);
this.buffer = new Uint8Array([
...this.buffer.slice(nonce.length + mac.length),
...this.buffer.slice(nonce.length, nonce.length + mac.length),
]);
const result = new XChaCha20Poly1305(key).open(nonce, this.buffer, aad);
if (!result) {
throw new Error('decryption failed');
}
this.buffer = Buffer.from(result);
}
this.buffer = new Uint8Array(this.buffer);
return this.buffer;
} catch (e) {
return Promise.reject(e);
}
};
encode_buffer = (buffer) => {
this.append_buffer(new Uint8Array(buffer));
};
encode_i8 = (num) => {
this.append_buffer(i8_to_ui8_array(num));
};
encode_top_i8 = (num) => {
this.push_buffer(i8_to_ui8_array(num));
};
encode_u8 = (num) => {
this.append_buffer(ui8_to_ui8_array(num));
};
encode_top_u8 = (num) => {
this.push_buffer(ui8_to_ui8_array(num));
};
encode_i16 = (num) => {
this.append_buffer(i16_to_be_ui8_array(num));
};
encode_top_i16 = (num) => {
this.push_buffer(i16_to_be_ui8_array(num));
};
encode_ui16 = (num) => {
this.append_buffer(ui16_to_be_ui8_array(num));
};
encode_top_ui16 = (num) => {
this.push_buffer(ui16_to_be_ui8_array(num));
};
encode_i32 = (num) => {
this.append_buffer(i32_to_be_ui8_array(num));
};
encode_top_i32 = (num) => {
this.push_buffer(i32_to_be_ui8_array(num));
};
encode_ui32 = (num) => {
this.append_buffer(ui32_to_be_ui8_array(num));
};
encode_top_ui32 = (num) => {
this.push_buffer(ui32_to_be_ui8_array(num));
};
encode_i64 = (num) => {
this.append_buffer(new Uint8Array(new Int64BE(num).toArray()));
};
encode_top_i64 = (num) => {
this.push_buffer(new Uint8Array(new Int64BE(num).toArray()));
};
encode_ui64 = (num) => {
this.append_buffer(new Uint8Array(new Uint64BE(num).toArray()));
};
encode_top_ui64 = (num) => {
this.push_buffer(new Uint8Array(new Uint64BE(num).toArray()));
};
encode_utf8 = (str) => {
if (!(typeof str === 'string' || str instanceof String)) {
throw new Error('Value must be of type string');
}
const buffer = new Uint8Array([...new TextEncoder().encode(str), 0]);
this.append_buffer(buffer);
};
encode_top_utf8 = (str) => {
if (!(typeof str === 'string' || str instanceof String)) {
throw new Error('Value must be of type string');
}
const buffer = new Uint8Array([...new TextEncoder().encode(str), 0]);
this.push_buffer(buffer);
};
encrypt = async (nonce) => {
try {
let hash = crypto.createHash('sha256');
hash = hash.update(new TextEncoder().encode(this.token));
const key = Uint8Array.from(hash.digest());
if (!nonce) {
nonce = Uint8Array.from(randomBytes(24));
}
const customEncryption = getCustomEncryption();
if (customEncryption) {
this.buffer = new Uint8Array(
Buffer.from(
await customEncryption.encrypt(
Buffer.from(key).toString('base64'),
Buffer.from(nonce).toString('base64'),
Buffer.from(this.buffer).toString('base64')
),
'base64'
)
);
} else {
const aad = ui32_to_be_ui8_array(this.buffer.length + 40);
this.buffer = new XChaCha20Poly1305(key).seal(nonce, this.buffer, aad);
this.buffer = new Uint8Array([
...this.buffer.slice(this.buffer.length - 16),
...this.buffer.slice(0, this.buffer.length - 16),
]);
this.push_buffer(nonce);
}
return this.buffer;
} catch (e) {
return Promise.reject(e);
}
};
push_buffer = (buffer) => {
if (!(buffer instanceof Uint8Array)) {
throw new Error('Buffer must be of type Uint8Array');
}
this.buffer = this.buffer
? new Uint8Array([...buffer, ...this.buffer])
: buffer;
};
}
import { randomBytes } from 'crypto';
import { Int64BE, Uint64BE } from 'int64-buffer';
import crypto from 'crypto';
import { TextEncoder } from 'text-encoding';
import { getCustomEncryption } from '../utils/constants';
import {
be_ui8_array_to_i16,
be_ui8_array_to_i32,
be_ui8_array_to_ui16,
be_ui8_array_to_ui32,
i16_to_be_ui8_array,
i32_to_be_ui8_array,
i8_to_ui8_array,
ui16_to_be_ui8_array,
ui32_to_be_ui8_array,
ui8_array_to_i8,
ui8_array_to_ui8,
ui8_to_ui8_array,
} from '../utils/byte_order';
import { XChaCha20Poly1305 } from '@stablelib/xchacha20poly1305';
export default class packet {
constructor(token) {
this.token = token;
}
buffer = new Uint8Array(0);
decode_offset = 0;
token;
append_buffer = (buffer) => {
if (!(buffer instanceof Uint8Array)) {
throw new Error('Buffer must be of type Uint8Array');
}
this.buffer = this.buffer
? new Uint8Array([...this.buffer, ...buffer])
: buffer;
};
clear = () => {
this.buffer = null;
this.decode_offset = 0;
};
decode_buffer = (length) => {
if (!this.buffer) {
throw new Error('Invalid buffer');
}
const ret = this.buffer.slice(
this.decode_offset,
this.decode_offset + length
);
this.decode_offset += length;
return Buffer.from(ret);
};
decode_stat = () => {
const mode = this.decode_ui16();
const nlink = this.decode_ui16();
const uid = this.decode_ui32();
const gid = this.decode_ui32();
const atime = this.decode_ui64();
const mtime = this.decode_ui64();
const ctime = this.decode_ui64();
const birth_time = this.decode_ui64();
const size = this.decode_ui64();
const blocks = this.decode_ui64();
const blksize = this.decode_ui32();
const flags = this.decode_ui32();
const directory = !!this.decode_ui8();
return {
mode,
nlink,
uid,
gid,
atime,
mtime,
ctime,
birth_time,
size,
blocks,
blksize,
flags,
directory,
};
};
decode_utf8 = () => {
if (!this.buffer) {
throw new Error('Invalid buffer');
}
const startIndex = this.decode_offset;
const endIndex = this.buffer.indexOf(0, startIndex);
if (endIndex >= 0) {
let ret = '';
for (let i = startIndex; i < endIndex; i++) {
ret += String.fromCharCode(this.buffer[i]);
}
this.decode_offset = endIndex + 1;
return ret;
}
throw new Error('String not found in buffer');
};
decode_i8 = () => {
return ui8_array_to_i8(this.buffer, this.decode_offset++);
};
decode_ui8 = () => {
return ui8_array_to_ui8(this.buffer, this.decode_offset++);
};
decode_i16 = () => {
const ret = be_ui8_array_to_i16(this.buffer, this.decode_offset);
this.decode_offset += 2;
return ret;
};
decode_ui16 = () => {
const ret = be_ui8_array_to_ui16(this.buffer, this.decode_offset);
this.decode_offset += 2;
return ret;
};
decode_i32 = () => {
const ret = be_ui8_array_to_i32(this.buffer, this.decode_offset);
this.decode_offset += 4;
return ret;
};
decode_ui32 = () => {
const ret = be_ui8_array_to_ui32(this.buffer, this.decode_offset);
this.decode_offset += 4;
return ret;
};
decode_i64 = () => {
const ret = new Int64BE(
this.buffer.slice(this.decode_offset, this.decode_offset + 8)
);
this.decode_offset += 8;
return ret.toString(10);
};
decode_ui64 = () => {
const ret = new Uint64BE(
this.buffer.slice(this.decode_offset, this.decode_offset + 8)
);
this.decode_offset += 8;
return ret.toString(10);
};
decrypt = async () => {
try {
let hash = crypto.createHash('sha256');
hash = hash.update(new TextEncoder().encode(this.token));
const key = Uint8Array.from(hash.digest());
const nonce = this.buffer.slice(0, 24);
const mac = this.buffer.slice(24, 16 + 24);
const customEncryption = getCustomEncryption();
if (customEncryption) {
this.buffer = Buffer.from(
await customEncryption.decrypt(
Buffer.from(key).toString('base64'),
Buffer.from(nonce).toString('base64'),
Buffer.from(mac).toString('base64'),
Buffer.from(this.buffer.slice(40)).toString('base64')
),
'base64'
);
} else {
const aad = ui32_to_be_ui8_array(this.buffer.length);
this.buffer = new Uint8Array([
...this.buffer.slice(nonce.length + mac.length),
...this.buffer.slice(nonce.length, nonce.length + mac.length),
]);
const result = new XChaCha20Poly1305(key).open(nonce, this.buffer, aad);
if (!result) {
throw new Error('decryption failed');
}
this.buffer = Buffer.from(result);
}
this.buffer = new Uint8Array(this.buffer);
return this.buffer;
} catch (e) {
return Promise.reject(e);
}
};
encode_buffer = (buffer) => {
this.append_buffer(new Uint8Array(buffer));
};
encode_i8 = (num) => {
this.append_buffer(i8_to_ui8_array(num));
};
encode_top_i8 = (num) => {
this.push_buffer(i8_to_ui8_array(num));
};
encode_u8 = (num) => {
this.append_buffer(ui8_to_ui8_array(num));
};
encode_top_u8 = (num) => {
this.push_buffer(ui8_to_ui8_array(num));
};
encode_i16 = (num) => {
this.append_buffer(i16_to_be_ui8_array(num));
};
encode_top_i16 = (num) => {
this.push_buffer(i16_to_be_ui8_array(num));
};
encode_ui16 = (num) => {
this.append_buffer(ui16_to_be_ui8_array(num));
};
encode_top_ui16 = (num) => {
this.push_buffer(ui16_to_be_ui8_array(num));
};
encode_i32 = (num) => {
this.append_buffer(i32_to_be_ui8_array(num));
};
encode_top_i32 = (num) => {
this.push_buffer(i32_to_be_ui8_array(num));
};
encode_ui32 = (num) => {
this.append_buffer(ui32_to_be_ui8_array(num));
};
encode_top_ui32 = (num) => {
this.push_buffer(ui32_to_be_ui8_array(num));
};
encode_i64 = (num) => {
this.append_buffer(new Uint8Array(new Int64BE(num).toArray()));
};
encode_top_i64 = (num) => {
this.push_buffer(new Uint8Array(new Int64BE(num).toArray()));
};
encode_ui64 = (num) => {
this.append_buffer(new Uint8Array(new Uint64BE(num).toArray()));
};
encode_top_ui64 = (num) => {
this.push_buffer(new Uint8Array(new Uint64BE(num).toArray()));
};
encode_utf8 = (str) => {
if (!(typeof str === 'string' || str instanceof String)) {
throw new Error('Value must be of type string');
}
const buffer = new Uint8Array([...new TextEncoder().encode(str), 0]);
this.append_buffer(buffer);
};
encode_top_utf8 = (str) => {
if (!(typeof str === 'string' || str instanceof String)) {
throw new Error('Value must be of type string');
}
const buffer = new Uint8Array([...new TextEncoder().encode(str), 0]);
this.push_buffer(buffer);
};
encrypt = async (nonce) => {
try {
let hash = crypto.createHash('sha256');
hash = hash.update(new TextEncoder().encode(this.token));
const key = Uint8Array.from(hash.digest());
if (!nonce) {
nonce = Uint8Array.from(randomBytes(24));
}
const customEncryption = getCustomEncryption();
if (customEncryption) {
this.buffer = new Uint8Array(
Buffer.from(
await customEncryption.encrypt(
Buffer.from(key).toString('base64'),
Buffer.from(nonce).toString('base64'),
Buffer.from(this.buffer).toString('base64')
),
'base64'
)
);
} else {
const aad = ui32_to_be_ui8_array(this.buffer.length + 40);
this.buffer = new XChaCha20Poly1305(key).seal(nonce, this.buffer, aad);
this.buffer = new Uint8Array([
...this.buffer.slice(this.buffer.length - 16),
...this.buffer.slice(0, this.buffer.length - 16),
]);
this.push_buffer(nonce);
}
return this.buffer;
} catch (e) {
return Promise.reject(e);
}
};
push_buffer = (buffer) => {
if (!(buffer instanceof Uint8Array)) {
throw new Error('Buffer must be of type Uint8Array');
}
this.buffer = this.buffer
? new Uint8Array([...buffer, ...this.buffer])
: buffer;
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,112 +1,112 @@
export const is_big_endian_system =
new Uint8Array(new Uint32Array([0x12345678]).buffer)[0] === 0x12;
export const is_little_endian_system =
new Uint8Array(new Uint32Array([0x12345678]).buffer)[0] === 0x78;
export const i8_to_ui8_array = (num) => {
if (typeof num === 'string' || num instanceof String) {
num = parseInt(num, 10);
}
const buffer = Buffer.alloc(1);
buffer.writeInt8(num);
return new Uint8Array(buffer);
};
export const ui8_array_to_i8 = (ar, offset) => {
const buffer = Buffer.alloc(1);
buffer[0] = ar[offset];
return buffer.readInt8(0);
};
export const ui8_to_ui8_array = (num) => {
if (typeof num === 'string' || num instanceof String) {
num = parseInt(num, 10);
}
const buffer = Buffer.alloc(1);
buffer.writeUInt8(num);
return new Uint8Array(buffer);
};
export const ui8_array_to_ui8 = (ar, offset) => {
const buffer = Buffer.alloc(1);
buffer[0] = ar[offset];
return buffer.readUInt8(0);
};
export const i16_to_be_ui8_array = (num) => {
if (typeof num === 'string' || num instanceof String) {
num = parseInt(num, 10);
}
const buffer = Buffer.alloc(2);
buffer.writeInt16BE(num);
return new Uint8Array(buffer);
};
export const be_ui8_array_to_i16 = (ar, offset) => {
const buffer = Buffer.alloc(2);
for (let i = offset; i < buffer.length + offset; i++) {
buffer[i - offset] = ar[i];
}
return buffer.readInt16BE(0);
};
export const ui16_to_be_ui8_array = (num) => {
if (typeof num === 'string' || num instanceof String) {
num = parseInt(num, 10);
}
const buffer = Buffer.alloc(2);
buffer.writeUInt16BE(num);
return new Uint8Array(buffer);
};
export const be_ui8_array_to_ui16 = (ar, offset) => {
const buffer = Buffer.alloc(2);
for (let i = offset; i < buffer.length + offset; i++) {
buffer[i - offset] = ar[i];
}
return buffer.readUInt16BE(0);
};
export const i32_to_be_ui8_array = (num) => {
if (typeof num === 'string' || num instanceof String) {
num = parseInt(num, 10);
}
const buffer = Buffer.alloc(4);
buffer.writeInt32BE(num);
return new Uint8Array(buffer);
};
export const be_ui8_array_to_i32 = (ar, offset) => {
const buffer = Buffer.alloc(4);
for (let i = offset; i < buffer.length + offset; i++) {
buffer[i - offset] = ar[i];
}
return buffer.readInt32BE(0);
};
export const ui32_to_be_ui8_array = (num) => {
if (typeof num === 'string' || num instanceof String) {
num = parseInt(num, 10);
}
const buffer = Buffer.alloc(4);
buffer.writeUInt32BE(num);
return new Uint8Array(buffer);
};
export const be_ui8_array_to_ui32 = (ar, offset) => {
const buffer = Buffer.alloc(4);
for (let i = offset; i < buffer.length + offset; i++) {
buffer[i - offset] = ar[i];
}
return buffer.readUInt32BE(0);
};
export const is_big_endian_system =
new Uint8Array(new Uint32Array([0x12345678]).buffer)[0] === 0x12;
export const is_little_endian_system =
new Uint8Array(new Uint32Array([0x12345678]).buffer)[0] === 0x78;
export const i8_to_ui8_array = (num) => {
if (typeof num === 'string' || num instanceof String) {
num = parseInt(num, 10);
}
const buffer = Buffer.alloc(1);
buffer.writeInt8(num);
return new Uint8Array(buffer);
};
export const ui8_array_to_i8 = (ar, offset) => {
const buffer = Buffer.alloc(1);
buffer[0] = ar[offset];
return buffer.readInt8(0);
};
export const ui8_to_ui8_array = (num) => {
if (typeof num === 'string' || num instanceof String) {
num = parseInt(num, 10);
}
const buffer = Buffer.alloc(1);
buffer.writeUInt8(num);
return new Uint8Array(buffer);
};
export const ui8_array_to_ui8 = (ar, offset) => {
const buffer = Buffer.alloc(1);
buffer[0] = ar[offset];
return buffer.readUInt8(0);
};
export const i16_to_be_ui8_array = (num) => {
if (typeof num === 'string' || num instanceof String) {
num = parseInt(num, 10);
}
const buffer = Buffer.alloc(2);
buffer.writeInt16BE(num);
return new Uint8Array(buffer);
};
export const be_ui8_array_to_i16 = (ar, offset) => {
const buffer = Buffer.alloc(2);
for (let i = offset; i < buffer.length + offset; i++) {
buffer[i - offset] = ar[i];
}
return buffer.readInt16BE(0);
};
export const ui16_to_be_ui8_array = (num) => {
if (typeof num === 'string' || num instanceof String) {
num = parseInt(num, 10);
}
const buffer = Buffer.alloc(2);
buffer.writeUInt16BE(num);
return new Uint8Array(buffer);
};
export const be_ui8_array_to_ui16 = (ar, offset) => {
const buffer = Buffer.alloc(2);
for (let i = offset; i < buffer.length + offset; i++) {
buffer[i - offset] = ar[i];
}
return buffer.readUInt16BE(0);
};
export const i32_to_be_ui8_array = (num) => {
if (typeof num === 'string' || num instanceof String) {
num = parseInt(num, 10);
}
const buffer = Buffer.alloc(4);
buffer.writeInt32BE(num);
return new Uint8Array(buffer);
};
export const be_ui8_array_to_i32 = (ar, offset) => {
const buffer = Buffer.alloc(4);
for (let i = offset; i < buffer.length + offset; i++) {
buffer[i - offset] = ar[i];
}
return buffer.readInt32BE(0);
};
export const ui32_to_be_ui8_array = (num) => {
if (typeof num === 'string' || num instanceof String) {
num = parseInt(num, 10);
}
const buffer = Buffer.alloc(4);
buffer.writeUInt32BE(num);
return new Uint8Array(buffer);
};
export const be_ui8_array_to_ui32 = (ar, offset) => {
const buffer = Buffer.alloc(4);
for (let i = offset; i < buffer.length + offset; i++) {
buffer[i - offset] = ar[i];
}
return buffer.readUInt32BE(0);
};

View File

@@ -1,16 +1,16 @@
import { v4 as uuidv4 } from 'uuid';
import _package_json from '../../package.json';
let customEncryption;
export const getCustomEncryption = () => {
return customEncryption;
};
export const setCustomEncryption = (ce) => {
customEncryption = ce;
};
export const instance_id = uuidv4();
export const package_json = _package_json;
export const get_version = () => _package_json.version;
import { v4 as uuidv4 } from 'uuid';
import _package_json from '../../package.json';
let customEncryption;
export const getCustomEncryption = () => {
return customEncryption;
};
export const setCustomEncryption = (ce) => {
customEncryption = ce;
};
export const instance_id = uuidv4();
export const package_json = _package_json;
export const get_version = () => _package_json.version;