Skip to content

Commit 4819f98

Browse files
committed
Initial commit.
0 parents  commit 4819f98

15 files changed

+2868
-0
lines changed

File.C

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

File.h

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#ifndef File_h
2+
#define File_h
3+
4+
#ifndef Global_h
5+
#include "Global.h"
6+
#endif
7+
8+
#include <unistd.h>
9+
#include <fcntl.h>
10+
#include <sys/stat.h>
11+
12+
#ifndef _LARGEFILE64_SOURCE
13+
#define lseek64 ::lseek
14+
#define open64 ::open
15+
#endif
16+
17+
18+
//=================================================================================================
19+
// A buffered file abstraction with only 'putChar()' and 'getChar()'.
20+
21+
22+
#define File_BufSize 1024 // A small buffer seem to work just as fine as a big one (at least under Linux)
23+
24+
enum FileMode { READ, WRITE };
25+
26+
class Exception_EOF {};
27+
28+
29+
// WARNING! This code is not thoroughly tested. May contain bugs!
30+
31+
class File {
32+
int fd; // Underlying file descriptor.
33+
FileMode mode; // Reading or writing.
34+
uchar* buf; // Read or write buffer.
35+
int size; // Size of buffer (at end of file, less than 'File_BufSize').
36+
int pos; // Current position in buffer
37+
bool own_fd; // Do we own the file descriptor? If so, will close file in destructor.
38+
39+
public:
40+
#define DEFAULTS fd(-1), mode(READ), buf(NULL), size(-1), pos(0), own_fd(true)
41+
File(void) : DEFAULTS {}
42+
43+
File(int fd, FileMode mode, bool own_fd = true) : DEFAULTS {
44+
open(fd, mode, own_fd); }
45+
46+
File(cchar* name, cchar* mode) : DEFAULTS {
47+
open(name, mode); }
48+
#undef DEFAULTS
49+
50+
~File(void) {
51+
close(); }
52+
53+
void open(int fd, FileMode mode, bool own_fd = true); // Low-level open. If 'own_fd' is FALSE, descriptor will not be closed by destructor.
54+
void open(cchar* name, cchar* mode); // FILE* compatible interface.
55+
void close(void);
56+
57+
bool null(void) { // TRUE if no file is opened.
58+
return fd == -1; }
59+
60+
int releaseDescriptor(void) { // Don't run UNIX function 'close()' on descriptor in 'File's 'close()'.
61+
if (mode == READ)
62+
lseek64(fd, pos - size, SEEK_CUR);
63+
own_fd = false;
64+
return fd; }
65+
66+
FileMode getMode(void) {
67+
return mode; }
68+
69+
void setMode(FileMode m) {
70+
if (m == mode) return;
71+
if (m == READ){
72+
flush();
73+
size = read(fd, buf, File_BufSize);
74+
}else{
75+
lseek64(fd, pos - size, SEEK_CUR);
76+
size = -1; }
77+
mode = m;
78+
pos = 0; }
79+
80+
int getCharQ(void) { // Quick version with minimal overhead -- don't call this in the wrong mode!
81+
#ifdef PARANOID
82+
assert(mode == READ);
83+
#endif
84+
if (pos < size) return (uchar)buf[pos++];
85+
if (size < File_BufSize) return EOF;
86+
size = read(fd, buf, File_BufSize);
87+
pos = 0;
88+
if (size == 0) return EOF;
89+
return (uchar)buf[pos++]; }
90+
91+
int putCharQ(int chr) { // Quick version with minimal overhead -- don't call this in the wrong mode!
92+
#ifdef PARANOID
93+
assert(mode == WRITE);
94+
#endif
95+
if (pos == File_BufSize)
96+
write(fd, buf, File_BufSize),
97+
pos = 0;
98+
return buf[pos++] = (uchar)chr; }
99+
100+
int getChar(void) {
101+
if (mode == WRITE) setMode(READ);
102+
return getCharQ(); }
103+
104+
int putChar(int chr) {
105+
if (mode == READ) setMode(WRITE);
106+
return putCharQ(chr); }
107+
108+
bool eof(void) {
109+
assert(mode == READ);
110+
if (pos < size) return false;
111+
if (size < File_BufSize) return true;
112+
size = read(fd, buf, File_BufSize);
113+
pos = 0;
114+
if (size == 0) return true;
115+
return false; }
116+
117+
void flush(void) {
118+
assert(mode == WRITE);
119+
write(fd, buf, pos);
120+
pos = 0; }
121+
122+
void seek(int64 pos, int whence = SEEK_SET);
123+
int64 tell(void);
124+
};
125+
126+
127+
//=================================================================================================
128+
// Some nice helper functions:
129+
130+
131+
void putUInt (File& out, uint64 val);
132+
uint64 getUInt (File& in) throw(Exception_EOF);
133+
static inline uint64 encode64(int64 val) { return (val >= 0) ? (uint64)val << 1 : (((uint64)(~val) << 1) | 1); }
134+
static inline int64 decode64(uint64 val) { return ((val & 1) == 0) ? (int64)(val >> 1) : ~(int64)(val >> 1); }
135+
static inline void putInt (File& out, int64 val) { putUInt(out, encode64(val)); }
136+
static inline uint64 getInt (File& in) { return decode64(getUInt(in)); }
137+
138+
139+
//=================================================================================================
140+
#endif

0 commit comments

Comments
 (0)