diff options
author | Sascha Volkenandt <sascha (at) akv-soft (dot) de> | 2007-05-30 20:26:14 +0000 |
---|---|---|
committer | Sascha Volkenandt <sascha (at) akv-soft (dot) de> | 2007-05-30 20:26:14 +0000 |
commit | 2bff302c8a8eb6768313df248b06e7f725a4ae87 (patch) | |
tree | 580511702ea74ed4a9e2689be804104746eb7caa | |
parent | 1043c52409de2c44e5707177ee9dc1977126ca67 (diff) | |
download | vdr-plugin-live-2bff302c8a8eb6768313df248b06e7f725a4ae87.tar.gz vdr-plugin-live-2bff302c8a8eb6768313df248b06e7f725a4ae87.tar.bz2 |
- new files
-rwxr-xr-x | cache.h | 89 | ||||
-rw-r--r-- | filecache.cpp | 57 | ||||
-rw-r--r-- | filecache.h | 55 | ||||
-rw-r--r-- | pages/content.ecpp | 34 |
4 files changed, 235 insertions, 0 deletions
@@ -0,0 +1,89 @@ +#ifndef VGSTOOLS_CACHE_H +#define VGSTOOLS_CACHE_H + +#include <algorithm> +#include <ctime> +#include <list> +#include <map> +#include <utility> +#include "stdext.h" + +/* Interface for TValue: + * size_t weight() + * bool is_newer( time_t ) + * bool load() + * + */ + +namespace vgstools { + +template< typename TKey, typename TValue > +class cache +{ +public: + typedef TKey key_type; + typedef TValue value_type; + typedef std::tr1::shared_ptr< value_type > ptr_type; + +private: + struct Value + { + ptr_type value; + std::time_t creation; + + Value( key_type const& key ) + : value( new value_type( key ) ) + , creation( 0 ) {} + }; + + typedef std::list< Value > ValueList; + typedef std::map< TKey, typename ValueList::iterator > KeyMap; + +public: + cache( size_t maxWeight ) + : m_maxWeight( maxWeight ) + , m_currentWeight( 0 ) {} + + size_t weight() const { return m_currentWeight; } + size_t count() const { return m_values.size(); } + + ptr_type get( key_type const& key ) + { + typename KeyMap::iterator it = m_lookup.find( key ); + if ( it == m_lookup.end() ) { + typename ValueList::iterator element = m_values.insert( m_values.begin(), Value( key ) ); + std::pair< typename KeyMap::iterator, bool > result = m_lookup.insert( std::make_pair( key, element ) ); + it = result.first; + } + + Value* value = &*it->second; + std::time_t now = std::time( 0 ); + if ( value->creation == 0 || !value->value->is_current() ) { + m_currentWeight -= value->value->weight(); + if ( !value->value->load() ) { + m_values.erase( it->second ); + m_lookup.erase( it ); + return ptr_type(); + } + m_currentWeight += value->value->weight(); + value->creation = now; + } + if ( it->second != m_values.begin() ) { + typename ValueList::iterator element = m_values.insert( m_values.begin(), *it->second ); + m_values.erase( it->second ); + it->second = element; + value = &*element; + } + return value->value; + } + +private: + std::size_t m_maxWeight; + std::size_t m_currentWeight; + ValueList m_values; + KeyMap m_lookup; +}; + +} // namespace vgstools + +#endif // VGSTOOLS_CACHE_H diff --git a/filecache.cpp b/filecache.cpp new file mode 100644 index 0000000..a5912d0 --- /dev/null +++ b/filecache.cpp @@ -0,0 +1,57 @@ +#include <algorithm> +#include <fstream> +#include <istream> +#include "filecache.h" + +namespace vdrlive { + +std::time_t FileObject::get_filetime( std::string const& path ) +{ + return 9999; +} + +bool FileObject::is_current() const +{ + return m_ctime < get_filetime( m_path ); + /*struct stat statBuf = { 0 }; + * if ( ::stat( m_path.c_str(), &statBuf ) < 0 ) { + * } + if ( m_ctime == 0 ) + return true; + m_ctime = get_filetime( m_path ); + return timestamp < m_ctime;*/ +} + +bool FileObject::load() +{ + std::ifstream ifs( m_path.c_str(), std::ios::in | std::ios::binary | std::ios::ate ); + if ( !ifs ) + return false; + + std::streamsize size = ifs.tellg(); + ifs.seekg( 0, std::ios::beg ); + + std::vector< char > data( size ); + data.resize( size ); + ifs.read( &data[0], size ); + ifs.close(); + + m_ctime = get_filetime( m_path ); + m_data.swap( data ); + return true; +} + +FileCache& LiveFileCache() +{ + static FileCache instance( 1000000 ); + return instance; +} + +} // namespace vdrlive + +using namespace vdrlive; + +int main() +{ + FileCache::ptr_type f = LiveFileCache().get("/tmp/live/active.png"); +} diff --git a/filecache.h b/filecache.h new file mode 100644 index 0000000..0556616 --- /dev/null +++ b/filecache.h @@ -0,0 +1,55 @@ +#ifndef VDR_LIVE_FILECACHE_H +#define VDR_LIVE_FILECACHE_H + +#include <string> +#include <vector> +#include <vdr/tools.h> +#include "cache.h" + +namespace vdrlive { + +class FileObject +{ +public: + FileObject( std::string const& path ) + : m_ctime( 0 ) + , m_path( path ) {} + + std::size_t size() const { return m_data.size(); } + std::size_t weight() const { return size(); } + bool is_current() const; + bool load(); + char const* data() const { return &m_data[0]; } + std::time_t ctime() const { return m_ctime; } + +private: + static std::time_t get_filetime( std::string const& path ); + + mutable std::time_t m_ctime; + std::string m_path; + std::vector< char > m_data; +}; + +class FileCache: public vgstools::cache< std::string, FileObject > +{ + typedef vgstools::cache< std::string, FileObject > base_type; +public: + FileCache( size_t maxWeight ): base_type( maxWeight ) {} + + ptr_type get( key_type const& key ) + { + dsyslog( "vdrlive::FileCache::get( %s )", key.c_str() ); + dsyslog( "vdrlive::FileCache had %u entries (weight: %u)", count(), weight() ); + ptr_type result = base_type::get( key ); + dsyslog( "vdrlive::FileCache now has %u entries (weight: %u)", count(), weight() ); + dsyslog( "vdrlive::FileCache::get( %s ) = %p", key.c_str(), result.get() ); + return result; + } +}; + +//typedef vgstools::cache< std::string, FileObject > FileCache; +FileCache& LiveFileCache(); + +} // namespace vdrlive + +#endif // VDR_LIVE_FILECACHE_H diff --git a/pages/content.ecpp b/pages/content.ecpp new file mode 100644 index 0000000..cc604ba --- /dev/null +++ b/pages/content.ecpp @@ -0,0 +1,34 @@ +<%pre> +#include <string> +#include <tnt/httpheader.h> +#include "filecache.h" +#include "setup.h" + +using namespace std; +using namespace vdrlive; + +</%pre> +<%args> +string file; +</%args> +<%session scope="global"> +bool logged_in(false); +</%session> +<%cpp> +//if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); + +reply.setContentType("image/png"); +//reply.setContentType("text/plain"); + +FileCache::ptr_type f = LiveFileCache().get("/tmp/live/" + file); +if (f.get() == 0) + return HTTP_NOT_FOUND; + +string ctime = tnt::HttpMessage::htdate(f->ctime()); +string browserTime = request.getHeader(tnt::httpheader::ifModifiedSince); +if (browserTime == ctime) + return HTTP_NOT_MODIFIED; + +reply.setHeader(tnt::httpheader::lastModified, ctime); +reply.out().write(f->data(), f->size()); +</%cpp> |