Mercurial > projects > ddmd
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