[matroska] r1263 - trunk/foo_input_matroska

[email protected] Fri, 13 Oct 2006 00:51:53 +0400 (MSD)
Newsgroups gmane.comp.multimedia.matroska.cvs
Message-ID <[email protected]>
Author: ayana
Date: 2006-10-13 00:51:49 +0400 (Fri, 13 Oct 2006)
New Revision: 1263

Added:
   trunk/foo_input_matroska/filesystem_matroska.cpp
   trunk/foo_input_matroska/filesystem_matroska.h
Log:
add: transparent access to attachment file

Added: trunk/foo_input_matroska/filesystem_matroska.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/foo_input_matroska/filesystem_matroska.cpp	2006-10-12 20:51:02 =
UTC (rev 1262)
+++ trunk/foo_input_matroska/filesystem_matroska.cpp	2006-10-12 20:51:49 =
UTC (rev 1263)
@@ -0,0 +1,133 @@
+#include "filesystem_matroska.h"
+
+bool filesystem_matroska::get_canonical_path(const char * p_path,pfc::st=
ring_base & p_out)
+{
+    p_out =3D p_path;
+    return true;
+}
+
+bool filesystem_matroska::is_our_path(const char * p_path)
+{
+    if (stricmp_utf8_partial(p_path, "matroska://") =3D=3D 0 || pfc::str=
ing_find_last(p_path, '|') !=3D infinite) {
+        pfc::string8 source_file;
+        get_source_file_path(p_path, source_file);
+        pfc::string8 ext(pfc::string_extension(source_file).get_ptr());
+        if (stricmp_utf8(ext, "mka") =3D=3D 0 || stricmp_utf8(ext, "mkv"=
) =3D=3D 0) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool filesystem_matroska::get_display_path(const char * p_path,pfc::stri=
ng_base & p_out)
+{
+    p_out =3D p_path;
+    return true;
+}
+
+void filesystem_matroska::open(service_ptr_t<file> & p_out,const char * =
p_path, t_open_mode p_mode,abort_callback & p_abort)
+{
+    pfc::string8 path, attachment_file_name;
+    if (!get_source_file_path(p_path, path) || !get_attachment_file_name=
(p_path, attachment_file_name)) {
+        throw exception_io_not_found();
+    }
+    service_ptr_t<container_matroska> matroska;
+    container_matroska::g_open(matroska, path, true, p_abort);
+    if (matroska =3D=3D NULL) {
+        throw exception_io_not_found();
+    }
+    for (t_size i =3D 0; i !=3D matroska->get_attachment_list()->get_cou=
nt(); ++i) {
+        pfc::string8 name;
+        matroska::attachment attachment_file =3D matroska->get_attachmen=
t_list()->get_item(i);
+        attachment_file.get_name(name);
+        if (stricmp_utf8(name, attachment_file_name) =3D=3D 0) {
+            pfc::array_t<unsigned char> buffer;
+            buffer.set_size(attachment_file.get_size());
+            attachment_file.get(static_cast<void *>(buffer.get_ptr()));
+            filesystem::g_open_tempmem(p_out, p_abort);
+            p_out->write(static_cast<void *>(buffer.get_ptr()), buffer.g=
et_size(), p_abort);
+            p_out->reopen(p_abort);
+            return;
+        }
+    }
+    throw exception_io_not_found();
+}
+
+void filesystem_matroska::remove(const char * p_path,abort_callback & p_=
abort)
+{
+    throw exception_io_denied();
+}
+
+void filesystem_matroska::move(const char * p_src,const char * p_dst,abo=
rt_callback & p_abort)
+{
+    throw exception_io_denied();
+}
+
+bool filesystem_matroska::is_remote(const char * p_src)
+{
+    pfc::string8 path;
+    if (get_source_file_path(p_src, path)) {
+        return g_is_remote(path);
+    }
+    return false;
+}
+
+void filesystem_matroska::get_stats(const char * p_path,t_filestats & p_=
stats,bool & p_is_writeable,abort_callback & p_abort)
+{
+    pfc::string8 path;
+    if (get_source_file_path(p_path, path)) {
+        t_filestats filestats;
+        bool is_writeable =3D false;
+        g_get_stats(path, filestats, is_writeable, p_abort);
+        pfc::string8 attachment_file_name;
+        service_ptr_t<container_matroska> matroska;
+        container_matroska::g_open(matroska, path, true, p_abort);
+        if (matroska !=3D NULL && get_attachment_file_name(p_path, attac=
hment_file_name)) {
+            for (t_size i =3D 0; i !=3D matroska->get_attachment_list()-=
>get_count(); ++i) {
+                pfc::string8 name;
+                matroska->get_attachment_list()->get_item(i).get_name(na=
me);
+                if (stricmp_utf8(name, attachment_file_name) =3D=3D 0) {
+                    p_stats =3D filestats;
+                    p_stats.m_size =3D matroska->get_attachment_list()->=
get_item(i).get_size();
+                    p_is_writeable =3D false;
+                    return;
+                }
+            }
+        }
+    }
+    throw exception_io_not_found();
+}
+
+void filesystem_matroska::create_directory(const char * p_path,abort_cal=
lback & p_abort)
+{
+    throw exception_io_denied();
+}
+
+void filesystem_matroska::list_directory(const char * p_path,directory_c=
allback & p_out,abort_callback & p_abort)
+{
+    pfc::string8 path;
+    if (get_source_file_path(p_path, path)) {
+        service_ptr_t<container_matroska> matroska;
+        container_matroska::g_open(matroska, path, true, p_abort);
+        if (matroska !=3D NULL) {
+            for (t_size i =3D 0; i !=3D matroska->get_attachment_list()-=
>get_count(); ++i) {
+                pfc::string8 name;
+                matroska->get_attachment_list()->get_item(i).get_name(na=
me);
+                t_filestats filestats;
+                bool is_writeable =3D false;
+                g_get_stats(path, filestats, is_writeable, p_abort);
+                filestats.m_size =3D matroska->get_attachment_list()->ge=
t_item(i).get_size();
+                pfc::string8 url;
+                g_make_matroska_path(url, path, name);
+                p_out.on_entry(this, p_abort, url, false, filestats);
+            }
+            return;
+        }
+    }
+    throw exception_io_denied();
+}
+
+bool filesystem_matroska::supports_content_types()
+{
+    return false;
+}
\ No newline at end of file

Added: trunk/foo_input_matroska/filesystem_matroska.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/foo_input_matroska/filesystem_matroska.h	2006-10-12 20:51:02 UT=
C (rev 1262)
+++ trunk/foo_input_matroska/filesystem_matroska.h	2006-10-12 20:51:49 UT=
C (rev 1263)
@@ -0,0 +1,90 @@
+#ifndef _FOO_INPUT_MATROSKA_FILESYSTEM_MATROSKA_H_
+#define _FOO_INPUT_MATROSKA_FILESYSTEM_MATROSKA_H_
+
+#include "../SDK/foobar2000.h"
+#include "container_matroska.h"
+
+class NOVTABLE filesystem_matroska : public filesystem {
+public:
+	virtual bool get_canonical_path(const char * p_path,pfc::string_base & =
p_out);
+	virtual bool is_our_path(const char * p_path);
+	virtual bool get_display_path(const char * p_path,pfc::string_base & p_=
out);
+
+	virtual void open(service_ptr_t<file> & p_out,const char * p_path, t_op=
en_mode p_mode,abort_callback & p_abort);
+    virtual void remove(const char * p_path,abort_callback & p_abort);
+    virtual void move(const char * p_src,const char * p_dst,abort_callba=
ck & p_abort);
+	//! Queries whether a file at specified path belonging to this filesyst=
em is a remove object or not.
+	virtual bool is_remote(const char * p_src);
+
+	//! Retrieves stats of a file at specified path.
+	virtual void get_stats(const char * p_path,t_filestats & p_stats,bool &=
 p_is_writeable,abort_callback & p_abort);
+=09
+	virtual bool relative_path_create(const char * file_path,const char * p=
laylist_path,pfc::string_base & out) {return 0;}
+	virtual bool relative_path_parse(const char * relative_path,const char =
* playlist_path,pfc::string_base & out) {return 0;}
+
+	//! Creates a directory.
+	virtual void create_directory(const char * p_path,abort_callback & p_ab=
ort);
+
+	virtual void list_directory(const char * p_path,directory_callback & p_=
out,abort_callback & p_abort);
+
+	//! Hint; returns whether this filesystem supports mime types.
+	virtual bool supports_content_types();
+
+private:
+    inline bool get_source_file_path(const char * p_path, pfc::string_ba=
se & p_out)
+    {
+        pfc::string8 path, file;
+        if (archive_impl::g_parse_unpack_path(p_path, path, file)) {
+            path << "|" << file;
+        } else {
+            path =3D p_path;
+        }
+        path.remove_chars(0, 11);
+        path.truncate(path.find_last('|'));
+        pfc::string8 ext(pfc::string_extension(path).get_ptr());
+        if (filesystem::g_is_recognized_path(path)) {
+            p_out =3D path;
+            return true;
+        }
+        return false;
+    }
+    inline bool get_attachment_file_name(const char * p_path, pfc::strin=
g_base & p_out)
+    {
+        pfc::string8 path, file;
+        if (archive_impl::g_parse_unpack_path(p_path, path, file)) {
+            path << "|" << file;
+        } else {
+            path =3D p_path;
+        }
+        path.remove_chars(0, 11);
+        if (path.find_last('|') !=3D infinite) {
+            path.remove_chars(0, path.find_last('|')+1);
+        } else {
+            path.remove_chars(0, path.find_last('\\')+1);
+        }
+        if (path.find_first('\\') =3D=3D 0) {
+            path.remove_chars(0, 1);
+        }
+        if (path.length() !=3D 0) {
+            p_out =3D path;
+            return true;
+        }
+        return false;
+    }
+
+public:
+    static void g_make_matroska_path(pfc::string_base & path, const char=
 * file, const char * name)
+    {
+	    path =3D "matroska://";
+	    path +=3D file;
+	    path +=3D "|";
+	    path +=3D name;
+    }
+};
+
+template<typename T>
+class filesystem_matroska_factory_t : public service_factory_single_t<T>=
 {};
+
+static filesystem_matroska_factory_t<filesystem_matroska> g_filesystem_m=
atroska_factory;
+
+#endif//_FOO_INPUT_MATROSKA_FILESYSTEM_MATROSKA_H_