1 ////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // Nestopia - NES/Famicom emulator written in C++
4 //
5 // Copyright (C) 2003-2008 Martin Freij
6 //
7 // This file is part of Nestopia.
8 //
9 // Nestopia is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // Nestopia is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with Nestopia; if not, write to the Free Software
21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 //
23 ////////////////////////////////////////////////////////////////////////////////////////
24 
25 #ifndef NST_IO_FILE_H
26 #define NST_IO_FILE_H
27 
28 #pragma once
29 
30 #include "language/resource.h"
31 #include "NstString.hpp"
32 
33 namespace Nestopia
34 {
35 	namespace Io
36 	{
37 		class File
38 		{
39 		public:
40 
41 			enum
42 			{
43 				READ = 0x01,
44 				WRITE = 0x02,
45 				EMPTY = 0x04,
46 				EXISTING = 0x08,
47 				SEQUENTIAL_ACCESS = 0x10,
48 				RANDOM_ACCESS = 0x20,
49 				WRITE_THROUGH = 0x40,
50 				COLLECT = READ|EXISTING|SEQUENTIAL_ACCESS,
51 				DUMP = WRITE|EMPTY|SEQUENTIAL_ACCESS
52 			};
53 
54 			enum
55 			{
56 				UTF16_LE = 0xFEFF,
57 				UTF16_BE = 0xFFFE
58 			};
59 
60 			enum
61 			{
62 				MAX_SIZE = 0x7FFFFFFF
63 			};
64 
65 			enum Offset
66 			{
67 				BEGIN,
68 				CURRENT,
69 				END
70 			};
71 
72 			enum Exception
73 			{
74 				ERR_READ = IDS_FILE_ERR_READ,
75 				ERR_WRITE = IDS_FILE_ERR_WRITE,
76 				ERR_SEEK = IDS_FILE_ERR_READ,
77 				ERR_OPEN = IDS_FILE_ERR_OPEN,
78 				ERR_NOT_FOUND = IDS_FILE_ERR_NOTFOUND,
79 				ERR_ALREADY_EXISTS = IDS_FILE_ERR_ALREADYEXISTS,
80 				ERR_READ_ONLY = IDS_FILE_ERR_READONLY,
81 				ERR_TOO_BIG = IDS_FILE_ERR_TOOBIG
82 			};
83 
84 			File();
85 			File(GenericString,uint);
86 			~File();
87 
88 			void Open(GenericString,uint);
89 			void Close();
90 			uint Seek(Offset,int=0) const;
91 			void Truncate() const;
92 			void Truncate(uint) const;
93 			void Flush() const;
94 			uint Size() const;
95 
96 			void Write     (const void*,uint) const;
97 			uint WriteSome (const void*,uint) const;
98 			void Write8    (uint) const;
99 			void Write16   (uint) const;
100 			void Write32   (uint) const;
101 			void Read      (void*,uint) const;
102 			uint ReadSome  (void*,uint) const;
103 			uint Read8     () const;
104 			uint Read16    () const;
105 			uint Read32    () const;
106 			void Peek      (void*,uint) const;
107 			void Peek      (uint,void*,uint) const;
108 			uint Peek8     () const;
109 			uint Peek16    () const;
110 			uint Peek32    () const;
111 
112 			void ReadText (String::Heap<char>&) const;
113 			void ReadText (String::Heap<wchar_t>&) const;
114 			void WriteText (cstring,uint,bool=false) const;
115 			void WriteText (wcstring,uint,bool=false) const;
116 
117 			static void ParseText (cstring,uint,String::Heap<char>&);
118 			static void ParseText (cstring,uint,String::Heap<wchar_t>&);
119 
120 		private:
121 
122 			class Proxy
123 			{
124 				const File& file;
125 
126 			public:
127 
Proxy(const File & file)128 				Proxy(const File& file)
129 				: file(file) {}
130 
operator =(int pos) const131 				void operator = (int pos) const
132 				{
133 					file.Seek( BEGIN, pos );
134 				}
135 
operator +=(int count) const136 				void operator += (int count) const
137 				{
138 					file.Seek( CURRENT, count );
139 				}
140 
operator -=(int count) const141 				void operator -= (int count) const
142 				{
143 					file.Seek( CURRENT, -count );
144 				}
145 
operator uint() const146 				operator uint () const
147 				{
148 					return file.Seek( CURRENT );
149 				}
150 			};
151 
152 			class StreamProxy
153 			{
154 				const File& file;
155 
156 			public:
157 
StreamProxy(const File & f)158 				StreamProxy(const File& f)
159 				: file(f) {}
160 
161 				template<typename T>
operator <<(const T & buffer) const162 				const StreamProxy& operator << (const T& buffer) const
163 				{
164 					NST_COMPILE_ASSERT( sizeof(buffer[0]) == sizeof(char) );
165 					file.Write( buffer.Ptr(), buffer.Length() );
166 					return *this;
167 				}
168 
operator >>(T & buffer) const169 				template<typename T> void operator >> (T& buffer) const
170 				{
171 					NST_COMPILE_ASSERT( sizeof(buffer[0]) == sizeof(char) );
172 					buffer.Resize( file.Size() - file.Position() );
173 					file.Read( buffer.Ptr(), buffer.Length() );
174 				}
175 			};
176 
177 			void* handle;
178 			Path name;
179 
180 		public:
181 
IsOpen() const182 			bool IsOpen() const
183 			{
184 				return handle;
185 			}
186 
GetName() const187 			const Path& GetName() const
188 			{
189 				return name;
190 			}
191 
Stream() const192 			StreamProxy Stream() const
193 			{
194 				return *this;
195 			}
196 
Position() const197 			Proxy Position() const
198 			{
199 				return *this;
200 			}
201 
Rewind() const202 			void Rewind() const
203 			{
204 				Seek( BEGIN );
205 			}
206 
207 			static bool Delete(wcstring);
208 		};
209 	}
210 }
211 
212 #endif
213