view file.rhope @ 89:5a195ee08eac

Fix memory leak and bug that was preventing First@Dictionary from working properly
author Mike Pavone <pavone@retrodev.com>
date Sat, 31 Jul 2010 00:19:15 -0400
parents 2e2e55fc12f9
children f51c4c17457c
line wrap: on
line source


//This implementation will change quite a bit once the transaction system is working
//and I've finalized how File I/O will fit into that. This is just a very basic
//implementation to allow the compiler to be self-hosting.

Foreign C:libc
{
	open[name(Array,Raw Pointer),flags(Int32,Naked),mode(UInt32,Naked):filedes(Int32,Naked)]
	close[filedes(Int32,Naked):status(Int32,Naked)]
	fsync[filedes(Int32,Naked):status(Int32,Naked)]
	fstat[filedes(Int32,Naked),buf(Stat,Raw Pointer,Mutable):err(Int32,Naked),buf]
	lseek[filedes(Int32,Naked),offset(Int64,Naked),whence(Int32,Naked):out(Int64,Naked)]
	ftruncate[filedes(Int32,Naked),length(Int64,Naked):status(Int32,Naked)]
}

Blueprint Stat
{
	Device(UInt64,Naked)	
	Inode(UInt64,Naked)
	Link Count(UInt64,Naked)
	Mode(UInt32,Naked)
	Owner ID(UInt32,Naked)
	Group ID(UInt32,Naked)
	Pad0(Int32,Naked)
	RDevice(UInt64,Naked)
	Size(Int64,Naked)
	Block Size(Int64,Naked)
	Block Count(Int64,Naked)
	Access Time(Int64,Naked)
	Access Time Nano(UInt64,Naked)
	Mod Time(Int64,Naked)
	Mod Time Nano(UInt64,Naked)
	Status Time(Int64,Naked)
	Status Time Nano(UInt64,Naked)
	Unused1(Int64,Naked)
	Unused2(Int64,Naked)
	Unused3(Int64,Naked)
}

Stat[fd:out]
{
	err,out <- fstat[fd, Build[Stat()]]
}

Blueprint File
{
	Name
}

Blueprint File Read
{
	Name
	Descriptor(Int32,Naked)
	Info
}

Blueprint File Write
{
	Name
	Descriptor(Int32,Naked)
	Info
}

Blueprint File ReadWrite
{
	Name
	Read Offset(Int64,Naked)
	Descriptor(Int32,Naked)
	Info
}

File[name:out]
{
	out <- [Build[File()]]Name <<[name]
}


Open@File[file,mode:out,error]
{
	If[[mode]=["r"]]
	{
		imode <- 0i32
		type <- File Read()
		out <- Val[ofile]
	}{
		If[[mode]=["w"]]
		{ 
			imode <- 65i32
			type <- File Write()
			out <- Val[ofile]
			If[[fd]!=[-1i32]]
			{ lseek[fd, 0i64, 2i32] }
		}{
			,error <- If[[mode]=["rw"]]
			{ 
				imode <- 66i32
				type <- File ReadWrite()
				out <- [ofile]Read Offset <<[0i64]
			}
		}
	}
	fd <- open[[[[file]Name >>]Flatten]Buffer >>, imode, 438u32]
	error <- If[[fd]=[-1i32]] {}
	{
		ofile <- [[[Build[type]	
			]Name <<[ [file]Name >> ]
			]Descriptor <<[fd]
			]Info <<[Stat[fd]]
	}
}

Read@File[file,bytes:data,outfile,error]
{
	,error <- [file]Open["r"]
	{
		data,outfile,error <- [~]Read[bytes]
	}
}
/*
Append@File[file,data:out,error]
{
	,error <- [file]Open["w"]
	{
		out,error <- [~]Append[data]
	}
}*/

String@File[file:out,error]
{
	f,error <- [file]Open["r"]
	{
		out,error <- String[~]
		{ Close[f] }
	}
}

Truncate@File[file:out,error]
{
	f,error <- [file]Open["w"]
	{	
		out,error <- Truncate[f]
	}
}

Write@File[file,data:out,error]
{
	f,error <- [file]Open["w"]
	{
		out,error <- [f]Write[data]
	}
}


String@File Read[file:out,error]
{
	,error <- [file]Read[[file]Length]
	{ out <- String[~] }
}

Read@File Read[file,inbytes(Int32):data,outfile,error]
{
	readbytes, mdata <- read[[file]Descriptor >>, [Array[]]Set[inbytes, 0u8], Int64[inbytes]]
	error <- If[[readbytes]<[0i64]] {}
	{
		outfile <- file
		data <- [mdata]Length <<[ Trunc Int32[readbytes] ]
	}
	/* 
	//Skip buffering for now. Buffering approach may need to change later anyway
	buflen <- [[file]Buffer >>]Length
	If[buflen]
	{
		If[[inbytes]=[buflen]]
		{	
			data <- [file]Buffer >>
			outfile <- [file]Buffer <<[Array[]]
		}{
			If[[inbytes]<[buflen]]
			{
			
			}{
				
			}
		}
	}{
		readbytes, mdata <- read[[file]Descriptor >>, [Array[]]Set[inbytes, 0u8], Int64[inbytes]]
		error <- If[[readbytes]<[0i64]] {}
		{
			outfile <- file
			data <- [mdata]Length <<[ Trunc Int32[readbytes] ]
		}
	} */
}

Length@File Read[file:out]
{
	out <- Trunc Int32[[[file]Info >>]Size >>]
}

Close@File Read[file:out]
{
	close[[file]Descriptor >>]
	out <- File[[file]Name >>]
}

Length@File Write[file:out]
{
	out <- Trunc Int32[[[file]Info >>]Size >>]
}

Truncate@File Write[file:out,err]
{
	err <- If[ftruncate[[file]Descriptor >>, 0i64]] {}
	{ 
		err <- If[lseek[[file]Descriptor >>, 0i64, 0i32]] {}
		{ out <- [file]Info <<[ [[file]Info >>]Size <<[0i64] ] }
	}
}

Write@File Write[file,data(Array):out,err]
{
	err <- If[write[[file]Descriptor >>, data, Int64[[data]Length >>]]] {}
	{
		out <- file
	}
}

Close@File Write[file:out]
{
	fsync[[file]Descriptor >>]
	{ close[[file]Descriptor >>] }
	out <- File[[file]Name >>]
}