1 /***************************************************************************
2                           cfile.cpp  -  CJP's file class
3                              -------------------
4     begin                : Thu May 23 2002
5     copyright            : (C) 2002 by CJP
6     email                : cornware-cjp@users.sourceforge.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 #include "cfile.h"
18 #include <cstdio>
19 #include <cstdlib>
20 #include <dirent.h>
21 #include <sys/stat.h>
22 
CFile(CString filename,bool write)23 CFile::CFile(CString filename, bool write)
24 {
25 	CFile::open(filename, write);
26 }
27 
CFile()28 CFile::CFile()
29 {
30 	fp = NULL; //closed
31 }
32 
~CFile()33 CFile::~CFile()
34 {
35 	CFile::close();
36 }
37 
open(CString filename,bool write)38 bool CFile::open(CString filename, bool write)
39 {
40 	m_Filename = filename;
41 	m_Write = write;
42 
43 	const char *fn = filename.c_str();
44 
45 	if(write)
46 	{
47 		fp = fopen(fn,"wb");
48 
49 		if(fp==NULL)
50 		{printf("Error: could not write to %s\n", fn); return false;}
51 	}
52 	else
53 	{
54 		fp = fopen(fn,"rb");
55 
56 		if(fp==NULL)
57 			{printf("Error: could not read from %s\n", fn); return false;}
58 	}
59 
60 	return true;
61 }
62 
close()63 void CFile::close()
64 {
65 	if(fp==NULL) return;
66 	fclose(fp);
67 	fp = NULL;
68 }
69 
reopen()70 void CFile::reopen()
71 {
72 	CFile::close();
73 	CFile::open(m_Filename, m_Write);
74 }
75 
readl()76 CString CFile::readl()
77 {
78 	if(fp==NULL)
79 		return "\n";
80 
81 	CString ret;
82 	ret = "";
83 
84 	int c = 0; //!='\n' en !=EOF
85 	while((c!='\n' && c!=EOF))
86 	{
87 		c = fgetc(fp);
88 		if (c=='\r') c = fgetc(fp); //MS-DOS indeling
89 		if(c!='\n' && c!=EOF)
90 			ret += c;
91 	}
92 
93 	if(c==EOF && ret.length()==0)
94 		ret += '\n';
95 
96 	return ret;
97 }
98 
writel(CString l)99 void CFile::writel(CString l)
100 {
101   const char *c = l.c_str();
102   fputs(c, fp);
103   fputc('\n', fp);
104 }
105 
readBytes(unsigned int maxlen)106 CBinBuffer CFile::readBytes(unsigned int maxlen)
107 {
108 	if(fp==NULL)
109 		return CBinBuffer();
110 
111 	Uint8 buffer[maxlen];
112 
113 	unsigned int size = fread(buffer, 1, maxlen, fp);
114 
115 	CBinBuffer ret;
116 	for(unsigned int i=0; i < size; i++)
117 		ret += buffer[i];
118 
119 	return ret;
120 }
121 
writeBytes(const CBinBuffer & b)122 void CFile::writeBytes(const CBinBuffer &b)
123 {
124 	if(fp==NULL)
125 		return;
126 
127 	Uint8 buffer[b.size()];
128 	for(unsigned int i=0; i < b.size(); i++)
129 		buffer[i] = b[i];
130 
131 	fwrite(buffer, 1, b.size(), fp);
132 }
133 
fileExists(const CString & filename)134 bool fileExists(const CString &filename)
135 {
136 	//try to open it with fopen
137 	FILE *fp = fopen(filename.c_str(), "r");
138 
139 	if(fp == NULL) return false;
140 
141 	fclose(fp);
142 	return true;
143 }
144 
dirExists(const CString & dirname)145 bool dirExists(const CString &dirname)
146 {
147 	DIR *theDir = opendir(dirname.c_str());
148 
149 	if(theDir == NULL) return false;
150 
151 	closedir(theDir);
152 	return true;
153 }
154 
getDirContents(const CString & dir,const CString & ext,bool sort)155 vector<CString> getDirContents(const CString &dir, const CString &ext, bool sort)
156 {
157 	vector<CString> ret;
158 
159 	DIR *dir1 = opendir(dir.c_str());
160 
161 	if(dir1 == NULL) return ret;
162 
163 	while(true)
164 	{
165 		struct dirent *entry = readdir(dir1);
166 		if(entry == NULL) break;
167 
168 		CString entname = entry->d_name;
169 		CString ent_lcase = entname;
170 		ent_lcase.toLower();
171 		//file extension check:
172 		if(ext == "" || ent_lcase.right(ext.length()) == ext)
173 			//(ent_lcase.inStr(ext) >= 0 &&
174 			//ent_lcase.inStr(ext) == (int)(ent_lcase.length() - ext.length()) )
175 			//)
176 			ret.push_back(entname);
177 	}
178 
179 	closedir(dir1);
180 
181 	//Now sort
182 	if(sort && ret.size() > 1)
183 		for(unsigned int i=0; i < ret.size()-1; i++)
184 		{
185 			CString &item = ret[i];
186 
187 			//Find earlier item
188 			for(unsigned int j=i+1; j < ret.size(); j++)
189 			{
190 				CString &newitem = ret[j];
191 				if(newitem.compare(item) < 0)
192 				{
193 					//Swap if found
194 					item.swap(newitem);
195 				}
196 			}
197 		}
198 
199 	return ret;
200 }
201 
getAbsDir(const CString & dir)202 CString getAbsDir(const CString &dir)
203 {
204 	CString absdir;
205 	char absdirbuffer[4096];
206 	if(realpath(dir.c_str(), absdirbuffer) != NULL)
207 	{
208 		absdir = CString(absdirbuffer) + "/";
209 	}
210 	return absdir;
211 }
212 
makeDir(const CString & dirname)213 bool makeDir(const CString &dirname)
214 {
215 	//printf("makeDir(\"%s\");\n", dirname.c_str());
216 	if(!dirExists(dirname))
217 	{
218 		int i = 1;
219 
220 		while(true)
221 		{
222 			int nextSlash = dirname.mid(i+1).inStr('/');
223 
224 			CString subdir;
225 			if(nextSlash < 0)
226 			{
227 				nextSlash = dirname.length()-1;
228 				subdir = dirname;
229 			}
230 			else
231 			{
232 				nextSlash += i+1;
233 				subdir = dirname.mid(0, nextSlash);
234 			}
235 
236 			if(!dirExists(subdir))
237 			{
238 				printf("Making dir %s\n", subdir.c_str());
239 				mkdir(subdir.c_str(), 00700);
240 			}
241 
242 			i = nextSlash;
243 			if(i == int(dirname.length())-1) break;
244 		}
245 	}
246 
247 	if(!dirExists(dirname)) return false;
248 
249 	return true;
250 }
251 
makeFile(const CString & filename)252 bool makeFile(const CString &filename)
253 {
254 	//find the last slash
255 	int pos = 0;
256 	while(true)
257 	{
258 		int nextSlash = filename.mid(pos+1).inStr('/');
259 		if(nextSlash < 0) break;
260 
261 		nextSlash += pos+1;
262 
263 		pos = nextSlash;
264 	}
265 
266 	if(!makeDir(filename.mid(0, pos)) ) return false;
267 
268 	FILE *fp = fopen(filename.c_str(), "w");
269 	if(fp == NULL) return false;
270 	fclose(fp);
271 
272 	return true;
273 }
274 
copyFile(const CString & src,const CString & dest)275 bool copyFile(const CString &src, const CString &dest)
276 {
277 	FILE *fp1 = fopen(src.c_str(), "r");
278 	if(fp1 == NULL) return false;
279 
280 	FILE *fp2 = fopen(dest.c_str(), "w");
281 	if(fp2 == NULL)
282 	{
283 		fclose(fp1);
284 		return false;
285 	}
286 
287 	while(true)
288 	{
289 		int c = fgetc(fp1);
290 		if(c == EOF) break;
291 		fputc(c, fp2);
292 	}
293 
294 	fclose(fp1);
295 	fclose(fp2);
296 	return true;
297 }
298