Beispiel #1
0
VFS_NAMESPACE_START

// From miniz.c
//#define MZ_ZIP_MODE_READING 2


static bool zip_reader_reopen_vfsfile(mz_zip_archive *pZip, mz_uint32 flags)
{
    if(!(pZip && pZip->m_pIO_opaque && pZip->m_pRead))
        return false;
    VFSFile *vf = (VFSFile*)pZip->m_pIO_opaque;
    if(!vf->isopen())
        if(!vf->open("rb"))
            return false;
    if(pZip->m_zip_mode == MZ_ZIP_MODE_READING)
        return true;
    mz_uint64 file_size = vf->size();
    if(!file_size)
    {
        vf->close();
        return false;
    }
    if (!mz_zip_reader_init(pZip, file_size, flags))
    {
        vf->close();
        return false;
    }
    return true;
}
Beispiel #2
0
ZipReader::ZipReader(const Path &p)
: _path(p),
  _in(FileUtils::openInputStream(p))
{
    if (!_in)
        FAIL("Failed to construct ZipReader: Input stream is invalid");
    uint64 size = FileUtils::fileSize(p);
    if (size == 0)
    	FAIL("Failed to construct ZipReader: Error reading file size");

    std::memset(&_archive, 0, sizeof(mz_zip_archive));
    _archive.m_pRead = &minizFileReadFunc;
    _archive.m_pIO_opaque = _in.get();
    if (!mz_zip_reader_init(&_archive, size, 0))
        FAIL("Initializing zip reader failed");

    int count = mz_zip_reader_get_num_files(&_archive);
    for (int i = 0; i < count; ++i) {
    	mz_zip_archive_file_stat stat;
    	mz_zip_reader_file_stat(&_archive, i, &stat);

    	ZipEntry entry;
    	entry.fullPath = Path(stat.m_filename);
    	entry.name = entry.fullPath.fileName();
    	entry.size = stat.m_uncomp_size;
    	entry.isDirectory = !entry.fullPath.empty() && entry.fullPath.asString().back() == '/';
    	entry.archiveIndex = i;

    	addPath(Path(stat.m_filename).stripSeparator(), std::move(entry));
    }
}
Beispiel #3
0
static bool zip_reader_init_vfsfile(mz_zip_archive *pZip, VFSFile *vf, mz_uint32 flags)
{
    if(!(pZip || vf))
        return false;
    vf->open("rb");
    mz_uint64 file_size = vf->size();
    if(!file_size)
    {
        vf->close();
        return false;
    }
    pZip->m_pRead = zip_read_func;
    pZip->m_pIO_opaque = vf;
    if (!mz_zip_reader_init(pZip, file_size, flags))
    {
        vf->close();
        return false;
    }
    return true;
}
Beispiel #4
0
static int lmz_reader_init(lua_State* L) {
  const char* path = luaL_checkstring(L, 1);
  mz_uint32 flags = luaL_optint(L, 2, 0);
  mz_uint64 size;
  lmz_file_t* zip = lua_newuserdata(L, sizeof(*zip));
  mz_zip_archive* archive = &(zip->archive);
  luaL_getmetatable(L, "miniz_reader");
  lua_setmetatable(L, -2);
  memset(archive, 0, sizeof(*archive));
  zip->loop = uv_default_loop();
  zip->fd = uv_fs_open(zip->loop, &(zip->req), path, O_RDONLY, 0644, NULL);
  uv_fs_fstat(zip->loop, &(zip->req), zip->fd, NULL);
  size = zip->req.statbuf.st_size;
  archive->m_pRead = lmz_file_read;
  archive->m_pIO_opaque = zip;
  if (!mz_zip_reader_init(archive, size, flags)) {
    lua_pushnil(L);
    lua_pushfstring(L, "read %s fail because of %s", path,
      mz_zip_get_error_string(mz_zip_get_last_error(archive)));
    return 2;
  }
  return 1;
}
adapt_serving_context* adapt_start_serving(adapt_callback* callback) {
    int tries;
    int file_index;
    char* rewrites = 0;
    char* document_root = 0;
    adapt_serving_context* context = (adapt_serving_context*)calloc(sizeof(adapt_serving_context), 1);
    time_t timeval;
    adapt_resource_init();
    time(&timeval);
    sprintf(context->content_prefix, "/E%lx/", timeval);
    sprintf(context->html_prefix, "/H%lx/", timeval);
    sprintf(context->msg_url, "/M%lx", timeval);
    context->callback = callback;
    if (callback->packaging_type == ADAPT_PACKAGE_ZIP) {
        context->zip.m_pRead = adapt_file_read_func;
        context->zip.m_pIO_opaque = callback;
        if (!mz_zip_reader_init(&context->zip, callback->content_length, MZ_ZIP_FLAG_CASE_SENSITIVE)) {
            free(context);
            return NULL;
        }
        // Check if this is an epub file.
        file_index = mz_zip_reader_locate_file(&context->zip, "META-INF/container.xml", NULL,
                                               MZ_ZIP_FLAG_CASE_SENSITIVE);
        context->content_type = TYPE_UNKNOWN;
        if (file_index >= 0) {
            // This looks like epub
            context->content_type = TYPE_OPF;
        } else {
            // This is not an epub. Maybe fb2.zip?
            mz_zip_archive_file_stat file_info;
            if (mz_zip_reader_file_stat(&context->zip, 0, &file_info)) {
                const char* filename = file_info.m_filename;
                size_t len = strlen(filename);
                if (len > 4 && strcmp(filename + len - 4, ".fb2") == 0) {
                    // This is FB2 file
                    context->content_type = TYPE_XML;
                    context->content = strcpy((char*)malloc(strlen(filename) + 1), filename);
                }
            }
        }
    } else if (callback->packaging_type == ADAPT_PACKAGE_FILE_SYSTEM) {
        size_t len;
        char* container_name;
        char* end;
        if (!callback->base_path) {
            free(context);
            return NULL;
        }
        // Go through the parent folder chain trying to find META-INF/container.xml (that will serve as
        // the package root)
        len = strlen(callback->base_path);
        container_name = (char*)malloc(len + 25);
        strcpy(container_name, callback->base_path);
        end = container_name + len;
        do {
            char * q = end - 1;
            while (container_name + 3 < q && *q != '/') {
                q--;
            }
            if (*q != '/') {
                break;
            }
            end = q;
            strcpy(end + 1, "META-INF/container.xml");
        } while (!file_exists(container_name));
        if (*end != '/') {
            free(context);
            return NULL;
        }
        if (len < 4 || strcmp(callback->base_path + len - 4, ".opf") == 0) {
            context->content_type = TYPE_OPF;
        } else {
            size_t prefix_len = (end - container_name + 1);
            const char* path = callback->base_path + prefix_len;
            context->content = strcpy((char*)malloc(strlen(path) + 1), path);
            context->content_type = TYPE_XML;
            context->prefix_len = prefix_len;
        }
        end[1] = '\0';
        rewrites = (char*)malloc(strlen(container_name) + strlen(context->content_prefix) + 2);
        sprintf(rewrites, "%s=%s", context->content_prefix, container_name);
        document_root = container_name;
    } else if (callback->packaging_type == ADAPT_PACKAGE_SINGLE_FILE) {
        // Assume it's FB2
        context->content_type = TYPE_XML;
        context->content = strcpy((char*)malloc(9), "file.fb2");
    }
    if (context->content_type == TYPE_UNKNOWN) {
        adapt_stop_serving(context);
        return NULL;
    }
    context->server_callbacks.begin_request = adapt_serve;
    context->options = (char**)calloc(sizeof(char*), 7);
    context->options[0] = strcpy((char*)malloc(16), "listening_ports");
    context->options[1] = (char*)calloc(100, 1);
    if (rewrites) {
        context->options[2] = strcpy((char*)malloc(24), "url_rewrite_patterns");
        context->options[3] = rewrites;
        context->options[4] = strcpy((char*)malloc(24), "document_root");
        context->options[5] = document_root;
    }
    tries = 0;
    do {
        sprintf(context->options[1], "127.0.0.1:%d", adapt_port);
        context->server_context = mg_start(&context->server_callbacks, context, (const char**)context->options);
        sprintf(context->bootstrap_url, "http://127.0.0.1:%d%sdriver.xhtml",
                adapt_port, context->html_prefix);
        adapt_port++;
        tries++;
    } while (!context->server_context && tries < 10);
    return context;
}