Browse code

Use std::filesystem::path for reading/writing files.

Also remove fstream_wfopen.h as it is no longer needed.
Also make XSFFile not store the string of the path but store the path as std::filesystem::path.

Naram Qashat authored on 2021/04/05 00:20:56
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,763 +0,0 @@
1
-// This comes from llvm's libcxx project. I've copied the code from there (with heavy modifications) for use with MinGW to support opening Windows "Unicode" filenames.
2
-
3
-#if defined(_WIN32) && !defined(_MSC_VER)
4
-#pragma once
5
-
6
-#include <streambuf>
7
-#include <locale>
8
-#include <memory>
9
-#include <fstream>
10
-
11
-class filebuf_wfopen : public std::filebuf
12
-{
13
-public:
14
-	typedef typename traits_type::state_type state_type;
15
-
16
-	// 27.9.1.2 Constructors/destructor:
17
-	filebuf_wfopen() : __extbuf_(nullptr), __extbufnext_(nullptr), __extbufend_(nullptr), __ebs_(0),
18
-		__intbuf_(nullptr), __ibs_(0), __file_(nullptr), __cv_(nullptr), __st_(), __st_last_(),
19
-		__om_(static_cast<std::ios_base::openmode>(0)), __cm_(static_cast<std::ios_base::openmode>(0)),
20
-		__owns_eb_(false), __owns_ib_(false), __always_noconv_(false)
21
-	{
22
-		if (std::has_facet<std::codecvt<char, char, state_type>>(this->getloc()))
23
-		{
24
-			this->__cv_ = &std::use_facet<std::codecvt<char, char, state_type>>(this->getloc());
25
-			this->__always_noconv_ = this->__cv_->always_noconv();
26
-		}
27
-		this->setbuf(nullptr, 4096);
28
-	}
29
-
30
-	virtual ~filebuf_wfopen()
31
-	{
32
-		try
33
-		{
34
-			this->close();
35
-		}
36
-		catch (...)
37
-		{
38
-		}
39
-		if (this->__owns_eb_)
40
-			delete[] this->__extbuf_;
41
-		if (this->__owns_ib_)
42
-			delete[] this->__intbuf_;
43
-	}
44
-
45
-	// 27.9.1.4 Members:
46
-	bool is_open() const
47
-	{
48
-		return !!this->__file_;
49
-	}
50
-	filebuf_wfopen *open(const char *__s, std::ios_base::openmode __mode)
51
-	{
52
-		filebuf_wfopen *__rt = nullptr;
53
-		if (!this->__file_)
54
-		{
55
-			__rt = this;
56
-			const char *__mdstr = nullptr;
57
-			switch (__mode & ~std::ios_base::ate)
58
-			{
59
-				case std::ios_base::out:
60
-				case std::ios_base::out | std::ios_base::trunc:
61
-					__mdstr = "w";
62
-					break;
63
-				case std::ios_base::out | std::ios_base::app:
64
-				case std::ios_base::app:
65
-					__mdstr = "a";
66
-					break;
67
-				case std::ios_base::in:
68
-					__mdstr = "r";
69
-					break;
70
-				case std::ios_base::in | std::ios_base::out:
71
-					__mdstr = "r+";
72
-					break;
73
-				case std::ios_base::in | std::ios_base::out | std::ios_base::trunc:
74
-					__mdstr = "w+";
75
-					break;
76
-				case std::ios_base::in | std::ios_base::out | std::ios_base::app:
77
-				case std::ios_base::in | std::ios_base::app:
78
-					__mdstr = "a+";
79
-					break;
80
-				case std::ios_base::out | std::ios_base::binary:
81
-				case std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
82
-					__mdstr = "wb";
83
-					break;
84
-				case std::ios_base::out | std::ios_base::app | std::ios_base::binary:
85
-				case std::ios_base::app | std::ios_base::binary:
86
-					__mdstr = "ab";
87
-					break;
88
-				case std::ios_base::in | std::ios_base::binary:
89
-					__mdstr = "rb";
90
-					break;
91
-				case std::ios_base::in | std::ios_base::out | std::ios_base::binary:
92
-					__mdstr = "r+b";
93
-					break;
94
-				case std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
95
-					__mdstr = "w+b";
96
-					break;
97
-				case std::ios_base::in | std::ios_base::out | std::ios_base::app | std::ios_base::binary:
98
-				case std::ios_base::in | std::ios_base::app | std::ios_base::binary:
99
-					__mdstr = "a+b";
100
-					break;
101
-				default:
102
-					__rt = nullptr;
103
-			}
104
-			if (__rt)
105
-			{
106
-				this->__file_ = fopen(__s, __mdstr);
107
-				if (this->__file_)
108
-				{
109
-					this->__om_ = __mode;
110
-					if ((__mode & std::ios_base::ate) && fseek(this->__file_, 0, SEEK_END))
111
-					{
112
-						fclose(this->__file_);
113
-						this->__file_ = nullptr;
114
-						__rt = nullptr;
115
-					}
116
-				}
117
-				else
118
-					__rt = nullptr;
119
-			}
120
-		}
121
-		return __rt;
122
-	}
123
-	filebuf_wfopen *open(const std::string &__s, std::ios_base::openmode __mode)
124
-	{
125
-		return this->open(__s.c_str(), __mode);
126
-	}
127
-	filebuf_wfopen *open(const wchar_t *__s, std::ios_base::openmode __mode)
128
-	{
129
-		filebuf_wfopen *__rt = nullptr;
130
-		if (!this->__file_)
131
-		{
132
-			__rt = this;
133
-			const wchar_t *__mdstr = nullptr;
134
-			switch (__mode & ~std::ios_base::ate)
135
-			{
136
-				case std::ios_base::out:
137
-				case std::ios_base::out | std::ios_base::trunc:
138
-					__mdstr = L"w";
139
-					break;
140
-				case std::ios_base::out | std::ios_base::app:
141
-				case std::ios_base::app:
142
-					__mdstr = L"a";
143
-					break;
144
-				case std::ios_base::in:
145
-					__mdstr = L"r";
146
-					break;
147
-				case std::ios_base::in | std::ios_base::out:
148
-					__mdstr = L"r+";
149
-					break;
150
-				case std::ios_base::in | std::ios_base::out | std::ios_base::trunc:
151
-					__mdstr = L"w+";
152
-					break;
153
-				case std::ios_base::in | std::ios_base::out | std::ios_base::app:
154
-				case std::ios_base::in | std::ios_base::app:
155
-					__mdstr = L"a+";
156
-					break;
157
-				case std::ios_base::out | std::ios_base::binary:
158
-				case std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
159
-					__mdstr = L"wb";
160
-					break;
161
-				case std::ios_base::out | std::ios_base::app | std::ios_base::binary:
162
-				case std::ios_base::app | std::ios_base::binary:
163
-					__mdstr = L"ab";
164
-					break;
165
-				case std::ios_base::in | std::ios_base::binary:
166
-					__mdstr = L"rb";
167
-					break;
168
-				case std::ios_base::in | std::ios_base::out | std::ios_base::binary:
169
-					__mdstr = L"r+b";
170
-					break;
171
-				case std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
172
-					__mdstr = L"w+b";
173
-					break;
174
-				case std::ios_base::in | std::ios_base::out | std::ios_base::app | std::ios_base::binary:
175
-				case std::ios_base::in | std::ios_base::app | std::ios_base::binary:
176
-					__mdstr = L"a+b";
177
-					break;
178
-				default:
179
-					__rt = nullptr;
180
-			}
181
-			if (__rt)
182
-			{
183
-				this->__file_ = _wfopen(__s, __mdstr);
184
-				if (this->__file_)
185
-				{
186
-					this->__om_ = __mode;
187
-					if ((__mode & std::ios_base::ate) && fseek(this->__file_, 0, SEEK_END))
188
-					{
189
-						fclose(this->__file_);
190
-						this->__file_ = nullptr;
191
-						__rt = nullptr;
192
-					}
193
-				}
194
-				else
195
-					__rt = nullptr;
196
-			}
197
-		}
198
-		return __rt;
199
-	}
200
-	filebuf_wfopen *open(const std::wstring &__s, std::ios_base::openmode __mode)
201
-	{
202
-		return this->open(__s.c_str(), __mode);
203
-	}
204
-	filebuf_wfopen *close()
205
-	{
206
-		filebuf_wfopen *__rt = nullptr;
207
-		if (this->__file_)
208
-		{
209
-			__rt = this;
210
-			std::unique_ptr<FILE, int (*)(FILE *)> __h(this->__file_, fclose);
211
-			if (this->sync())
212
-				__rt = nullptr;
213
-			if (!fclose(__h.release()))
214
-				this->__file_ = nullptr;
215
-			else
216
-				__rt = nullptr;
217
-		}
218
-		return __rt;
219
-	}
220
-
221
-protected:
222
-	// 27.9.1.5 Overridden virtual functions:
223
-	virtual int_type underflow()
224
-	{
225
-		if (!this->__file_)
226
-			return traits_type::eof();
227
-		bool __initial = this->__read_mode();
228
-		char __1buf;
229
-		if (!this->gptr())
230
-			this->setg(&__1buf, &__1buf + 1, &__1buf + 1);
231
-		const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);
232
-		int_type __c = traits_type::eof();
233
-		if (this->gptr() == this->egptr())
234
-		{
235
-			memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz);
236
-			if (this->__always_noconv_)
237
-			{
238
-				size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
239
-				__nmemb = fread(this->eback() + __unget_sz, 1, __nmemb, this->__file_);
240
-				if (__nmemb)
241
-				{
242
-					this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb);
243
-					__c = traits_type::to_int_type(*this->gptr());
244
-				}
245
-			}
246
-			else
247
-			{
248
-				memmove(this->__extbuf_, this->__extbufnext_, this->__extbufend_ - this->__extbufnext_);
249
-				this->__extbufnext_ = this->__extbuf_ + (this->__extbufend_ - this->__extbufnext_);
250
-				this->__extbufend_ = this->__extbuf_ +
251
-					(this->__extbuf_ == this->__extbuf_min_ ? sizeof(this->__extbuf_min_) : this->__ebs_);
252
-				size_t __nmemb = std::min<size_t>(this->__ibs_ - __unget_sz,
253
-					this->__extbufend_ - this->__extbufnext_);
254
-				std::codecvt_base::result __r;
255
-				this->__st_last_ = this->__st_;
256
-				size_t __nr = fread(const_cast<char *>(this->__extbufnext_), 1, __nmemb, this->__file_);
257
-				if (__nr)
258
-				{
259
-					if (!this->__cv_)
260
-						throw std::bad_cast();
261
-					this->__extbufend_ = this->__extbufnext_ + __nr;
262
-					char *__inext;
263
-					__r = this->__cv_->in(this->__st_, this->__extbuf_, this->__extbufend_, this->__extbufnext_,
264
-						this->eback() + __unget_sz, this->eback() + this->__ibs_, __inext);
265
-					if (__r == std::codecvt_base::noconv)
266
-					{
267
-						this->setg(this->__extbuf_, this->__extbuf_, const_cast<char *>(this->__extbufend_));
268
-						__c = traits_type::to_int_type(*this->gptr());
269
-					}
270
-					else if (__inext != this->eback() + __unget_sz)
271
-					{
272
-						this->setg(this->eback(), this->eback() + __unget_sz, __inext);
273
-						__c = traits_type::to_int_type(*this->gptr());
274
-					}
275
-				}
276
-			}
277
-		}
278
-		else
279
-			__c = traits_type::to_int_type(*this->gptr());
280
-		if (this->eback() == &__1buf)
281
-			this->setg(nullptr, nullptr, nullptr);
282
-		return __c;
283
-	}
284
-	virtual int_type pbackfail(int_type __c = traits_type::eof())
285
-	{
286
-		if (this->__file_ && this->eback() < this->gptr())
287
-		{
288
-			if (traits_type::eq_int_type(__c, traits_type::eof()))
289
-			{
290
-				this->gbump(-1);
291
-				return traits_type::not_eof(__c);
292
-			}
293
-			if ((this->__om_ & std::ios_base::out) ||
294
-				traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
295
-			{
296
-				this->gbump(-1);
297
-				*this->gptr() = traits_type::to_char_type(__c);
298
-				return __c;
299
-			}
300
-		}
301
-		return traits_type::eof();
302
-	}
303
-	virtual int_type overflow (int_type __c = traits_type::eof())
304
-	{
305
-		if (!this->__file_)
306
-			return traits_type::eof();
307
-		this->__write_mode();
308
-		char __1buf;
309
-		char *__pb_save = this->pbase();
310
-		char *__epb_save = this->epptr();
311
-		if (!traits_type::eq_int_type(__c, traits_type::eof()))
312
-		{
313
-			if (!this->pptr())
314
-				this->setp(&__1buf, &__1buf + 1);
315
-			*this->pptr() = traits_type::to_char_type(__c);
316
-			this->pbump(1);
317
-		}
318
-		if (this->pptr() != this->pbase())
319
-		{
320
-			if (this->__always_noconv_)
321
-			{
322
-				size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
323
-				if (fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
324
-					return traits_type::eof();
325
-			}
326
-			else
327
-			{
328
-				char *__extbe = this->__extbuf_;
329
-				std::codecvt_base::result __r;
330
-				do
331
-				{
332
-					if (!this->__cv_)
333
-						throw std::bad_cast();
334
-					const char *__e;
335
-					__r = this->__cv_->out(this->__st_, this->pbase(), this->pptr(), __e, this->__extbuf_,
336
-						this->__extbuf_ + this->__ebs_, __extbe);
337
-					if (__e == this->pbase())
338
-						return traits_type::eof();
339
-					if (__r == std::codecvt_base::noconv)
340
-					{
341
-						size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
342
-						if (fwrite(this->pbase(), 1, __nmemb, this->__file_) != __nmemb)
343
-							return traits_type::eof();
344
-					}
345
-					else if (__r == std::codecvt_base::ok || __r == std::codecvt_base::partial)
346
-					{
347
-						size_t __nmemb = static_cast<size_t>(__extbe - this->__extbuf_);
348
-						if (fwrite(this->__extbuf_, 1, __nmemb, this->__file_) != __nmemb)
349
-							return traits_type::eof();
350
-						if (__r == std::codecvt_base::partial)
351
-						{
352
-							this->setp(const_cast<char *>(__e), this->pptr());
353
-							this->pbump(this->epptr() - this->pbase());
354
-						}
355
-					}
356
-					else
357
-						return traits_type::eof();
358
-				} while (__r == std::codecvt_base::partial);
359
-			}
360
-			this->setp(__pb_save, __epb_save);
361
-		}
362
-		return traits_type::not_eof(__c);
363
-	}
364
-	virtual std::streambuf *setbuf(char *__s, std::streamsize __n)
365
-	{
366
-		this->setg(nullptr, nullptr, nullptr);
367
-		this->setp(nullptr, nullptr);
368
-		if (this->__owns_eb_)
369
-			delete[] this->__extbuf_;
370
-		if (this->__owns_ib_)
371
-			delete[] this->__intbuf_;
372
-		this->__ebs_ = __n;
373
-		if (this->__ebs_ > sizeof(this->__extbuf_min_))
374
-		{
375
-			if (this->__always_noconv_ && __s)
376
-			{
377
-				this->__extbuf_ = __s;
378
-				this->__owns_eb_ = false;
379
-			}
380
-			else
381
-			{
382
-				this->__extbuf_ = new char[this->__ebs_];
383
-				this->__owns_eb_ = true;
384
-			}
385
-		}
386
-		else
387
-		{
388
-			this->__extbuf_ = this->__extbuf_min_;
389
-			this->__ebs_ = sizeof(this->__extbuf_min_);
390
-			this->__owns_eb_ = false;
391
-		}
392
-		if (!this->__always_noconv_)
393
-		{
394
-			this->__ibs_ = std::max<std::streamsize>(__n, sizeof(this->__extbuf_min_));
395
-			if (__s && this->__ibs_ >= sizeof(this->__extbuf_min_))
396
-			{
397
-				this->__intbuf_ = __s;
398
-				this->__owns_ib_ = false;
399
-			}
400
-			else
401
-			{
402
-				this->__intbuf_ = new char[this->__ibs_];
403
-				this->__owns_ib_ = true;
404
-			}
405
-		}
406
-		else
407
-		{
408
-			this->__ibs_ = 0;
409
-			this->__intbuf_ = nullptr;
410
-			this->__owns_ib_ = false;
411
-		}
412
-		return this;
413
-	}
414
-	virtual pos_type seekoff(off_type __off, std::ios_base::seekdir __way,
415
-		std::ios_base::openmode = std::ios_base::in | std::ios_base::out)
416
-	{
417
-		if (!this->__cv_)
418
-			throw std::bad_cast();
419
-		int __width = this->__cv_->encoding();
420
-		if (!this->__file_ || (__width <= 0 && __off) || this->sync())
421
-			return pos_type(off_type(-1));
422
-		// __width > 0 || __off == 0
423
-		int __whence;
424
-		switch (__way)
425
-		{
426
-			case std::ios_base::beg:
427
-				__whence = SEEK_SET;
428
-				break;
429
-			case std::ios_base::cur:
430
-				__whence = SEEK_CUR;
431
-				break;
432
-			case std::ios_base::end:
433
-				__whence = SEEK_END;
434
-				break;
435
-			default:
436
-				return pos_type(off_type(-1));
437
-		}
438
-		if (fseek(this->__file_, __width > 0 ? __width * __off : 0, __whence))
439
-			return pos_type(off_type(-1));
440
-		pos_type __r = ftell(this->__file_);
441
-		__r.state(this->__st_);
442
-		return __r;
443
-	}
444
-	virtual pos_type seekpos(pos_type __sp,
445
-		std::ios_base::openmode = std::ios_base::in | std::ios_base::out)
446
-	{
447
-		if (!this->__file_ || this->sync())
448
-			return pos_type(off_type(-1));
449
-		if (fseek(this->__file_, __sp, SEEK_SET))
450
-			return pos_type(off_type(-1));
451
-		this->__st_ = __sp.state();
452
-		return __sp;
453
-	}
454
-	virtual int sync()
455
-	{
456
-		if (!this->__file_)
457
-			return 0;
458
-		if (!this->__cv_)
459
-			throw std::bad_cast();
460
-		if (this->__cm_ & std::ios_base::out)
461
-		{
462
-			if (this->pptr() != this->pbase() && this->overflow() == traits_type::eof())
463
-				return -1;
464
-			std::codecvt_base::result __r;
465
-			do
466
-			{
467
-				char *__extbe;
468
-				__r = this->__cv_->unshift(this->__st_, this->__extbuf_, this->__extbuf_ + this->__ebs_,
469
-					__extbe);
470
-				size_t __nmemb = static_cast<size_t>(__extbe - this->__extbuf_);
471
-				if (fwrite(this->__extbuf_, 1, __nmemb, this->__file_) != __nmemb)
472
-					return -1;
473
-			} while (__r == std::codecvt_base::partial);
474
-			if (__r == std::codecvt_base::error)
475
-				return -1;
476
-			if (fflush(this->__file_))
477
-				return -1;
478
-		}
479
-		else if (this->__cm_ & std::ios_base::in)
480
-		{
481
-			off_type __c;
482
-			state_type __state = this->__st_last_;
483
-			bool __update_st = false;
484
-			if (this->__always_noconv_)
485
-				__c = this->egptr() - this->gptr();
486
-			else
487
-			{
488
-				int __width = this->__cv_->encoding();
489
-				__c = this->__extbufend_ - this->__extbufnext_;
490
-				if (__width > 0)
491
-					__c += __width * (this->egptr() - this->gptr());
492
-				else if (this->gptr() != this->egptr())
493
-				{
494
-					int __off =  this->__cv_->length(__state, this->__extbuf_, this->__extbufnext_,
495
-						this->gptr() - this->eback());
496
-					__c += this->__extbufnext_ - this->__extbuf_ - __off;
497
-					__update_st = true;
498
-				}
499
-			}
500
-			if (fseek(this->__file_, -__c, SEEK_CUR))
501
-				return -1;
502
-			if (__update_st)
503
-				this->__st_ = __state;
504
-			this->__extbufnext_ = this->__extbufend_ = this->__extbuf_;
505
-			this->setg(nullptr, nullptr, nullptr);
506
-			this->__cm_ = static_cast<std::ios_base::openmode>(0);
507
-		}
508
-		return 0;
509
-	}
510
-	virtual void imbue(const std::locale &__loc)
511
-	{
512
-		this->sync();
513
-		this->__cv_ = &std::use_facet<std::codecvt<char, char, state_type>>(__loc);
514
-		bool __old_anc = this->__always_noconv_;
515
-		this->__always_noconv_ = this->__cv_->always_noconv();
516
-		if (__old_anc != this->__always_noconv_)
517
-		{
518
-			this->setg(nullptr, nullptr, nullptr);
519
-			this->setp(nullptr, nullptr);
520
-			// invariant, char_type is char, else we couldn't get here
521
-			if (this->__always_noconv_) // need to dump __intbuf_
522
-			{
523
-				if (this->__owns_eb_)
524
-					delete[] this->__extbuf_;
525
-				this->__owns_eb_ = this->__owns_ib_;
526
-				this->__ebs_ = this->__ibs_;
527
-				this->__extbuf_ = this->__intbuf_;
528
-				this->__ibs_ = 0;
529
-				this->__intbuf_ = nullptr;
530
-				this->__owns_ib_ = false;
531
-			}
532
-			// need to obtain an __intbuf_.
533
-			else if (!this->__owns_eb_ && this->__extbuf_ != this->__extbuf_min_)
534
-				// If __extbuf_ is user-supplied, use it, else new __intbuf_
535
-			{
536
-				this->__ibs_ = this->__ebs_;
537
-				this->__intbuf_ = this->__extbuf_;
538
-				this->__owns_ib_ = false;
539
-				this->__extbuf_ = new char[this->__ebs_];
540
-				this->__owns_eb_ = true;
541
-			}
542
-			else
543
-			{
544
-				this->__ibs_ = this->__ebs_;
545
-				this->__intbuf_ = new char[this->__ibs_];
546
-				this->__owns_ib_ = true;
547
-			}
548
-		}
549
-	}
550
-
551
-private:
552
-	char *__extbuf_;
553
-	const char *__extbufnext_;
554
-	const char *__extbufend_;
555
-	char __extbuf_min_[8];
556
-	size_t __ebs_;
557
-	char *__intbuf_;
558
-	size_t __ibs_;
559
-	FILE *__file_;
560
-	const std::codecvt<char, char, state_type> *__cv_;
561
-	state_type __st_;
562
-	state_type __st_last_;
563
-	std::ios_base::openmode __om_;
564
-	std::ios_base::openmode __cm_;
565
-	bool __owns_eb_;
566
-	bool __owns_ib_;
567
-	bool __always_noconv_;
568
-
569
-	bool __read_mode()
570
-	{
571
-		if (!(this->__cm_ & std::ios_base::in))
572
-		{
573
-			this->setp(nullptr, nullptr);
574
-			if (this->__always_noconv_)
575
-				this->setg(this->__extbuf_, this->__extbuf_ + this->__ebs_, this->__extbuf_ + this->__ebs_);
576
-			else
577
-				this->setg(this->__intbuf_, this->__intbuf_ + this->__ibs_, this->__intbuf_ + this->__ibs_);
578
-			this->__cm_ = std::ios_base::in;
579
-			return true;
580
-		}
581
-		return false;
582
-	}
583
-	void __write_mode()
584
-	{
585
-		if (!(this->__cm_ & std::ios_base::out))
586
-		{
587
-			this->setg(nullptr, nullptr, nullptr);
588
-			if (this->__ebs_ > sizeof(this->__extbuf_min_))
589
-			{
590
-				if (this->__always_noconv_)
591
-					this->setp(this->__extbuf_, this->__extbuf_ + (this->__ebs_ - 1));
592
-				else
593
-					this->setp(this->__intbuf_, this->__intbuf_ + (this->__ibs_ - 1));
594
-			}
595
-			else
596
-				this->setp(nullptr, nullptr);
597
-			this->__cm_ = std::ios_base::out;
598
-		}
599
-	}
600
-};
601
-
602
-// basic_ifstream
603
-
604
-class ifstream_wfopen : public std::ifstream
605
-{
606
-public:
607
-	ifstream_wfopen() { std::ios::rdbuf(&this->__sb_); }
608
-	explicit ifstream_wfopen(const char *__s, std::ios_base::openmode __mode = std::ios_base::in)
609
-	{
610
-		if (this->__sb_.open(__s, __mode | std::ios_base::in))
611
-			std::ios::rdbuf(&this->__sb_);
612
-		else
613
-			this->setstate(std::ios_base::failbit);
614
-	}
615
-	explicit ifstream_wfopen(const std::string &__s, std::ios_base::openmode __mode = std::ios_base::in)
616
-	{
617
-		if (this->__sb_.open(__s, __mode | std::ios_base::in))
618
-			std::ios::rdbuf(&this->__sb_);
619
-		else
620
-			this->setstate(std::ios_base::failbit);
621
-	}
622
-	explicit ifstream_wfopen(const wchar_t *__s, std::ios_base::openmode __mode = std::ios_base::in)
623
-	{
624
-		if (this->__sb_.open(__s, __mode | std::ios_base::in))
625
-			std::ios::rdbuf(&this->__sb_);
626
-		else
627
-			this->setstate(std::ios_base::failbit);
628
-	}
629
-	explicit ifstream_wfopen(const std::wstring &__s, std::ios_base::openmode __mode = std::ios_base::in)
630
-	{
631
-		if (this->__sb_.open(__s, __mode | std::ios_base::in))
632
-			std::ios::rdbuf(&this->__sb_);
633
-		else
634
-			this->setstate(std::ios_base::failbit);
635
-	}
636
-
637
-	std::filebuf *rdbuf() const
638
-	{
639
-		return const_cast<std::filebuf *>(static_cast<const std::filebuf *>(&this->__sb_));
640
-	}
641
-	bool is_open() const
642
-	{
643
-		return this->__sb_.is_open();
644
-	}
645
-	void open(const char *__s, std::ios_base::openmode __mode = std::ios_base::in)
646
-	{
647
-		if (this->__sb_.open(__s, __mode | std::ios_base::in))
648
-			this->clear();
649
-		else
650
-			this->setstate(std::ios_base::failbit);
651
-	}
652
-	void open(const std::string &__s, std::ios_base::openmode __mode = std::ios_base::in)
653
-	{
654
-		if (this->__sb_.open(__s, __mode | std::ios_base::in))
655
-			this->clear();
656
-		else
657
-			this->setstate(std::ios_base::failbit);
658
-	}
659
-	void open(const wchar_t *__s, std::ios_base::openmode __mode = std::ios_base::in)
660
-	{
661
-		if (this->__sb_.open(__s, __mode | std::ios_base::in))
662
-			this->clear();
663
-		else
664
-			this->setstate(std::ios_base::failbit);
665
-	}
666
-	void open(const std::wstring &__s, std::ios_base::openmode __mode = std::ios_base::in)
667
-	{
668
-		if (this->__sb_.open(__s, __mode | std::ios_base::in))
669
-			this->clear();
670
-		else
671
-			this->setstate(std::ios_base::failbit);
672
-	}
673
-	void close()
674
-	{
675
-		if (!this->__sb_.close())
676
-			this->setstate(std::ios_base::failbit);
677
-	}
678
-
679
-private:
680
-	filebuf_wfopen __sb_;
681
-};
682
-
683
-// basic_ofstream
684
-
685
-class ofstream_wfopen : public std::ofstream
686
-{
687
-public:
688
-	ofstream_wfopen() { std::ios::rdbuf(&this->__sb_); }
689
-	explicit ofstream_wfopen(const char *__s, std::ios_base::openmode __mode = std::ios_base::out)
690
-	{
691
-		if (this->__sb_.open(__s, __mode | std::ios_base::out))
692
-			std::ios::rdbuf(&this->__sb_);
693
-		else
694
-			this->setstate(std::ios_base::failbit);
695
-	}
696
-	explicit ofstream_wfopen(const std::string &__s, std::ios_base::openmode __mode = std::ios_base::out)
697
-	{
698
-		if (this->__sb_.open(__s, __mode | std::ios_base::out))
699
-			std::ios::rdbuf(&this->__sb_);
700
-		else
701
-			this->setstate(std::ios_base::failbit);
702
-	}
703
-	explicit ofstream_wfopen(const wchar_t *__s, std::ios_base::openmode __mode = std::ios_base::out)
704
-	{
705
-		if (this->__sb_.open(__s, __mode | std::ios_base::out))
706
-			std::ios::rdbuf(&this->__sb_);
707
-		else
708
-			this->setstate(std::ios_base::failbit);
709
-	}
710
-	explicit ofstream_wfopen(const std::wstring &__s, std::ios_base::openmode __mode = std::ios_base::out)
711
-	{
712
-		if (!this->__sb_.open(__s, __mode | std::ios_base::out))
713
-			std::ios::rdbuf(&this->__sb_);
714
-		else
715
-			this->setstate(std::ios_base::failbit);
716
-	}
717
-
718
-	std::filebuf *rdbuf() const
719
-	{
720
-		return const_cast<std::filebuf *>(static_cast<const std::filebuf *>(&this->__sb_));
721
-	}
722
-	bool is_open() const
723
-	{
724
-		return this->__sb_.is_open();
725
-	}
726
-	void open(const char *__s, std::ios_base::openmode __mode = std::ios_base::out)
727
-	{
728
-		if (this->__sb_.open(__s, __mode | std::ios_base::out))
729
-			this->clear();
730
-		else
731
-			this->setstate(std::ios_base::failbit);
732
-	}
733
-	void open(const std::string &__s, std::ios_base::openmode __mode = std::ios_base::out)
734
-	{
735
-		if (this->__sb_.open(__s, __mode | std::ios_base::out))
736
-			this->clear();
737
-		else
738
-			this->setstate(std::ios_base::failbit);
739
-	}
740
-	void open(const wchar_t *__s, std::ios_base::openmode __mode = std::ios_base::out)
741
-	{
742
-		if (this->__sb_.open(__s, __mode | std::ios_base::out))
743
-			this->clear();
744
-		else
745
-			this->setstate(std::ios_base::failbit);
746
-	}
747
-	void open(const std::wstring &__s, std::ios_base::openmode __mode = std::ios_base::out)
748
-	{
749
-		if (this->__sb_.open(__s, __mode | std::ios_base::out))
750
-			this->clear();
751
-		else
752
-			this->setstate(std::ios_base::failbit);
753
-	}
754
-	void close()
755
-	{
756
-		if (!this->__sb_.close())
757
-			this->setstate(std::ios_base::failbit);
758
-	}
759
-
760
-private:
761
-	filebuf_wfopen __sb_;
762
-};
763
-#endif
Browse code

* Small Makefile changes.

* Removed a couple files that were not being used.
* Cleanups found with clang's -Weverything (and shutting it up about a
lot of things that were ridiculous, as well as ignoring some of the
warnings still coming up).

