summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSascha Volkenandt <sascha (at) akv-soft (dot) de>2007-05-30 20:26:14 +0000
committerSascha Volkenandt <sascha (at) akv-soft (dot) de>2007-05-30 20:26:14 +0000
commit2bff302c8a8eb6768313df248b06e7f725a4ae87 (patch)
tree580511702ea74ed4a9e2689be804104746eb7caa
parent1043c52409de2c44e5707177ee9dc1977126ca67 (diff)
downloadvdr-plugin-live-2bff302c8a8eb6768313df248b06e7f725a4ae87.tar.gz
vdr-plugin-live-2bff302c8a8eb6768313df248b06e7f725a4ae87.tar.bz2
- new files
-rwxr-xr-xcache.h89
-rw-r--r--filecache.cpp57
-rw-r--r--filecache.h55
-rw-r--r--pages/content.ecpp34
4 files changed, 235 insertions, 0 deletions
diff --git a/cache.h b/cache.h
new file mode 100755
index 0000000..b34c1c2
--- /dev/null
+++ b/cache.h
@@ -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>