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: