1#include "File.h" 2 3 4void File::open(int file_descr, FileMode m, bool own) 5{ 6 if (fd != -1) ::close(fd); 7 fd = file_descr; 8 mode = m; 9 own_fd = own; 10 pos = 0; 11 buf = xmalloc<uchar>(File_BufSize); 12 if (mode == READ) size = read(fd, buf, File_BufSize); 13 else size = -1; 14} 15 16void File::open(cchar* name, cchar* mode_) 17{ 18 if (fd != -1) ::close(fd); 19 bool has_r = strchr(mode_, 'r') != NULL; 20 bool has_w = strchr(mode_, 'w') != NULL; 21 bool has_a = strchr(mode_, 'a') != NULL; 22 bool has_p = strchr(mode_, '+') != NULL; 23 bool has_x = strchr(mode_, 'x') != NULL; 24 assert(!(has_r && has_w)); 25 assert(has_r || has_w || has_a); 26 27 int mask = 0; 28 if (has_p) mask |= O_RDWR; 29 else if (has_r) mask |= O_RDONLY; 30 else mask |= O_WRONLY; 31 32 if (!has_r) mask |= O_CREAT; 33 if (has_w) mask |= O_TRUNC; 34 if (has_x) mask |= O_EXCL; 35 36 fd = open64(name, mask, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); 37 38 if (fd != -1){ 39 mode = has_r ? READ : WRITE; 40 own_fd = true; 41 pos = 0; 42 if (has_a) lseek64(fd, 0, SEEK_END); 43 buf = xmalloc<uchar>(File_BufSize); 44 if (mode == READ) size = read(fd, buf, File_BufSize); 45 else size = -1; 46 } 47} 48 49 50void File::close(void) 51{ 52 if (fd == -1) return; 53 if (mode == WRITE) 54 flush(); 55 xfree(buf); buf = NULL; 56 if (own_fd) 57 ::close(fd); 58 fd = -1; 59} 60 61void File::seek(int64 file_pos, int whence) 62{ 63 if (mode == WRITE){ 64 flush(); 65 pos = 0; 66 lseek64(fd, file_pos, whence); 67 }else{ 68 if (whence == SEEK_CUR) lseek64(fd, file_pos - (size - pos), SEEK_CUR); 69 else lseek64(fd, file_pos, whence); 70 size = read(fd, buf, File_BufSize); 71 pos = 0; 72 } 73} 74 75int64 File::tell(void) 76{ 77 if (mode == WRITE) 78 return lseek64(fd, 0, SEEK_CUR); 79 else 80 return lseek64(fd, 0, SEEK_CUR) - (size - pos); 81} 82 83 84//================================================================================================= 85// Marshaling: 86 87 88void putUInt(File& out, uint64 val) 89{ 90 if (val < 0x20000000){ 91 uint v = (uint)val; 92 if (v < 0x80) 93 out.putChar(v); 94 else{ 95 if (v < 0x2000) 96 out.putChar(0x80 | (v >> 8)), 97 out.putChar((uchar)v); 98 else if (v < 0x200000) 99 out.putChar(0xA0 | (v >> 16)), 100 out.putChar((uchar)(v >> 8)), 101 out.putChar((uchar)v); 102 else 103 out.putChar((v >> 24) | 0xC0), 104 out.putChar((uchar)(v >> 16)), 105 out.putChar((uchar)(v >> 8)), 106 out.putChar((uchar)v); 107 } 108 }else 109 out.putChar(0xE0), 110 out.putChar((uchar)(val >> 56)), 111 out.putChar((uchar)(val >> 48)), 112 out.putChar((uchar)(val >> 40)), 113 out.putChar((uchar)(val >> 32)), 114 out.putChar((uchar)(val >> 24)), 115 out.putChar((uchar)(val >> 16)), 116 out.putChar((uchar)(val >> 8)), 117 out.putChar((uchar)val); 118} 119 120 121uint64 getUInt(File& in) 122 throw(Exception_EOF) 123{ 124 uint byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7; 125 byte0 = in.getChar(); 126 if (byte0 == (uint)EOF) 127 throw Exception_EOF(); 128 if (!(byte0 & 0x80)) 129 return byte0; 130 else{ 131 switch ((byte0 & 0x60) >> 5){ 132 case 0: 133 byte1 = in.getChar(); 134 return ((byte0 & 0x1F) << 8) | byte1; 135 case 1: 136 byte1 = in.getChar(); 137 byte2 = in.getChar(); 138 return ((byte0 & 0x1F) << 16) | (byte1 << 8) | byte2; 139 case 2: 140 byte1 = in.getChar(); 141 byte2 = in.getChar(); 142 byte3 = in.getChar(); 143 return ((byte0 & 0x1F) << 24) | (byte1 << 16) | (byte2 << 8) | byte3; 144 default: 145 byte0 = in.getChar(); 146 byte1 = in.getChar(); 147 byte2 = in.getChar(); 148 byte3 = in.getChar(); 149 byte4 = in.getChar(); 150 byte5 = in.getChar(); 151 byte6 = in.getChar(); 152 byte7 = in.getChar(); 153 return ((uint64)((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3) << 32) 154 | (uint64)((byte4 << 24) | (byte5 << 16) | (byte6 << 8) | byte7); 155 } 156 } 157} 158