Naram Qashat authored on 2014/09/25 12:28:21
Showing 1 changed files
... ...
@@ -53,7 +53,7 @@ public:
53 53
 		if (!this->__file_)
54 54
 		{
55 55
 			__rt = this;
56
-			const char *__mdstr;
56
+			const char *__mdstr = nullptr;
57 57
 			switch (__mode & ~std::ios_base::ate)
58 58
 			{
59 59
 				case std::ios_base::out:
... ...
@@ -130,7 +130,7 @@ public:
130 130
 		if (!this->__file_)
131 131
 		{
132 132
 			__rt = this;
133
-			const wchar_t *__mdstr;
133
+			const wchar_t *__mdstr = nullptr;
134 134
 			switch (__mode & ~std::ios_base::ate)
135 135
 			{
136 136
 				case std::ios_base::out:
Browse code

Lots of changes in regards to strings, as follows:

* Removed my custom String class, as well as removed the really old
Unicode ConvertUTF, the UTF Converter, and the UTF Encode/Decode
functions.
* Replaced the above with using standard C++ std::wstring_convert and
std::codecvt_utf8.
* Added headers adapted from llvm's libc++ project for allowing the
above C++ classes to exist with GCC and Clang when libc++ isn't being
used.
* Used std::string over std::wstring whenever possible.
* Added header adapted from llvm's libc++ project to create special
versions of the ifstream and ofstream classes that would utilize _wfopen
on non-MSVC Windows compilers, so those compilers could access files on
Windows that use characters outside the current codepage.
* Removed the -static-libgcc and -static-libstdc++ flags from the
Makefile for non-MSVC builds. The generated DLLs will require extra DLLs
from either Cygwin or MinGW (whichever is used to compile), I've only
tested with MinGW and for some reason they crash Winamp on exit, I have
no idea why.

Naram Qashat authored on 2014/09/24 13:58:55
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,763 @@
1
+// This comes from llvm's libcxx project. I've copied the code from there (with heavy modifications) for use with MinGW to support opening Windows "Unicode" filenames.
2
+
3
+#if defined(_WIN32) && !defined(_MSC_VER)
4
+#pragma once
5
+
6
+#include <streambuf>
7
+#include <locale>
8
+#include <memory>
9
+#include <fstream>
10
+
11
+class filebuf_wfopen : public std::filebuf
12
+{
13
+public:
14
+	typedef typename traits_type::state_type state_type;
15
+
16
+	// 27.9.1.2 Constructors/destructor:
17
+	filebuf_wfopen() : __extbuf_(nullptr), __extbufnext_(nullptr), __extbufend_(nullptr), __ebs_(0),
18
+		__intbuf_(nullptr), __ibs_(0), __file_(nullptr), __cv_(nullptr), __st_(), __st_last_(),
19
+		__om_(static_cast<std::ios_base::openmode>(0)), __cm_(static_cast<std::ios_base::openmode>(0)),
20
+		__owns_eb_(false), __owns_ib_(false), __always_noconv_(false)
21
+	{
22
+		if (std::has_facet<std::codecvt<char, char, state_type>>(this->getloc()))
23
+		{
24
+			this->__cv_ = &std::use_facet<std::codecvt<char, char, state_type>>(this->getloc());
25
+			this->__always_noconv_ = this->__cv_->always_noconv();
26
+		}
27
+		this->setbuf(nullptr, 4096);
28
+	}
29
+
30
+	virtual ~filebuf_wfopen()
31
+	{
32
+		try
33
+		{
34
+			this->close();
35
+		}
36
+		catch (...)
37
+		{
38
+		}
39
+		if (this->__owns_eb_)
40
+			delete[] this->__extbuf_;
41
+		if (this->__owns_ib_)
42
+			delete[] this->__intbuf_;
43
+	}
44
+
45
+	// 27.9.1.4 Members:
46
+	bool is_open() const
47
+	{
48
+		return !!this->__file_;
49
+	}
50
+	filebuf_wfopen *open(const char *__s, std::ios_base::openmode __mode)
51
+	{
52
+		filebuf_wfopen *__rt = nullptr;
53
+		if (!this->__file_)
54
+		{
55
+			__rt = this;
56
+			const char *__mdstr;
57
+			switch (__mode & ~std::ios_base::ate)
58
+			{
59
+				case std::ios_base::out:
60
+				case std::ios_base::out | std::ios_base::trunc:
61
+					__mdstr = "w";
62
+					break;
63
+				case std::ios_base::out | std::ios_base::app:
64
+				case std::ios_base::app:
65
+					__mdstr = "a";
66
+					break;
67
+				case std::ios_base::in:
68
+					__mdstr = "r";
69
+					break;
70
+				case std::ios_base::in | std::ios_base::out:
71
+					__mdstr = "r+";
72
+					break;
73
+				case std::ios_base::in | std::ios_base::out | std::ios_base::trunc:
74
+					__mdstr = "w+";
75
+					break;
76
+				case std::ios_base::in | std::ios_base::out | std::ios_base::app:
77
+				case std::ios_base::in | std::ios_base::app:
78
+					__mdstr = "a+";
79
+					break;
80
+				case std::ios_base::out | std::ios_base::binary:
81
+				case std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
82
+					__mdstr = "wb";
83
+					break;
84
+				case std::ios_base::out | std::ios_base::app | std::ios_base::binary:
85
+				case std::ios_base::app | std::ios_base::binary:
86
+					__mdstr = "ab";
87
+					break;
88
+				case std::ios_base::in | std::ios_base::binary:
89
+					__mdstr = "rb";
90
+					break;
91
+				case std::ios_base::in | std::ios_base::out | std::ios_base::binary:
92
+					__mdstr = "r+b";
93
+					break;
94
+				case std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
95
+					__mdstr = "w+b";
96
+					break;
97
+				case std::ios_base::in | std::ios_base::out | std::ios_base::app | std::ios_base::binary:
98
+				case std::ios_base::in | std::ios_base::app | std::ios_base::binary:
99
+					__mdstr = "a+b";
100
+					break;
101
+				default:
102
+					__rt = nullptr;
103
+			}
104
+			if (__rt)
105
+			{
106
+				this->__file_ = fopen(__s, __mdstr);
107
+				if (this->__file_)
108
+				{
109
+					this->__om_ = __mode;
110
+					if ((__mode & std::ios_base::ate) && fseek(this->__file_, 0, SEEK_END))
111
+					{
112
+						fclose(this->__file_);
113
+						this->__file_ = nullptr;
114
+						__rt = nullptr;
115
+					}
116
+				}
117
+				else
118
+					__rt = nullptr;
119
+			}
120
+		}
121
+		return __rt;
122
+	}
123
+	filebuf_wfopen *open(const std::string &__s, std::ios_base::openmode __mode)
124
+	{
125
+		return this->open(__s.c_str(), __mode);
126
+	}
127
+	filebuf_wfopen *open(const wchar_t *__s, std::ios_base::openmode __mode)
128
+	{
129
+		filebuf_wfopen *__rt = nullptr;
130
+		if (!this->__file_)
131
+		{
132
+			__rt = this;
133
+			const wchar_t *__mdstr;
134
+			switch (__mode & ~std::ios_base::ate)
135
+			{
136
+				case std::ios_base::out:
137
+				case std::ios_base::out | std::ios_base::trunc:
138
+					__mdstr = L"w";
139
+					break;
140
+				case std::ios_base::out | std::ios_base::app:
141
+				case std::ios_base::app:
142
+					__mdstr = L"a";
143
+					break;
144
+				case std::ios_base::in:
145
+					__mdstr = L"r";
146
+					break;
147
+				case std::ios_base::in | std::ios_base::out:
148
+					__mdstr = L"r+";
149
+					break;
150
+				case std::ios_base::in | std::ios_base::out | std::ios_base::trunc:
151
+					__mdstr = L"w+";
152
+					break;
153
+				case std::ios_base::in | std::ios_base::out | std::ios_base::app:
154
+				case std::ios_base::in | std::ios_base::app:
155
+					__mdstr = L"a+";
156
+					break;
157
+				case std::ios_base::out | std::ios_base::binary:
158
+				case std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
159
+					__mdstr = L"wb";
160
+					break;
161
+				case std::ios_base::out | std::ios_base::app | std::ios_base::binary:
162
+				case std::ios_base::app | std::ios_base::binary:
163
+					__mdstr = L"ab";
164
+					break;
165
+				case std::ios_base::in | std::ios_base::binary:
166
+					__mdstr = L"rb";
167
+					break;
168
+				case std::ios_base::in | std::ios_base::out | std::ios_base::binary:
169
+					__mdstr = L"r+b";
170
+					break;
171
+				case std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
172
+					__mdstr = L"w+b";
173
+					break;
174
+				case std::ios_base::in | std::ios_base::out | std::ios_base::app | std::ios_base::binary:
175
+				case std::ios_base::in | std::ios_base::app | std::ios_base::binary:
176
+					__mdstr = L"a+b";
177
+					break;
178
+				default:
179
+					__rt = nullptr;
180
+			}
181
+			if (__rt)
182
+			{
183
+				this->__file_ = _wfopen(__s, __mdstr);
184
+				if (this->__file_)
185
+				{
186
+					this->__om_ = __mode;
187
+					if ((__mode & std::ios_base::ate) && fseek(this->__file_, 0, SEEK_END))
188
+					{
189
+						fclose(this->__file_);
190
+						this->__file_ = nullptr;
191
+						__rt = nullptr;
192
+					}
193
+				}
194
+				else
195
+					__rt = nullptr;
196
+			}
197
+		}
198
+		return __rt;
199
+	}
200
+	filebuf_wfopen *open(const std::wstring &__s, std::ios_base::openmode __mode)
201
+	{
202
+		return this->open(__s.c_str(), __mode);
203
+	}
204
+	filebuf_wfopen *close()
205
+	{
206
+		filebuf_wfopen *__rt = nullptr;
207
+		if (this->__file_)
208
+		{
209
+			__rt = this;
210
+			std::unique_ptr<FILE, int (*)(FILE *)> __h(this->__file_, fclose);
211
+			if (this->sync())
212
+				__rt = nullptr;
213
+			if (!fclose(__h.release()))
214
+				this->__file_ = nullptr;
215
+			else
216
+				__rt = nullptr;
217
+		}
218
+		return __rt;
219
+	}
220
+
221
+protected:
222
+	// 27.9.1.5 Overridden virtual functions:
223
+	virtual int_type underflow()
224
+	{
225
+		if (!this->__file_)
226
+			return traits_type::eof();
227
+		bool __initial = this->__read_mode();
228
+		char __1buf;
229
+		if (!this->gptr())
230
+			this->setg(&__1buf, &__1buf + 1, &__1buf + 1);
231
+		const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);
232
+		int_type __c = traits_type::eof();
233
+		if (this->gptr() == this->egptr())
234
+		{
235
+			memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz);
236
+			if (this->__always_noconv_)
237
+			{
238
+				size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
239
+				__nmemb = fread(this->eback() + __unget_sz, 1, __nmemb, this->__file_);
240
+				if (__nmemb)
241
+				{
242
+					this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb);
243
+					__c = traits_type::to_int_type(*this->gptr());
244
+				}
245
+			}
246
+			else
247
+			{
248
+				memmove(this->__extbuf_, this->__extbufnext_, this->__extbufend_ - this->__extbufnext_);
249
+				this->__extbufnext_ = this->__extbuf_ + (this->__extbufend_ - this->__extbufnext_);
250
+				this->__extbufend_ = this->__extbuf_ +
251
+					(this->__extbuf_ == this->__extbuf_min_ ? sizeof(this->__extbuf_min_) : this->__ebs_);
252
+				size_t __nmemb = std::min<size_t>(this->__ibs_ - __unget_sz,
253
+					this->__extbufend_ - this->__extbufnext_);
254
+				std::codecvt_base::result __r;
255
+				this->__st_last_ = this->__st_;
256
+				size_t __nr = fread(const_cast<char *>(this->__extbufnext_), 1, __nmemb, this->__file_);
257
+				if (__nr)
258
+				{
259
+					if (!this->__cv_)
260
+						throw std::bad_cast();
261
+					this->__extbufend_ = this->__extbufnext_ + __nr;
262
+					char *__inext;
263
+					__r = this->__cv_->in(this->__st_, this->__extbuf_, this->__extbufend_, this->__extbufnext_,
264
+						this->eback() + __unget_sz, this->eback() + this->__ibs_, __inext);
265
+					if (__r == std::codecvt_base::noconv)
266
+					{
267
+						this->setg(this->__extbuf_, this->__extbuf_, const_cast<char *>(this->__extbufend_));
268
+						__c = traits_type::to_int_type(*this->gptr());
269
+					}
270
+					else if (__inext != this->eback() + __unget_sz)
271
+					{
272
+						this->setg(this->eback(), this->eback() + __unget_sz, __inext);
273
+						__c = traits_type::to_int_type(*this->gptr());
274
+					}
275
+				}
276
+			}
277
+		}
278
+		else
279
+			__c = traits_type::to_int_type(*this->gptr());
280
+		if (this->eback() == &__1buf)
281
+			this->setg(nullptr, nullptr, nullptr);
282
+		return __c;
283
+	}
284
+	virtual int_type pbackfail(int_type __c = traits_type::eof())
285
+	{
286
+		if (this->__file_ && this->eback() < this->gptr())
287
+		{
288
+			if (traits_type::eq_int_type(__c, traits_type::eof()))
289
+			{
290
+				this->gbump(-1);
291
+				return traits_type::not_eof(__c);
292
+			}
293
+			if ((this->__om_ & std::ios_base::out) ||
294
+				traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
295
+			{
296
+				this->gbump(-1);
297
+				*this->gptr() = traits_type::to_char_type(__c);
298
+				return __c;
299
+			}
300
+		}
301
+		return traits_type::eof();
302
+	}
303
+	virtual int_type overflow (int_type __c = traits_type::eof())
304
+	{
305
+		if (!this->__file_)
306
+			return traits_type::eof();
307
+		this->__write_mode();
308
+		char __1buf;
309
+		char *__pb_save = this->pbase();
310
+		char *__epb_save = this->epptr();
311
+		if (!traits_type::eq_int_type(__c, traits_type::eof()))
312
+		{
313
+			if (!this->pptr())
314
+				this->setp(&__1buf, &__1buf + 1);
315
+			*this->pptr() = traits_type::to_char_type(__c);
316
+			this->pbump(1);
317
+		}
318
+		if (this->pptr() != this->pbase())
319
+		{
320
+			if (this->__always_noconv_)
321
+			{
322
+				size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
323
+				if (fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
324
+					return traits_type::eof();
325
+			}
326
+			else
327
+			{
328
+				char *__extbe = this->__extbuf_;
329
+				std::codecvt_base::result __r;
330
+				do
331
+				{
332
+					if (!this->__cv_)
333
+						throw std::bad_cast();
334
+					const char *__e;
335
+					__r = this->__cv_->out(this->__st_, this->pbase(), this->pptr(), __e, this->__extbuf_,
336
+						this->__extbuf_ + this->__ebs_, __extbe);
337
+					if (__e == this->pbase())
338
+						return traits_type::eof();
339
+					if (__r == std::codecvt_base::noconv)
340
+					{
341
+						size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
342
+						if (fwrite(this->pbase(), 1, __nmemb, this->__file_) != __nmemb)
343
+							return traits_type::eof();
344
+					}
345
+					else if (__r == std::codecvt_base::ok || __r == std::codecvt_base::partial)
346
+					{
347
+						size_t __nmemb = static_cast<size_t>(__extbe - this->__extbuf_);
348
+						if (fwrite(this->__extbuf_, 1, __nmemb, this->__file_) != __nmemb)
349
+							return traits_type::eof();
350
+						if (__r == std::codecvt_base::partial)
351
+						{
352
+							this->setp(const_cast<char *>(__e), this->pptr());
353
+							this->pbump(this->epptr() - this->pbase());
354
+						}
355
+					}
356
+					else
357
+						return traits_type::eof();
358
+				} while (__r == std::codecvt_base::partial);
359
+			}
360
+			this->setp(__pb_save, __epb_save);
361
+		}
362
+		return traits_type::not_eof(__c);
363
+	}
364
+	virtual std::streambuf *setbuf(char *__s, std::streamsize __n)
365
+	{
366
+		this->setg(nullptr, nullptr, nullptr);
367
+		this->setp(nullptr, nullptr);
368
+		if (this->__owns_eb_)
369
+			delete[] this->__extbuf_;
370
+		if (this->__owns_ib_)
371
+			delete[] this->__intbuf_;
372
+		this->__ebs_ = __n;
373
+		if (this->__ebs_ > sizeof(this->__extbuf_min_))
374
+		{
375
+			if (this->__always_noconv_ && __s)
376
+			{
377
+				this->__extbuf_ = __s;
378
+				this->__owns_eb_ = false;
379
+			}
380
+			else
381
+			{
382
+				this->__extbuf_ = new char[this->__ebs_];
383
+				this->__owns_eb_ = true;
384
+			}
385
+		}
386
+		else
387
+		{
388
+			this->__extbuf_ = this->__extbuf_min_;
389
+			this->__ebs_ = sizeof(this->__extbuf_min_);
390
+			this->__owns_eb_ = false;
391
+		}
392
+		if (!this->__always_noconv_)
393
+		{
394
+			this->__ibs_ = std::max<std::streamsize>(__n, sizeof(this->__extbuf_min_));
395
+			if (__s && this->__ibs_ >= sizeof(this->__extbuf_min_))
396
+			{
397
+				this->__intbuf_ = __s;
398
+				this->__owns_ib_ = false;
399
+			}
400
+			else
401
+			{
402
+				this->__intbuf_ = new char[this->__ibs_];
403
+				this->__owns_ib_ = true;
404
+			}
405
+		}
406
+		else
407
+		{
408
+			this->__ibs_ = 0;
409
+			this->__intbuf_ = nullptr;
410
+			this->__owns_ib_ = false;
411
+		}
412
+		return this;
413
+	}
414
+	virtual pos_type seekoff(off_type __off, std::ios_base::seekdir __way,
415
+		std::ios_base::openmode = std::ios_base::in | std::ios_base::out)
416
+	{
417
+		if (!this->__cv_)
418
+			throw std::bad_cast();
419
+		int __width = this->__cv_->encoding();
420
+		if (!this->__file_ || (__width <= 0 && __off) || this->sync())
421
+			return pos_type(off_type(-1));
422
+		// __width > 0 || __off == 0
423
+		int __whence;
424
+		switch (__way)
425
+		{
426
+			case std::ios_base::beg:
427
+				__whence = SEEK_SET;
428
+				break;
429
+			case std::ios_base::cur:
430
+				__whence = SEEK_CUR;
431
+				break;
432
+			case std::ios_base::end:
433
+				__whence = SEEK_END;
434
+				break;
435
+			default:
436
+				return pos_type(off_type(-1));
437
+		}
438
+		if (fseek(this->__file_, __width > 0 ? __width * __off : 0, __whence))
439
+			return pos_type(off_type(-1));
440
+		pos_type __r = ftell(this->__file_);
441
+		__r.state(this->__st_);
442
+		return __r;
443
+	}
444
+	virtual pos_type seekpos(pos_type __sp,
445
+		std::ios_base::openmode = std::ios_base::in | std::ios_base::out)
446
+	{
447
+		if (!this->__file_ || this->sync())
448
+			return pos_type(off_type(-1));
449
+		if (fseek(this->__file_, __sp, SEEK_SET))
450
+			return pos_type(off_type(-1));
451
+		this->__st_ = __sp.state();
452
+		return __sp;
453
+	}
454
+	virtual int sync()
455
+	{
456
+		if (!this->__file_)
457
+			return 0;
458
+		if (!this->__cv_)
459
+			throw std::bad_cast();
460
+		if (this->__cm_ & std::ios_base::out)
461
+		{
462
+			if (this->pptr() != this->pbase() && this->overflow() == traits_type::eof())
463
+				return -1;
464
+			std::codecvt_base::result __r;
465
+			do
466
+			{
467
+				char *__extbe;
468
+				__r = this->__cv_->unshift(this->__st_, this->__extbuf_, this->__extbuf_ + this->__ebs_,
469
+					__extbe);
470
+				size_t __nmemb = static_cast<size_t>(__extbe - this->__extbuf_);
471
+				if (fwrite(this->__extbuf_, 1, __nmemb, this->__file_) != __nmemb)
472
+					return -1;
473
+			} while (__r == std::codecvt_base::partial);
474
+			if (__r == std::codecvt_base::error)
475
+				return -1;
476
+			if (fflush(this->__file_))
477
+				return -1;
478
+		}
479
+		else if (this->__cm_ & std::ios_base::in)
480
+		{
481
+			off_type __c;
482
+			state_type __state = this->__st_last_;
483
+			bool __update_st = false;
484
+			if (this->__always_noconv_)
485
+				__c = this->egptr() - this->gptr();
486
+			else
487
+			{
488
+				int __width = this->__cv_->encoding();
489
+				__c = this->__extbufend_ - this->__extbufnext_;
490
+				if (__width > 0)
491
+					__c += __width * (this->egptr() - this->gptr());
492
+				else if (this->gptr() != this->egptr())
493
+				{
494
+					int __off =  this->__cv_->length(__state, this->__extbuf_, this->__extbufnext_,
495
+						this->gptr() - this->eback());
496
+					__c += this->__extbufnext_ - this->__extbuf_ - __off;
497
+					__update_st = true;
498
+				}
499
+			}
500
+			if (fseek(this->__file_, -__c, SEEK_CUR))
501
+				return -1;
502
+			if (__update_st)
503
+				this->__st_ = __state;
504
+			this->__extbufnext_ = this->__extbufend_ = this->__extbuf_;
505
+			this->setg(nullptr, nullptr, nullptr);
506
+			this->__cm_ = static_cast<std::ios_base::openmode>(0);
507
+		}
508
+		return 0;
509
+	}
510
+	virtual void imbue(const std::locale &__loc)
511
+	{
512
+		this->sync();
513
+		this->__cv_ = &std::use_facet<std::codecvt<char, char, state_type>>(__loc);
514
+		bool __old_anc = this->__always_noconv_;
515
+		this->__always_noconv_ = this->__cv_->always_noconv();
516
+		if (__old_anc != this->__always_noconv_)
517
+		{
518
+			this->setg(nullptr, nullptr, nullptr);
519
+			this->setp(nullptr, nullptr);
520
+			// invariant, char_type is char, else we couldn't get here
521
+			if (this->__always_noconv_) // need to dump __intbuf_
522
+			{
523
+				if (this->__owns_eb_)
524
+					delete[] this->__extbuf_;
525
+				this->__owns_eb_ = this->__owns_ib_;
526
+				this->__ebs_ = this->__ibs_;
527
+				this->__extbuf_ = this->__intbuf_;
528
+				this->__ibs_ = 0;
529
+				this->__intbuf_ = nullptr;
530
+				this->__owns_ib_ = false;
531
+			}
532
+			// need to obtain an __intbuf_.
533
+			else if (!this->__owns_eb_ && this->__extbuf_ != this->__extbuf_min_)
534
+				// If __extbuf_ is user-supplied, use it, else new __intbuf_
535
+			{
536
+				this->__ibs_ = this->__ebs_;
537
+				this->__intbuf_ = this->__extbuf_;
538
+				this->__owns_ib_ = false;
539
+				this->__extbuf_ = new char[this->__ebs_];
540
+				this->__owns_eb_ = true;
541
+			}
542
+			else
543
+			{
544
+				this->__ibs_ = this->__ebs_;
545
+				this->__intbuf_ = new char[this->__ibs_];
546
+				this->__owns_ib_ = true;
547
+			}
548
+		}
549
+	}
550
+
551
+private:
552
+	char *__extbuf_;
553
+	const char *__extbufnext_;
554
+	const char *__extbufend_;
555
+	char __extbuf_min_[8];
556
+	size_t __ebs_;
557
+	char *__intbuf_;
558
+	size_t __ibs_;
559
+	FILE *__file_;
560
+	const std::codecvt<char, char, state_type> *__cv_;
561
+	state_type __st_;
562
+	state_type __st_last_;
563
+	std::ios_base::openmode __om_;
564
+	std::ios_base::openmode __cm_;
565
+	bool __owns_eb_;
566
+	bool __owns_ib_;
567
+	bool __always_noconv_;
568
+
569
+	bool __read_mode()
570
+	{
571
+		if (!(this->__cm_ & std::ios_base::in))
572
+		{
573
+			this->setp(nullptr, nullptr);
574
+			if (this->__always_noconv_)
575
+				this->setg(this->__extbuf_, this->__extbuf_ + this->__ebs_, this->__extbuf_ + this->__ebs_);
576
+			else
577
+				this->setg(this->__intbuf_, this->__intbuf_ + this->__ibs_, this->__intbuf_ + this->__ibs_);
578
+			this->__cm_ = std::ios_base::in;
579
+			return true;
580
+		}
581
+		return false;
582
+	}
583
+	void __write_mode()
584
+	{
585
+		if (!(this->__cm_ & std::ios_base::out))
586
+		{
587
+			this->setg(nullptr, nullptr, nullptr);
588
+			if (this->__ebs_ > sizeof(this->__extbuf_min_))
589
+			{
590
+				if (this->__always_noconv_)
591
+					this->setp(this->__extbuf_, this->__extbuf_ + (this->__ebs_ - 1));
592
+				else
593
+					this->setp(this->__intbuf_, this->__intbuf_ + (this->__ibs_ - 1));
594
+			}
595
+			else
596
+				this->setp(nullptr, nullptr);
597
+			this->__cm_ = std::ios_base::out;
598
+		}
599
+	}
600
+};
601
+
602
+// basic_ifstream
603
+
604
+class ifstream_wfopen : public std::ifstream
605
+{
606
+public:
607
+	ifstream_wfopen() { std::ios::rdbuf(&this->__sb_); }
608
+	explicit ifstream_wfopen(const char *__s, std::ios_base::openmode __mode = std::ios_base::in)
609
+	{
610
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
611
+			std::ios::rdbuf(&this->__sb_);
612
+		else
613
+			this->setstate(std::ios_base::failbit);
614
+	}
615
+	explicit ifstream_wfopen(const std::string &__s, std::ios_base::openmode __mode = std::ios_base::in)
616
+	{
617
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
618
+			std::ios::rdbuf(&this->__sb_);
619
+		else
620
+			this->setstate(std::ios_base::failbit);
621
+	}
622
+	explicit ifstream_wfopen(const wchar_t *__s, std::ios_base::openmode __mode = std::ios_base::in)
623
+	{
624
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
625
+			std::ios::rdbuf(&this->__sb_);
626
+		else
627
+			this->setstate(std::ios_base::failbit);
628
+	}
629
+	explicit ifstream_wfopen(const std::wstring &__s, std::ios_base::openmode __mode = std::ios_base::in)
630
+	{
631
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
632
+			std::ios::rdbuf(&this->__sb_);
633
+		else
634
+			this->setstate(std::ios_base::failbit);
635
+	}
636
+
637
+	std::filebuf *rdbuf() const
638
+	{
639
+		return const_cast<std::filebuf *>(static_cast<const std::filebuf *>(&this->__sb_));
640
+	}
641
+	bool is_open() const
642
+	{
643
+		return this->__sb_.is_open();
644
+	}
645
+	void open(const char *__s, std::ios_base::openmode __mode = std::ios_base::in)
646
+	{
647
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
648
+			this->clear();
649
+		else
650
+			this->setstate(std::ios_base::failbit);
651
+	}
652
+	void open(const std::string &__s, std::ios_base::openmode __mode = std::ios_base::in)
653
+	{
654
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
655
+			this->clear();
656
+		else
657
+			this->setstate(std::ios_base::failbit);
658
+	}
659
+	void open(const wchar_t *__s, std::ios_base::openmode __mode = std::ios_base::in)
660
+	{
661
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
662
+			this->clear();
663
+		else
664
+			this->setstate(std::ios_base::failbit);
665
+	}
666
+	void open(const std::wstring &__s, std::ios_base::openmode __mode = std::ios_base::in)
667
+	{
668
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
669
+			this->clear();
670
+		else
671
+			this->setstate(std::ios_base::failbit);
672
+	}
673
+	void close()
674
+	{
675
+		if (!this->__sb_.close())
676
+			this->setstate(std::ios_base::failbit);
677
+	}
678
+
679
+private:
680
+	filebuf_wfopen __sb_;
681
+};
682
+
683
+// basic_ofstream
684
+
685
+class ofstream_wfopen : public std::ofstream
686
+{
687
+public:
688
+	ofstream_wfopen() { std::ios::rdbuf(&this->__sb_); }
689
+	explicit ofstream_wfopen(const char *__s, std::ios_base::openmode __mode = std::ios_base::out)
690
+	{
691
+		if (this->__sb_.open(__s, __mode | std::ios_base::out))
692
+			std::ios::rdbuf(&this->__sb_);
693
+		else
694
+			this->setstate(std::ios_base::failbit);
695
+	}
696
+	explicit ofstream_wfopen(const std::string &__s, std::ios_base::openmode __mode = std::ios_base::out)
697
+	{
698
+		if (this->__sb_.open(__s, __mode | std::ios_base::out))
699
+			std::ios::rdbuf(&this->__sb_);
700
+		else
701
+			this->setstate(std::ios_base::failbit);
702
+	}
703
+	explicit ofstream_wfopen(const wchar_t *__s, std::ios_base::openmode __mode = std::ios_base::out)
704
+	{
705
+		if (this->__sb_.open(__s, __mode | std::ios_base::out))
706
+			std::ios::rdbuf(&this->__sb_);
707
+		else
708
+			this->setstate(std::ios_base::failbit);
709
+	}
710
+	explicit ofstream_wfopen(const std::wstring &__s, std::ios_base::openmode __mode = std::ios_base::out)
711
+	{
712
+		if (!this->__sb_.open(__s, __mode | std::ios_base::out))
713
+			std::ios::rdbuf(&this->__sb_);
714
+		else
715
+			this->setstate(std::ios_base::failbit);
716
+	}
717
+
718
+	std::filebuf *rdbuf() const
719
+	{
720
+		return const_cast<std::filebuf *>(static_cast<const std::filebuf *>(&this->__sb_));
721
+	}
722
+	bool is_open() const
723
+	{
724
+		return this->__sb_.is_open();
725
+	}
726
+	void open(const char *__s, std::ios_base::openmode __mode = std::ios_base::out)
727
+	{
728
+		if (this->__sb_.open(__s, __mode | std::ios_base::out))
729
+			this->clear();
730
+		else
731
+			this->setstate(std::ios_base::failbit);
732
+	}
733
+	void open(const std::string &__s, std::ios_base::openmode __mode = std::ios_base::out)
734
+	{
735
+		if (this->__sb_.open(__s, __mode | std::ios_base::out))
736
+			this->clear();
737
+		else
738
+			this->setstate(std::ios_base::failbit);
739
+	}
740
+	void open(const wchar_t *__s, std::ios_base::openmode __mode = std::ios_base::out)
741
+	{
742
+		if (this->__sb_.open(__s, __mode | std::ios_base::out))
743
+			this->clear();
744
+		else
745
+			this->setstate(std::ios_base::failbit);
746
+	}
747
+	void open(const std::wstring &__s, std::ios_base::openmode __mode = std::ios_base::out)
748
+	{
749
+		if (this->__sb_.open(__s, __mode | std::ios_base::out))
750
+			this->clear();
751
+		else
752
+			this->setstate(std::ios_base::failbit);
753
+	}
754
+	void close()
755
+	{
756
+		if (!this->__sb_.close())
757
+			this->setstate(std::ios_base::failbit);
758
+	}
759
+
760
+private:
761
+	filebuf_wfopen __sb_;
762
+};
763
+#endif