(*
/*
CLASS {NATIVE_File_stream|_Delphi_KOL}, BYTES, NATIVE, UNTESTED,
ABSTRACT :

//NATIVE: "{$IFNDEF FPC}{$DEFINE USE_FirstByte}{$ENDIF}" .

*/
*)

unit NATIVE_File_stream;
{$I EXTERNAL_DEFINES.inc}

interface uses Windows, KOL, AL4;

var All_streams: PList;

function Double_to_int64(d: Double): Int64;

implementation

function Double_to_int64(d: Double): Int64;
var s: String;
    i: Integer;
begin
    //s := Double2Str(Trunc(d));
    System.Str(d:0:0, s);
    i := pos('.', s);
    if i <= 0 then i := pos(',', s);
    if i > 0 then s := Copy(s, 1, i-1);
    Result := Int64(Str2Int64(s));
end;

(*

/*

TODO : "DEFINE STREAM_LARGE64 when compiling with $KOL option" .

CONST STR :
    NATIVE_File_stream_import = @
    "uses Windows, NATIVE_file_stream"
    
	NATIVE_All_streams = ""
    
    NATIVE_File_stream_open = @
    "var h, i: Integer;"
    "var mf: DWORD;"
    "var strm: PStream;"
    "    if All_streams = nil then All_streams := NewList;"
    "    if All_streams.Count = 0 then"
    "       All_streams.Add(nil);"
    "    h := -1;"
    "    for i := 1 to All_streams.Count-1 do"
    "        if All_streams.Items[i] = nil then begin"
    "           h := i; break;"
    "        end;"
    "    if (h <= 0) then begin"
    "       h := All_streams.Count;"
    "       All_streams.Add(nil);"
    "    end;"
    "    mf := ofOpenRead or ofOpenAlways or ofShareDenyWrite;"
    "    case X_Mode of"
    "       1: mf := ofOpenWrite or ofOpenAlways or ofShareDenyWrite;"
    "       2: mf := ofOpenReadWrite or ofOpenAlways or ofShareDenyWrite;"
    "       3: mf := ofOpenRead or ofOpenAlways or ofShareDenyNone;"
    "       4: mf := ofOpenReadWrite or ofOpenAlways or ofShareDenyNone;"
    "    end;"
    "    {$IFNDEF NOEXCEPTIONS}"
    "    try"
    "    {$ENDIF}"
    "        strm := NewFileStream(X_Path, mf);"
    "        All_streams.Items[h] := strm;"
    "    {$IFNDEF NOEXCEPTIONS}"
    "    except on E: Exception do "
    "			begin"
    "			{$IFnDEF SMALLEST_CODE}"     
    "				strm := nil;"
    "			{$ENDIF}"     
    "				h := 0;"     
    "			{$IFnDEF SMALLER_CODE}"     
    "				Any_exception(E);"
    "			{$ENDIF}"     
    "			end"     
    "    end;"
    "    {$ENDIF}"
    "	 if (strm <> nil) and (strm.Handle = INVALID_HANDLE_VALUE) then"
    "	 begin"
    "		strm.Free;"     
    " 		All_streams.Items[h] := nil;"
    " 		h := 0;"     
    "	 end;"     
    "    Result := h;"
    
    NATIVE_File_stream_destroy = @
    "    if (X_Handle < 1) or "
    "       (X_Handle >= All_streams.Count) or"
    "       (All_streams.Items[X_Handle] = nil) then Exit;"
    "    All_streams.Items[X_Handle] := nil;"
    
    NATIVE_File_stream_size = @
    "    if (All_streams = nil) or (X_Handle < 1) or "
    "       (X_Handle >= All_streams.Count) or"
    "       (All_streams.Items[X_Handle] = nil) then Exit;"
    "    X_lo_hi.SetIntegers(0, PStream(All_streams.Items[X_Handle]).Size);"
    "	 {$IFDEF _D5orHigher}"     
    "    X_lo_hi.SetIntegers(1, "
    "			 Int64("
    "				PStream(All_streams.Items[X_Handle]).Size)"
    " 				shr 32);"
    "	 {$ENDIF}"     
    
    NATIVE_File_stream_set_size = @
    "var sz: Int64;"
    "    if (All_streams = nil) or (X_Handle < 1) or "
    "       (X_Handle >= All_streams.Count) or"
    "       (All_streams.Items[X_Handle] = nil) then Exit;"
    "	 sz := X_lo_hi.GetIntegers(0);"     
    "	 sz := sz or (Int64(X_lo_hi.GetIntegers(1)) shl 32);"     
    "	 PStream(All_streams.Items[X_Handle]).Size := (sz);"

    //"    if (All_streams = nil) or (X_Handle < 1) or "
    //"       (X_Handle >= All_streams.Count) or"
    //"       (All_streams.Items[X_Handle] = nil) then Exit;"
    //"    X_lo_hi.SetIntegers(0, PStream(All_streams.Items[X_Handle]).Size);"
    //"	 {$IFDEF _D5orHigher}"
    //"    X_lo_hi.SetIntegers(1, "
    //"			 Int64("
    //"				PStream(All_streams.Items[X_Handle]).Size)"
    //" 				shr 32);"
    //"	 {$ENDIF}"
    
    NATIVE_File_stream_position = @
    "    if (All_streams = nil) or (X_Handle < 1) or "
    "       (X_Handle >= All_streams.Count) or"
    "       (All_streams.Items[X_Handle] = nil) then Exit;"
    "    X_lo_hi.SetIntegers(0, PStream(All_streams.Items[X_Handle]).Position);"
    "	 {$IFDEF _D5orHigher}"
    "    X_lo_hi.SetIntegers(1, "
    "			 Int64("
    "				PStream(All_streams.Items[X_Handle]).Position)"
    " 				shr 32);"
    "	 {$ENDIF}"     
    
    NATIVE_File_stream_set_pos = @
    "var To_pos: {$IFDEF _D5orHigher} Int64 {$ELSE} Integer {$ENDIF} ;"
    "var Size64: {$IFDEF _D5orHigher} Int64 {$ELSE} Integer {$ENDIF};"
    "var fs: PStream;"
    "{$IFnDEF SMALLER_CODE}"
    "try"
    "{$ENDIF}"
    "    if (All_streams = nil) or (X_Handle < 1) or "
    "       (X_Handle >= All_streams.Count) or"
    "       (All_streams.Items[X_Handle] = nil) then Exit;"
    "    fs := All_streams.Items[X_Handle];"
    "    if fs.Position > fs.Size then"
    "       fs.Size := fs.Position;"
    "    To_pos := X_New_lo"
    "			{$IFDEF _D5orHigher} or (Int64(X_New_hi) shl 32) {$ENDIF}"     
    "			;"
    "    case X_Disp of" 
    "       1: To_pos := To_pos + fs.Position;"
    "       2: To_pos := fs.Size + To_pos;"
    "    end;"
    "    if To_pos < 0 then To_pos := 0;"
    "    Size64 := {$IFDEF _D5orHigher} Double_to_int64{$ENDIF}(fs.Size);"
    "    if  To_pos >= Size64 then To_pos := Size64;"
    "    fs.Seek(To_pos, spBegin);"
    "{$IFnDEF SMALLER_CODE}"
    "except"
    "end;"
    "{$ENDIF}"
    
    NATIVE_File_stream_close = @
    "    if (All_streams = nil) or (X_Handle < 1) or "
    "       (X_Handle >= All_streams.Count) or"
    "       (All_streams.Items[X_Handle] = nil) then Exit;"
    "    PStream(All_streams.Items[X_Handle]).Free;"
    "    All_streams.Items[X_Handle] := nil;"
    
    NATIVE_File_stream_read_bytes = @
    "var i: Integer; {$IFNDEF USE_FirstByte} buf: array of Byte; {$ENDIF}"
    "    if (All_streams = nil) or (X_Handle < 1) or "
    "       (X_Handle >= All_streams.Count) "
    "       or (All_streams.Items[X_Handle] = nil) then"
    "       Exit;"
    "    {$IFNDEF NOEXCEPTIONS}"
    "    try"
    "    {$ENDIF}"
    "	 {$IFDEF USE_FirstByte}"
    "       Result := PStream(All_streams.Items[X_Handle]).Read("
    "           X_Dest.FirstByte^, X_Dest.Count());"
    "		{$IFnDEF SMALLER_CODE}"
    "			i := 0; if i = 0 then;"     
    "		{$ENDIF}"     
    "	 {$ELSE}"
    "		SetLength(buf, X_Dest.Count());"
    "       Result := PStream(All_streams.Items[X_Handle]).Read("
    "           buf[0], Length(buf));"
    "		for i := 0 to High(buf) do"
    "			X_Dest.SetBytes(i, buf[i]);"
    "	 {$ENDIF}"
    "    {$IFNDEF NOEXCEPTIONS}"
    "    except on E: Exception do Any_exception(E);"
    "    end;"
    "    {$ENDIF}"
    
    NATIVE_File_stream_write_bytes = @
    "var i: Integer; {$IFNDEF USE_FirstByte} buf: PByte; {$ENDIF}"
    "    if (All_streams = nil) or (X_Handle < 1) or "
    "       (X_Handle >= All_streams.Count) or"
    "       (All_streams.Items[X_Handle] = nil) then Exit;"
    "    {$IFNDEF NOEXCEPTIONS}"
    "    try"
    "    {$ENDIF}"
    "	 {$IFDEF USE_FirstByte}"
    "        Result := PStream(All_streams.Items[X_Handle]).Write("
    "           X_Source.FirstByte^, X_Source.Count());"
    "		{$IFnDEF SMALLER_CODE}"
    "			i := 0; if i = 0 then;"     
    "		{$ENDIF}"     
    "	 {$ELSE}"
    "		 GetMem(buf, X_Source.Count());"
    "		 for i := 0 to X_Source.Count()-1 do"
    "			 PByte(Integer(buf) + i)^ := X_Source.GetBytes(i);"
    "        Result := PStream(All_streams.Items[X_Handle]).Write("
    "           buf^, X_Source.Count());"
    "		 FreeMem(buf);"     
    "	 {$ENDIF}"
    "    {$IFNDEF NOEXCEPTIONS}"
    "    except on E: Exception do Any_exception(E);"
    "    end;" 
    "    {$ENDIF}"
    
    .

            
*/
*)

end .

(*
/*
END
*/
*)
