File: FileInputStream.h

package info (click to toggle)
darkradiant 3.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 41,080 kB
  • sloc: cpp: 264,743; ansic: 10,659; python: 1,852; xml: 1,650; sh: 92; makefile: 21
file content (111 lines) | stat: -rw-r--r-- 2,084 bytes parent folder | download | duplicates (5)
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
#pragma once

#include "idatastream.h"
#include <algorithm>
#include <cstdio>

namespace stream
{

namespace detail
{

inline int whence_for_seekdir(SeekableStream::seekdir direction)
{
	switch (direction)
	{
	case SeekableStream::cur:
		return SEEK_CUR;
	case SeekableStream::end:
		return SEEK_END;
	default:
		break;
	}
	return SEEK_SET;
}

}

/// \brief A wrapper around a file input stream opened for reading in binary mode. Similar to std::ifstream.
///
/// - Maintains a valid file handle associated with a name passed to the constructor.
/// - Implements SeekableInputStream.
class FileInputStream : 
	public SeekableInputStream
{
private:
	std::FILE* _file;
public:
	FileInputStream(const std::string& name) :
		_file(!name.empty() ? fopen(name.c_str(), "rb") : nullptr)
	{}

	~FileInputStream()
	{
		if (!failed())
		{
			fclose(_file);
		}
	}

	bool failed() const
	{
		return _file == nullptr;
	}

	size_type read(byte_type* buffer, size_type length) override
	{
		return fread(buffer, 1, length, _file);
	}

	size_type seek(size_type position) override
	{
		return fseek(_file, static_cast<long>(position), SEEK_SET);
	}

	size_type seek(offset_type offset, seekdir direction) override
	{
		return fseek(_file, offset, detail::whence_for_seekdir(direction));
	}

	size_type tell() const override
	{
		return ftell(_file);
	}

	std::FILE* file()
	{
		return _file;
	}
};

/// \brief A wrapper around a FileInputStream limiting access.
///
/// - Maintains an input stream.
/// - Provides input starting at an offset in the file for a limited range.
class SubFileInputStream : 
	public InputStream
{
private:
	FileInputStream& _istream;
	size_type _remaining;

public:
	typedef FileInputStream::position_type position_type;

	SubFileInputStream(FileInputStream& istream, position_type offset, size_type size) : 
		_istream(istream), 
		_remaining(size)
	{
		_istream.seek(offset);
	}

	size_type read(byte_type* buffer, size_type length) override
	{
		size_type result = _istream.read(buffer, std::min(length, _remaining));
		_remaining -= result;
		return result;
	}
};

}