~drizzle-trunk/drizzle/development

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
 *
 * PrimeBase Media Stream for MySQL
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 *
 * Original author: Paul McCullagh (H&G2JCtL)
 * Continued development: Barry Leslie
 *
 * 2007-06-07
 *
 * CORE SYSTEM:
 * Basic file I/O.
 *
 */

#ifndef __CSFILE_H__
#define __CSFILE_H__

#include <stdio.h>

#include "CSDefs.h"
#include "CSPath.h"
#include "CSException.h"
#include "CSSys.h"

class CSOutputStream;
class CSInputStream;

class CSFile : public CSSysFile, public CSRefObject {
public:
	CSPath *myFilePath;

	static const int DEFAULT = 0;	// Open for read/write, error if it does not exist.
	static const int READONLY = 1;	// Open for readonly
	static const int CREATE = 2;	// Create if it does not exist
	static const int TRUNCATE = 4;	// After open, set EOF to zero	

	CSFile(): myFilePath(NULL), iMode(-1), iLocked(0) { }

	virtual ~CSFile(); 

	CSOutputStream *getOutputStream();
	CSOutputStream *getOutputStream(off64_t offset);

	CSInputStream *getInputStream();
	CSInputStream *getInputStream(off64_t offset);

	/*
	 * Open the file in the specified
	 * mode.
	 */
	virtual void open(int mode);

	/* Lock the file. The file will be unlocked
	 * when closed.
	 */
	virtual void lock();

	virtual void unlock();

	/*
	 * Close the file.
	 */
	virtual void close();

	/*
	 * Calculate the Md5 digest for the file.
	 */
	void md5Digest(Md5Digest *digest);

	/*
	 * Move the current position to
	 * the end of the file.
	 */
	virtual off64_t getEOF();

	virtual void setEOF(off64_t offset);

	/*
	 * Read a given number of bytes. This function
	 * throws an error if the number of bytes read
	 * ius less than 'min_size'.
	 */
	virtual size_t read(void *data, off64_t offset, size_t size, size_t min_size);

	/*
	 * Write the given number of bytes.
	 * Throws IOException if an error occurs.
	 */
	virtual void write(const void *data, off64_t offset, size_t size);

	/*
	 * Flush the data written.
	 */
	virtual void flush();

	/* Flush the OS buffers: */
	virtual void sync() ;

	/* Resets access and modification times of the file: */
	virtual void touch();

	/*
	 * Return a platform specific prefered 
	 * line ending for text files.
	 */
	virtual const char *getEOL() { return "\n"; };

	virtual const char *getPathString() { return myFilePath->getCString(); }

	bool exists() { return myFilePath->exists(); }

	friend class CSReadBufferedFile;

private:
	int		iMode;
	int		iLocked;

	virtual void openFile(int mode);
	bool try_CreateAndOpen(CSThread *self, int mode, bool retry);

public:
	void streamOut(CSOutputStream *dst_stream, off64_t src_offset, off64_t size, char *buffer, size_t buffer_size);
	void streamIn(CSInputStream *src_stream, off64_t dst_offset, off64_t size, char *buffer, size_t buffer_size);

	static bool isDirNotFound(CSException *e) { return e->getErrorCode() == ENOENT; }
	static bool isDirExists(CSException *e) { return e->getErrorCode() == EEXIST; }

	static bool transfer(CSFile *dst_file, off64_t dst_offset, CSFile *src_file, off64_t src_offset, off64_t size, char *buffer, size_t buffer_size);

	static CSFile *newFile(CSPath *path);

	static CSFile *newFile(const char *path);

	static CSFile *newFile(const char *dir_str, const char *path_str);
};


// This stuff needs to be retought.

#ifdef DEBUG
#define SC_DEFAULT_FILE_BUFFER_SIZE			127
#else
#define SC_DEFAULT_FILE_BUFFER_SIZE			(64 * 1024)
#endif

class CSReadBufferedFile : public CSRefObject {
public:

	CSReadBufferedFile();

	~CSReadBufferedFile();
	
	void setFile(CSFile	*file) {myFile = file;}

	const char *getPathString() { return myFile->getPathString(); }
	void open(int mode) {myFile->open(mode); }

	void close();

	off64_t getEOF();

	void setEOF(off64_t offset);

	size_t read(void *data, off64_t offset, size_t size, size_t min_size);

	void write(const void *data, off64_t offset, size_t size);

	void flush();

	void sync();

	const char *getEOL();

private:
	CSFile	*myFile;

	char	iFileBuffer[SC_DEFAULT_FILE_BUFFER_SIZE];
	off64_t	iFileBufferOffset;
	size_t	iBufferDataLen;

	virtual void openFile(int mode);
};


#endif