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;
};
}
|