diff dmd/File.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 7427ded8caf7
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/File.d	Sat Oct 24 08:42:06 2009 +0400
@@ -0,0 +1,396 @@
+module dmd.File;
+
+import dmd.FileName;
+import dmd.Array;
+import dmd.Util;
+
+import core.stdc.stdlib;
+import core.sys.windows.windows;
+
+import std.string : toStringz;
+
+class File
+{
+    int ref_;					// != 0 if this is a reference to someone else's buffer
+    ubyte* buffer;				// data for our file
+    uint len;					// amount of data in buffer[]
+    void* touchtime;			// system time to use for file
+
+    FileName name;				// name of our file
+
+    this(string n)
+	{
+		name = new FileName(n);
+	}
+
+    this(FileName n)
+	{
+		name = n;
+	}
+
+    ~this()
+	{
+		if (buffer !is null) {
+			if (ref_ == 0) {
+				free(buffer);
+			} else {
+version (_WIN32) {
+				if (ref_ == 2) {
+					UnmapViewOfFile(buffer);
+				}
+}
+			}
+		}
+
+		if (touchtime !is null) {
+			free(touchtime);
+		}
+	}
+
+    void mark()
+	{
+		///mem.mark(buffer);
+		///mem.mark(touchtime);
+		///mem.mark(name);
+	}
+
+    string toChars()
+	{
+		return name.toChars();
+	}
+
+    /* Read file, return !=0 if error
+     */
+
+    int read()
+	{
+version (POSIX) {
+		int result = 0;
+
+		string name = this.name.toChars();
+
+		//printf("File::read('%s')\n",name);
+		int fd = open(name, O_RDONLY);
+		if (fd == -1) {
+			result = errno;
+			//printf("\topen error, errno = %d\n", errno);
+			goto err1;
+		}
+
+		if (ref_ == 0) {
+			free(buffer);
+		}
+
+		ref_ = 0;       // we own the buffer now
+
+		//printf("\tfile opened\n");
+		stat buf;
+		if (fstat(fd, &buf)) {
+			printf("\tfstat error, errno = %d\n", errno);
+			goto err2;
+		}
+
+		off_t size = buf.st_size;
+		buffer = cast(ubyte*)malloc(size + 2);
+		if (buffer is null) {
+			printf("\tmalloc error, errno = %d\n", errno);
+			goto err2;
+		}
+
+		ssize_t numread = .read(fd, buffer, size);
+		if (numread != size) {
+			printf("\tread error, errno = %d\n",errno);
+			goto err2;
+		}
+
+		if (touchtime !is null) {
+			memcpy(touchtime, &buf, buf.sizeof);
+		}
+
+		if (close(fd) == -1) {
+			printf("\tclose error, errno = %d\n",errno);
+			goto err;
+		}
+
+		len = size;
+
+		// Always store a wchar ^Z past end of buffer so scanner has a sentinel
+		buffer[size] = 0;		// ^Z is obsolete, use 0
+		buffer[size + 1] = 0;
+
+		return 0;
+
+	err2:
+		close(fd);
+
+	err:
+		free(buffer);
+		buffer = null;
+		len = 0;
+
+	err1:
+		result = 1;
+		return result;
+} else version (_WIN32) {
+		DWORD size;
+		DWORD numread;
+		HANDLE h;
+		int result = 0;
+
+		string name = this.name.toChars();
+		//std.stdio.writeln("Open file ", name);
+
+		h = CreateFileA(toStringz(name), GENERIC_READ, FILE_SHARE_READ, null, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, HANDLE.init);
+		if (h == INVALID_HANDLE_VALUE) {
+			goto err1;
+		}
+
+		if (!ref_) {
+			free(buffer);
+		}
+		ref_ = 0;
+
+		size = GetFileSize(h, null);
+		buffer = cast(ubyte*) malloc(size + 2);
+		if (!buffer)
+			goto err2;
+
+		if (ReadFile(h, buffer, size, &numread, null) != TRUE)
+			goto err2;
+
+		if (numread != size)
+			goto err2;
+
+		if (touchtime) {
+			if (!GetFileTime(h, null, null, &(cast(WIN32_FIND_DATA*)touchtime).ftLastWriteTime))
+				goto err2;
+		}
+
+		if (!CloseHandle(h))
+			goto err;
+
+		len = size;
+
+		// Always store a wchar ^Z past end of buffer so scanner has a sentinel
+		buffer[size] = 0;		// ^Z is obsolete, use 0
+		buffer[size + 1] = 0;
+		return 0;
+
+	err2:
+		CloseHandle(h);
+	err:
+		free(buffer);
+		buffer = null;
+		len = 0;
+
+	err1:
+		result = 1;
+		return result;
+} else {
+		static assert(0);
+}
+	}
+
+    /* Write file, either succeed or fail
+     * with error message & exit.
+     */
+
+    void readv()
+	{
+		if (read())
+			error("Error reading file '%s'\n",name.toChars());
+	}
+
+    /* Read file, return !=0 if error
+     */
+
+    int mmread()
+	{
+		assert(false);
+	}
+
+    /* Write file, either succeed or fail
+     * with error message & exit.
+     */
+
+    void mmreadv()
+	{
+		assert(false);
+	}
+
+    /* Write file, return !=0 if error
+     */
+
+	/*********************************************
+	 * Write a file.
+	 * Returns:
+	 *	0	success
+	 */
+    int write()
+	{
+version (POSIX) {
+		assert(false);
+		/+
+		int fd;
+		ssize_t numwritten;
+		char *name;
+
+		name = this->name->toChars();
+		fd = open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644);
+		if (fd == -1)
+		goto err;
+
+		numwritten = ::write(fd, buffer, len);
+		if (len != numwritten)
+		goto err2;
+		
+		if (close(fd) == -1)
+		goto err;
+
+		if (touchtime)
+		{   struct utimbuf ubuf;
+
+			ubuf.actime = ((struct stat *)touchtime)->st_atime;
+			ubuf.modtime = ((struct stat *)touchtime)->st_mtime;
+		if (utime(name, &ubuf))
+			goto err;
+		}
+		return 0;
+
+	err2:
+		close(fd);
+		::remove(name);
+	err:
+		return 1;
+		+/
+} else version (_WIN32) {
+		HANDLE h;
+		DWORD numwritten;
+
+		const(char)* name = toStringz(this.name.toChars());
+		h = CreateFileA(name, GENERIC_WRITE, 0, null, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, null);
+		if (h == INVALID_HANDLE_VALUE)
+			goto err;
+
+		if (WriteFile(h, buffer, len, &numwritten, null) != TRUE)
+			goto err2;
+
+		if (len != numwritten)
+			goto err2;
+		
+		if (touchtime) {
+			SetFileTime(h, null, null, &(cast(WIN32_FIND_DATA*)touchtime).ftLastWriteTime);
+		}
+		if (!CloseHandle(h))
+			goto err;
+		return 0;
+
+	err2:
+		CloseHandle(h);
+		DeleteFileA(name);
+	err:
+		return 1;
+} else {
+		static assert(false);
+}
+	}
+
+    /* Write file, either succeed or fail
+     * with error message & exit.
+     */
+
+    void writev()
+	{
+		if (write()) {
+			error("Error writing file '%s'\n", name.toChars());
+		}
+	}
+
+    /* Return !=0 if file exists.
+     *	0:	file doesn't exist
+     *	1:	normal file
+     *	2:	directory
+     */
+
+    /* Append to file, return !=0 if error
+     */
+
+    int append()
+	{
+		assert(false);
+	}
+
+    /* Append to file, either succeed or fail
+     * with error message & exit.
+     */
+
+    void appendv()
+	{
+		assert(false);
+	}
+
+    /* Return !=0 if file exists.
+     *	0:	file doesn't exist
+     *	1:	normal file
+     *	2:	directory
+     */
+
+    int exists()
+	{
+		assert(false);
+	}
+
+    /* Given wildcard filespec, return an array of
+     * matching File's.
+     */
+
+    static Array match(char*)
+	{
+		assert(false);
+	}
+
+    static Array match(FileName *)
+	{
+		assert(false);
+	}
+
+    // Compare file times.
+    // Return	<0	this < f
+    //		=0	this == f
+    //		>0	this > f
+    int compareTime(File f)
+	{
+		assert(false);
+	}
+
+    // Read system file statistics
+    void stat()
+	{
+		assert(false);
+	}
+
+    /* Set buffer
+     */
+
+    void setbuffer(void* buffer, uint len)
+    {
+		this.buffer = cast(ubyte*)buffer;
+		this.len = len;
+    }
+
+    void checkoffset(size_t offset, size_t nbytes)
+	{
+		assert(false);
+	}
+
+    void remove()		// delete file
+	{
+version (POSIX) {
+		.remove(this.name.toChars());
+} else version (_WIN32) {
+		DeleteFileA(toStringz(this.name.toChars()));
+} else {
+		assert(0);
+}
+	}
+}
\ No newline at end of file