Skip to content

Instantly share code, notes, and snippets.

@tondrej
Created April 15, 2018 16:26
Show Gist options
  • Save tondrej/4457e3292129d9a1dd0c3ac526b1bfcc to your computer and use it in GitHub Desktop.
Save tondrej/4457e3292129d9a1dd0c3ac526b1bfcc to your computer and use it in GitHub Desktop.
FastText Pascal wrapper class for ChakraCore host
type
TFastTextObject = class(TNativeObject)
private
FCallback: JsValueRef;
FHandle: TFastText;
procedure NN2Callback(const Word: string; Score: Single);
protected
class procedure RegisterMethods(AInstance: JsHandle); override;
public
constructor Create; virtual;
destructor Destroy; override;
function JsNN2(Args: PJsValueRefArray; ArgCount: Word): JsValueRef;
end;
{ TFastTextObject }
function _nn2callback(word: PAnsiChar; score: Single; data: Pointer): LongBool; cdecl;
var
FastText: TFastTextObject absolute data;
begin
FastText.NN2Callback(word, score);
end;
constructor TFastTextObject.Create;
begin
inherited Create;
Win32Check(fasttext_new(FHandle));
end;
destructor TFastTextObject.Destroy;
begin
fasttext_release(FHandle);
inherited Destroy;
end;
function JsStringArrayToNativeArray(Value: JsValueRef; out P: PPAnsiChar): Boolean;
var
L, I: Integer;
Element: JsValueRef;
P2: PPAnsiChar;
S: AnsiString;
begin
Result := False;
P := nil;
if JsGetValueType(Value) <> JsArray then
Exit;
L := JsNumberToInt(JsGetProperty(Value, 'length'));
if L = 0 then
Exit;
P := AllocMem((L + 1) * SizeOf(PAnsiChar));
P2 := P;
for I := 0 to L - 1 do
begin
if JsGetIndexedProperty(Value, IntToJsNumber(I), Element) <> JsNoError then
Exit;
S := JsStringToUnicodeString(Element);
P2^ := StrNew(PAnsiChar(S));
Inc(P2);
end;
P2^ := nil;
Result := True;
end;
procedure ReleaseNativeArray(P: PPAnsiChar);
var
P2: PPAnsiChar;
begin
P2 := P;
while Assigned(P2) and Assigned(P2^) do
begin
StrDispose(P2^);
Inc(P2);
end;
FreeMem(P);
end;
function TFastTextObject.JsNN2(Args: PJsValueRefArray; ArgCount: Word): JsValueRef;
var
mx: NativeUInt;
Positive, Negative: PPAnsiChar;
Count: Integer;
begin
Result := JsUndefinedValue;
if ArgCount < 5 then
raise Exception.Create('Invalid NN2 arguments');
mx := JsNumberToInt(Args^[0]);
Positive := nil;
Negative := nil;
Count := JsNumberToInt(Args^[3]);
FCallback := Args^[4];
try
if not JsStringArrayToNativeArray(Args^[1], Positive) then
Exit;
JsStringArrayToNativeArray(Args^[2], Negative);
Win32Check(fasttext_nn2(FHandle, mx, Positive, Negative, Count, @_nn2callback, Self));
finally
ReleaseNativeArray(Negative);
ReleaseNativeArray(Positive);
FCallback := JsUndefinedValue;
end;
end;
procedure TFastTextObject.NN2Callback(const Word: string; Score: Single);
begin
Context.CallFunction(FCallback, [FCallback, StringToJsString(Word), DoubleToJsNumber(Score)]);
end;
class procedure TFastTextObject.RegisterMethods(AInstance: JsHandle);
begin
RegisterMethod(AInstance, 'nn2', @TFastTextObject.JsNN2);
end;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment