1*c2c66affSColin Finck // File.cpp
2*c2c66affSColin Finck // This file is (C) 2002-2003 Royce Mitchell III and released under the BSD license
3*c2c66affSColin Finck
4*c2c66affSColin Finck #ifdef _MSC_VER
5*c2c66affSColin Finck #pragma warning ( disable : 4786 )
6*c2c66affSColin Finck #endif//_MSC_VER
7*c2c66affSColin Finck
8*c2c66affSColin Finck #include "File.h"
9*c2c66affSColin Finck
open(const char * filename,const char * mode)10*c2c66affSColin Finck bool File::open ( const char* filename, const char* mode )
11*c2c66affSColin Finck {
12*c2c66affSColin Finck close();
13*c2c66affSColin Finck _f = fopen ( filename, mode );
14*c2c66affSColin Finck return _f != 0;
15*c2c66affSColin Finck }
16*c2c66affSColin Finck
getline(bool strip_crlf)17*c2c66affSColin Finck std::string File::getline ( bool strip_crlf /*= false*/ )
18*c2c66affSColin Finck {
19*c2c66affSColin Finck std::string s = "";
20*c2c66affSColin Finck char buf[256];
21*c2c66affSColin Finck for ( ;; )
22*c2c66affSColin Finck {
23*c2c66affSColin Finck *buf = 0;
24*c2c66affSColin Finck fgets ( buf, sizeof(buf)-1, _f );
25*c2c66affSColin Finck if ( !*buf )
26*c2c66affSColin Finck break;
27*c2c66affSColin Finck s += buf;
28*c2c66affSColin Finck if ( strchr ( "\r\n", buf[strlen(buf)-1] ) )
29*c2c66affSColin Finck break;
30*c2c66affSColin Finck }
31*c2c66affSColin Finck if ( strip_crlf )
32*c2c66affSColin Finck {
33*c2c66affSColin Finck char* p = strpbrk ( &s[0], "\r\n" );
34*c2c66affSColin Finck if ( p )
35*c2c66affSColin Finck {
36*c2c66affSColin Finck *p = '\0';
37*c2c66affSColin Finck s.resize ( p-&s[0] );
38*c2c66affSColin Finck }
39*c2c66affSColin Finck }
40*c2c66affSColin Finck return s;
41*c2c66affSColin Finck }
42*c2c66affSColin Finck
43*c2c66affSColin Finck // this function searches for the next end-of-line and puts all data it
44*c2c66affSColin Finck // finds until then in the 'line' parameter.
45*c2c66affSColin Finck //
46*c2c66affSColin Finck // call continuously until the function returns false ( no more data )
next_line(std::string & line,bool strip_crlf)47*c2c66affSColin Finck bool File::next_line ( std::string& line, bool strip_crlf )
48*c2c66affSColin Finck {
49*c2c66affSColin Finck line = getline(strip_crlf);
50*c2c66affSColin Finck // indicate that we're done *if*:
51*c2c66affSColin Finck // 1) there's no more data, *and*
52*c2c66affSColin Finck // 2) we're at the end of the file
53*c2c66affSColin Finck return line.size()>0 || !eof();
54*c2c66affSColin Finck }
55*c2c66affSColin Finck
56*c2c66affSColin Finck /*
57*c2c66affSColin Finck example usage:
58*c2c66affSColin Finck
59*c2c66affSColin Finck bool mycallback ( const std::string& line, int line_number, long lparam )
60*c2c66affSColin Finck {
61*c2c66affSColin Finck std::cout << line << std::endl;
62*c2c66affSColin Finck return true; // continue enumeration
63*c2c66affSColin Finck }
64*c2c66affSColin Finck
65*c2c66affSColin Finck File f ( "file.txt", "rb" ); // open file for binary read-only ( i.e. "rb" )
66*c2c66affSColin Finck f.enum_lines ( mycallback, 0, true );
67*c2c66affSColin Finck */
68*c2c66affSColin Finck
enum_lines(bool (* callback)(const std::string & line,int line_number,long lparam),long lparam,bool strip_crlf)69*c2c66affSColin Finck bool File::enum_lines ( bool (*callback)(const std::string& line, int line_number, long lparam), long lparam, bool strip_crlf )
70*c2c66affSColin Finck {
71*c2c66affSColin Finck int line_number = 0;
72*c2c66affSColin Finck for ( ;; )
73*c2c66affSColin Finck {
74*c2c66affSColin Finck std::string s = getline(strip_crlf);
75*c2c66affSColin Finck line_number++;
76*c2c66affSColin Finck if ( !s.size() )
77*c2c66affSColin Finck {
78*c2c66affSColin Finck if ( eof() )
79*c2c66affSColin Finck return true;
80*c2c66affSColin Finck else
81*c2c66affSColin Finck continue;
82*c2c66affSColin Finck }
83*c2c66affSColin Finck if ( !(*callback) ( s, line_number, lparam ) )
84*c2c66affSColin Finck return false;
85*c2c66affSColin Finck }
86*c2c66affSColin Finck }
87*c2c66affSColin Finck
length()88*c2c66affSColin Finck size_t File::length()
89*c2c66affSColin Finck {
90*c2c66affSColin Finck #ifdef WIN32
91*c2c66affSColin Finck return _filelength ( _fileno(_f) );
92*c2c66affSColin Finck #elif defined(UNIX)
93*c2c66affSColin Finck struct stat file_stat;
94*c2c66affSColin Finck verify(fstat(fileno(_f), &file_stat) == 0);
95*c2c66affSColin Finck return file_stat.st_size;
96*c2c66affSColin Finck #endif
97*c2c66affSColin Finck }
98*c2c66affSColin Finck
close()99*c2c66affSColin Finck void File::close()
100*c2c66affSColin Finck {
101*c2c66affSColin Finck if ( _f )
102*c2c66affSColin Finck {
103*c2c66affSColin Finck fclose(_f);
104*c2c66affSColin Finck _f = 0;
105*c2c66affSColin Finck }
106*c2c66affSColin Finck }
107*c2c66affSColin Finck
LoadIntoString(std::string & s,const char * filename)108*c2c66affSColin Finck /*static*/ bool File::LoadIntoString ( std::string& s, const char* filename )
109*c2c66affSColin Finck {
110*c2c66affSColin Finck File in ( filename, "rb" );
111*c2c66affSColin Finck if ( !in.isopened() )
112*c2c66affSColin Finck return false;
113*c2c66affSColin Finck size_t len = in.length();
114*c2c66affSColin Finck s.resize ( len + 1 );
115*c2c66affSColin Finck if ( !in.read ( &s[0], len ) )
116*c2c66affSColin Finck return false;
117*c2c66affSColin Finck s[len] = '\0';
118*c2c66affSColin Finck s.resize ( len );
119*c2c66affSColin Finck return true;
120*c2c66affSColin Finck }
121*c2c66affSColin Finck
SaveFromString(const char * filename,const std::string & s,bool binary)122*c2c66affSColin Finck /*static*/ bool File::SaveFromString ( const char* filename, const std::string& s, bool binary )
123*c2c66affSColin Finck {
124*c2c66affSColin Finck File out ( filename, binary ? "wb" : "w" );
125*c2c66affSColin Finck if ( !out.isopened() )
126*c2c66affSColin Finck return false;
127*c2c66affSColin Finck out.write ( s.c_str(), s.size() );
128*c2c66affSColin Finck return true;
129*c2c66affSColin Finck }
130