win32-def
Version:
win32 definitions for node-ffi
102 lines • 3.87 kB
JavaScript
/* eslint-disable @typescript-eslint/no-unnecessary-type-parameters */
import assert from 'node:assert';
import { LoaderCache } from './loader.cache.js';
export function createProxyMethod(options) {
const { name, fnDefRetType, fnDefCallParams, lib } = options;
const fnDefArgs = LoaderCache.getFnDefArgs(lib, name);
assert(fnDefArgs.length > 0, 'fnDefArgs.length <= 0');
const proxyFn = createKoffiFunctionLike({
name,
fnDefRetType,
fnDefCallParams,
funcSync: (...args) => createExecutionFn({ lib, name, args, type: 'sync' }),
funcAsync: (...args) => createExecutionFn({ lib, name, args, type: 'async' }),
});
return proxyFn;
}
function createExecutionFn(options) {
const { lib, name, args, type } = options;
// args includes the last callback function for async call
const pureArgs = type === 'async' ? args.slice(0, -1) : args;
const fnDefArgs = LoaderCache.getFnDefArgs(lib, name);
assert(fnDefArgs.length > 0, 'fnDefArgs.length <= 0');
const runtimeDefArgs = multipleChoiceMapperProcessor(lib, name, pureArgs);
const func = LoaderCache.getFuncByDefArgs(lib, name, runtimeDefArgs);
assert(typeof func === 'function', `Function ${name} not found in cache, For:
args: ${JSON.stringify(runtimeDefArgs)},
fnDefCallParamsExpanded: ${JSON.stringify(fnDefArgs)} `);
if (type === 'async') {
return func.async(...args);
}
else {
return func(...args);
}
}
function multipleChoiceMapperProcessor(lib, fnName, runtimeArgs) {
const fnDefCallParamsExpanded = LoaderCache.getFnDefArgs(lib, fnName);
assert(fnDefCallParamsExpanded.length > 0, 'fnDefArgs.length <= 0');
const mapperList = LoaderCache.getMultipleChoiceListMapperSet(lib, fnName);
assert(mapperList && mapperList.size > 0, `multiple choice mapper not found for ${fnName}. It's may not be set.`);
let matched;
for (const mapper of mapperList) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const res = mapper(fnName, runtimeArgs, fnDefCallParamsExpanded);
if (res) {
assert(Array.isArray(res), `mapper must return an array`);
assert(res.length > 0, `fnDefArgs not matched for ${fnName}.
matchArgs: none,
fnDefCallParamsExpanded: ${JSON.stringify(fnDefCallParamsExpanded)}`);
matched = res;
break;
}
// try next mapper if return undefined
}
assert(matched, `fnDefArgs not matched for ${fnName}.
Check if missing function fnDefArgs, like
EnumPrintersW: [D.BOOL,
[
D.DWORD,
D.String,
D.DWORD,
[\`_Out_ \${S.PPRINTER_INFO_1}\`, \`_Out_ \${S.PPRINTER_INFO_4}\`], <== missing PPRINTER_INFO_5
D.DWORD,
D.LPDWORD,
D.LPDWORD,
]],
.
`);
return matched;
}
function createKoffiFunctionLike(options) {
const { name, fnDefRetType, fnDefCallParams, funcSync, funcAsync } = options;
const info = {
name,
fnDefRetType,
fnDefCallParams,
};
Object.defineProperty(funcSync, 'info', {
value: info,
});
Object.defineProperty(funcSync, 'async', {
value: funcAsync,
});
return funcSync;
}
export function updateMultipleChoiceMapperToCache(options) {
const { lib, fnName, mapperSet, mapperList } = options;
if (mapperList?.size) {
LoaderCache.updateMultipleChoiceListMapper(lib, mapperList);
}
if (fnName && mapperSet?.size) {
const set = LoaderCache.getMultipleChoiceListMapperSet(lib, fnName);
if (set) {
for (const mapper of mapperSet) {
set.add(mapper);
}
}
else {
LoaderCache.updateMultipleChoiceListMapper(lib, new Map([[fnName, mapperSet]]));
}
}
}
//# sourceMappingURL=multiple-choice-param.helper.js.map