blob: 76c66bb454d6adda0b1fa142ae103e0a07cc86a1 (
plain)
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
/*
* Copyright (C) 2005-2018 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
#pragma once
#include "threads/Event.h"
#include <stdint.h>
#include <string>
namespace XFILE {
#define CACHE_RC_OK 0
#define CACHE_RC_ERROR -1
#define CACHE_RC_WOULD_BLOCK -2
#define CACHE_RC_TIMEOUT -3
class IFile; // forward declaration
class CCacheStrategy{
public:
virtual ~CCacheStrategy();
virtual int Open() = 0;
virtual void Close() = 0;
virtual size_t GetMaxWriteSize(const size_t& iRequestSize) = 0;
virtual int WriteToCache(const char *pBuffer, size_t iSize) = 0;
virtual int ReadFromCache(char *pBuffer, size_t iMaxSize) = 0;
virtual int64_t WaitForData(uint32_t iMinAvail, std::chrono::milliseconds timeout) = 0;
virtual int64_t Seek(int64_t iFilePosition) = 0;
/*!
\brief Reset cache position
\param iSourcePosition position to reset to
\return Whether a full reset was performed, or not (e.g. only cache swap)
\sa CCacheStrategy
*/
virtual bool Reset(int64_t iSourcePosition) = 0;
virtual void EndOfInput(); // mark the end of the input stream so that Read will know when to return EOF
virtual bool IsEndOfInput();
virtual void ClearEndOfInput();
virtual int64_t CachedDataEndPosIfSeekTo(int64_t iFilePosition) = 0;
virtual int64_t CachedDataStartPos() = 0;
virtual int64_t CachedDataEndPos() = 0;
virtual bool IsCachedPosition(int64_t iFilePosition) = 0;
virtual CCacheStrategy *CreateNew() = 0;
CEvent m_space;
protected:
bool m_bEndOfInput = false;
};
/**
*/
class CSimpleFileCache : public CCacheStrategy {
public:
CSimpleFileCache();
~CSimpleFileCache() override;
int Open() override;
void Close() override;
size_t GetMaxWriteSize(const size_t& iRequestSize) override;
int WriteToCache(const char *pBuffer, size_t iSize) override;
int ReadFromCache(char *pBuffer, size_t iMaxSize) override;
int64_t WaitForData(uint32_t iMinAvail, std::chrono::milliseconds timeout) override;
int64_t Seek(int64_t iFilePosition) override;
bool Reset(int64_t iSourcePosition) override;
void EndOfInput() override;
int64_t CachedDataEndPosIfSeekTo(int64_t iFilePosition) override;
int64_t CachedDataStartPos() override;
int64_t CachedDataEndPos() override;
bool IsCachedPosition(int64_t iFilePosition) override;
CCacheStrategy *CreateNew() override;
int64_t GetAvailableRead();
protected:
std::string m_filename;
IFile* m_cacheFileRead;
IFile* m_cacheFileWrite;
CEvent* m_hDataAvailEvent;
volatile int64_t m_nStartPosition = 0;
volatile int64_t m_nWritePosition = 0;
volatile int64_t m_nReadPosition = 0;
};
class CDoubleCache : public CCacheStrategy{
public:
explicit CDoubleCache(CCacheStrategy *impl);
~CDoubleCache() override;
int Open() override;
void Close() override;
size_t GetMaxWriteSize(const size_t& iRequestSize) override;
int WriteToCache(const char *pBuffer, size_t iSize) override;
int ReadFromCache(char *pBuffer, size_t iMaxSize) override;
int64_t WaitForData(uint32_t iMinAvail, std::chrono::milliseconds timeout) override;
int64_t Seek(int64_t iFilePosition) override;
bool Reset(int64_t iSourcePosition) override;
void EndOfInput() override;
bool IsEndOfInput() override;
void ClearEndOfInput() override;
int64_t CachedDataEndPosIfSeekTo(int64_t iFilePosition) override;
int64_t CachedDataStartPos() override;
int64_t CachedDataEndPos() override;
bool IsCachedPosition(int64_t iFilePosition) override;
CCacheStrategy *CreateNew() override;
protected:
CCacheStrategy *m_pCache;
CCacheStrategy *m_pCacheOld;
};
}
|