diff --git a/include/asset.h b/include/asset.h
new file mode 100644
index 0000000..e54b837
--- /dev/null
+++ b/include/asset.h
@@ -0,0 +1,54 @@
+/**
+ * \file
+ * Represents an asset (a file on disk)
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2012 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __ASSET_H__
+#define __ASSET_H__
+
+#include
+
+#include "class.h"
+#include "commons.h"
+#include "hash.h"
+
+
+CLASS(Asset) {
+ char fname[2048];
+ char etag[200];
+ char mtime[200];
+
+ size_t nfname;
+ size_t netag;
+ size_t nmtime;
+
+ char * mime_type;
+ size_t size;
+
+ int handle;
+ char * data;
+};
+
+char * assetDataAt(size_t);
+
+#endif // __ASSET_H__
+
+// vim: set ts=4 sw=4:
diff --git a/include/utils/mime_type.h b/include/utils/mime_type.h
new file mode 100644
index 0000000..b899540
--- /dev/null
+++ b/include/utils/mime_type.h
@@ -0,0 +1,31 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2012 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __UTILS_MIME_TYPE_H__
+#define __UTILS_MIME_TYPE_H__
+
+char * getMimeType(const char *, size_t);
+void clearMimeTypes(void);
+
+#endif // __UTILS_MIME_TYPE_H__
+
+// vim: set ts=4 sw=4:
diff --git a/src/asset/asset.c b/src/asset/asset.c
new file mode 100644
index 0000000..a60cad2
--- /dev/null
+++ b/src/asset/asset.c
@@ -0,0 +1,99 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2012 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+// for mmap
+#include
+
+// for open and fstat
+#include
+#include
+#include
+
+// for access
+#include
+
+// for localtime
+#include
+
+
+#include "class.h"
+#include "asset.h"
+
+#include "utils/mime_type.h"
+
+static
+int
+assetCtor(void * _this, va_list * params)
+{
+ Asset this = _this;
+
+ struct tm * tmp;
+ struct stat st;
+ char * fname = va_arg(*params, char*);
+ char * ext;
+
+ this->nfname = va_arg(*params, size_t);
+
+ strncpy(this->fname, fname, 2047);
+ this->fname[2048] = '\0';
+
+ if (-1 == access(this->fname, O_RDONLY)) {
+ this->handle = -1;
+ } else {
+ this->handle = open(this->fname, O_RDONLY);
+ fstat(this->handle, &st);
+ }
+
+ tmp = localtime(&(st.st_mtime));
+ this->netag = strftime(this->etag, sizeof(this->etag), "%s", tmp);
+ this->nmtime = strftime(
+ this->mtime, sizeof(this->mtime), "%a, %d %b %Y %T %Z", tmp);
+
+ this->size = st.st_size;
+
+ ext = strrchr(this->fname, '.');
+ if (NULL != ext) {
+ ext++;
+ this->mime_type = getMimeType(ext, strlen(ext));
+ } else {
+ this->mime_type = "application/octet-stream";
+ }
+
+ this->data = mmap(
+ NULL, this->size, PROT_READ, MAP_PRIVATE, this->handle, 0);
+
+ return 0;
+}
+
+static void assetDtor(void * _this) {
+ Asset this = _this;
+
+ munmap(this->data, this->size);
+ close(this->handle);
+}
+
+INIT_IFACE(Class, assetCtor, assetDtor, NULL);
+CREATE_CLASS(Asset, NULL, IFACE(Class));
+
+// vim: set ts=4 sw=4:
diff --git a/src/mmapfiletest2.c b/src/mmapfiletest2.c
new file mode 100644
index 0000000..c5c1bd6
--- /dev/null
+++ b/src/mmapfiletest2.c
@@ -0,0 +1,54 @@
+// for random
+#include
+
+// for puts
+#include
+
+// for time
+#include
+
+#include "class.h"
+#include "commons.h"
+#include "utils/memory.h"
+
+#include "asset.h"
+
+int
+main(int argc, char * argv[])
+{
+ size_t i;
+ size_t position;
+ char print_buf[101];
+
+ Asset asset = new(Asset, CSTRA("./src/mmapfiletest.c"));
+
+ print_buf[100] = '\0';
+
+ srandom(time(NULL));
+ position = random() % (asset->size - 100);
+
+ for (i=0; i<100; i+=10) {
+ print_buf[i+0] = asset->data[position+i+0];
+ print_buf[i+1] = asset->data[position+i+1];
+ print_buf[i+2] = asset->data[position+i+2];
+ print_buf[i+3] = asset->data[position+i+3];
+ print_buf[i+4] = asset->data[position+i+4];
+ print_buf[i+5] = asset->data[position+i+5];
+ print_buf[i+6] = asset->data[position+i+6];
+ print_buf[i+7] = asset->data[position+i+7];
+ print_buf[i+8] = asset->data[position+i+8];
+ print_buf[i+9] = asset->data[position+i+9];
+ }
+
+ if (NULL != asset->mime_type) {
+ puts(asset->mime_type);
+ }
+ puts(print_buf);
+
+ delete(asset);
+ memCleanup();
+
+ return 0;
+}
+
+// vim: set et ts=4 sw=4:
diff --git a/src/utils/mime_type.c b/src/utils/mime_type.c
new file mode 100644
index 0000000..11899a5
--- /dev/null
+++ b/src/utils/mime_type.c
@@ -0,0 +1,111 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2012 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+// for fopen
+#include
+
+#include "hash.h"
+
+#include "class.h"
+#include "commons.h"
+
+Hash mime_types = NULL;
+
+void
+readMimeTypes(void)
+{
+ if (0 == access("./config/mime.types", O_RDONLY)) {
+ FILE * handle = fopen("./config/mime.types", "r");
+
+ if (NULL != handle) {
+ char buffer[512];
+
+ buffer[511] = '\0';
+ mime_types = new(Hash);
+
+ while (NULL != fgets(buffer, 511, handle)) {
+ char * tmp;
+ char * key = buffer;
+ char * value;
+ size_t nkey;
+ size_t nvalue;
+
+ tmp = memchr(key, ' ', 512);
+
+ if (NULL != tmp) {
+ *tmp = '\0';
+ }
+ nkey = tmp - buffer;
+
+ value = tmp + 1;
+ for (; *value == ' ' && value < buffer+511; value++);
+
+ nvalue = strlen(value);
+
+ if ('\n' == value[nvalue-1]) {
+ nvalue--;
+ value[nvalue] = '\0';
+ }
+
+ hashAdd(mime_types,
+ new(HashValue, key, nkey, value, nvalue));
+ }
+
+ fclose(handle);
+ }
+ }
+}
+
+char *
+getMimeType(const char * ext, size_t len)
+{
+ HashValue type;
+
+ if (NULL == mime_types) {
+ readMimeTypes();
+
+ if (NULL == mime_types) {
+ return NULL;
+ }
+ }
+
+ type = hashGet(mime_types, ext, len);
+
+ if (NULL == type) {
+ return NULL;
+ }
+
+ return (char *)type->value;
+}
+
+void
+clearMimeTypes(void)
+{
+ delete(mime_types);
+}
+
+// vim: set ts=4 sw=4: