130 lines
4.3 KiB
ObjectPascal
130 lines
4.3 KiB
ObjectPascal
unit SyNodeReadWrite;
|
|
|
|
interface
|
|
|
|
uses
|
|
SpiderMonkey, Classes, SynCommons;
|
|
|
|
// TODO - replace this implemenattion by buffers whed buffers become fully compartible with nodeJS
|
|
|
|
/// Used for create JS method for writing data to internal class buffer
|
|
// JS syntax: write(data: ArrayBuffer|String|Object, [encoding: "utf-8"|"ucs2"|"bin"|"base64"]'
|
|
// inmplementation must provide TTextWriter to write data to
|
|
function SMWrite_impl(cx: PJSContext; argc: uintN; vals: PjsvalVector; dest: TTextWriter): jsval; cdecl;
|
|
/// Used for create JS method for reading data from internal class buffer (aStr)
|
|
// JS syntax: read([encoding=utf-8: "utf-8"|"ucs2"|"bin"|"base64"])
|
|
// implementation must provide TTextWriter to write data to
|
|
function SMRead_impl(cx: PJSContext; argc: uintN; vals: PjsvalVector; const aStr: RawByteString): jsval; cdecl;
|
|
|
|
implementation
|
|
|
|
{$ifdef MSWINDOWS}
|
|
uses
|
|
Windows; // CP_UTF8
|
|
{$endif}
|
|
|
|
function SMRead_impl(cx: PJSContext; argc: uintN; vals: PjsvalVector; const aStr: RawByteString): jsval; cdecl;
|
|
var
|
|
encoding: RawUTF8;
|
|
len: Integer;
|
|
bufObj: PJSObject;
|
|
bufData: pointer;
|
|
decodedStr: RawByteString;
|
|
begin
|
|
if (argc = 0) or ((argc=1) and vals[0].isVoid) then
|
|
encoding := 'utf-8'
|
|
else
|
|
encoding := LowerCase(vals[0].asJSString.ToUTF8(cx));
|
|
|
|
if encoding = 'utf-8' then begin
|
|
Result := cx.NewJSString(Pointer(aStr), length(aStr), CP_UTF8).ToJSVal
|
|
end else if encoding = 'Windows-1251' then begin
|
|
Result := cx.NewJSString(Pointer(aStr), length(aStr), 1251).ToJSVal
|
|
end else if encoding = 'ucs2' then begin
|
|
Result := cx.NewJSString(aStr).ToJSVal
|
|
end else if encoding = 'bin2base64' then begin
|
|
decodedStr := BinToBase64(aStr);
|
|
Result := cx.NewJSString(decodedStr).ToJSVal;
|
|
end else if (encoding = 'bin') or (encoding = 'base64') then begin
|
|
if encoding = 'base64' then
|
|
decodedStr := Base64ToBin(aStr)
|
|
else
|
|
decodedStr := aStr;
|
|
len := length(decodedStr);
|
|
bufObj := cx.NewArrayBuffer(len);
|
|
bufData := bufObj.GetArrayBufferData;
|
|
Move(pointer(decodedStr)^, bufData^, len);
|
|
Result := bufObj.ToJSValue;
|
|
end else
|
|
raise ESMException.Create('Invalid encoding');
|
|
end;
|
|
|
|
function SMWrite_impl(cx: PJSContext; argc: uintN; vals: PjsvalVector; dest: TTextWriter): jsval; cdecl;
|
|
var
|
|
encoding: RawUTF8;
|
|
len: uint32;
|
|
isShared: boolean;
|
|
bufObj: PJSObject;
|
|
bufData: Puint8Vector;
|
|
tmp1: RawByteString;
|
|
tmp2: SynUnicode;
|
|
begin
|
|
if (argc < 1) or (argc>2) then
|
|
raise ESMException.Create('Usage: write(data: ArrayBuffer|String|Object, [encoding: "utf-8"|"ucs2"|"bin"|"base64"]');
|
|
|
|
encoding := '';
|
|
if argc=2 then begin
|
|
if (argc = 2) and (vals[1].isString) then
|
|
encoding := LowerCase(vals[1].asJSString.ToUTF8(cx));
|
|
end;
|
|
|
|
case cx.TypeOfValue(vals[0]) of
|
|
JSTYPE_STRING: begin
|
|
if (encoding = '') or (encoding = 'utf-8') or (encoding = 'utf8') then // default is utf-8
|
|
vals[0].asJSString.ToUTF8(cx, dest)
|
|
else if (encoding = 'ucs2') then begin
|
|
tmp2 := vals[0].asJSString.ToSynUnicode(cx);
|
|
dest.AddNoJSONEscapeW(pointer(tmp2), length(tmp2));
|
|
end else
|
|
raise ESMException.Create('invalid encoding');
|
|
end;
|
|
JSTYPE_NUMBER:
|
|
if vals[0].isInteger then
|
|
dest.Add(vals[0].asInteger)
|
|
else
|
|
dest.AddDouble(vals[0].asDouble);
|
|
JSTYPE_OBJECT: begin
|
|
bufObj := vals[0].asObject;
|
|
if bufObj=nil then begin
|
|
Result.asBoolean := true;
|
|
Exit;
|
|
end;
|
|
if bufObj.GetBufferDataAndLength(bufData, len) then begin
|
|
if encoding = 'base64' then begin
|
|
tmp1 := BinToBase64(PAnsiChar(bufData), len);
|
|
bufData := Puint8Vector(tmp1);
|
|
len := Length(tmp1);
|
|
encoding := 'bin';
|
|
end;
|
|
if (encoding = '') or (encoding = 'bin') then begin // default is bin
|
|
if len>0 then
|
|
dest.AddNoJSONEscape(pointer(bufData), len)
|
|
end else
|
|
raise ESMException.Create('invalid encoding');
|
|
end else begin
|
|
if (encoding = '') or (encoding = 'utf-8') or (encoding = 'utf8') then // default is utf-8
|
|
vals[0].AddJSON(cx, dest)
|
|
else
|
|
raise ESMException.Create('invalid encoding');
|
|
end;
|
|
end;
|
|
JSTYPE_VOID: begin end; // do nothing
|
|
else
|
|
raise ESMException.Create('invalid parameter type for Writer');
|
|
end;
|
|
result.asBoolean := True;
|
|
end;
|
|
|
|
end.
|
|
|