generated from duckdb/extension-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
replace miniz with hand crafted parser
- Loading branch information
Showing
19 changed files
with
2,358 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
meta: | ||
id: pbix | ||
title: PBIX archive file | ||
file-extension: pbix | ||
endian: le | ||
bit-endian: le | ||
seq: | ||
- id: sections | ||
type: pk_section | ||
repeat: eos | ||
types: | ||
pk_section: | ||
seq: | ||
- id: magic | ||
contents: 'PK' | ||
- id: section_type | ||
type: u2 | ||
- id: body | ||
type: | ||
switch-on: section_type | ||
cases: | ||
0x0201: central_dir_entry | ||
0x0403: local_file | ||
0x0605: end_of_central_dir | ||
0x0807: data_descriptor | ||
data_descriptor: | ||
seq: | ||
- id: data_descriptor_obs | ||
size: 12 | ||
local_file: | ||
seq: | ||
- id: header | ||
type: local_file_header | ||
- id: body | ||
size: header.len_body_compressed | ||
local_file_header: | ||
seq: | ||
- id: header_trimmed | ||
size: 14 | ||
- id: len_body_compressed | ||
type: u4 | ||
- id: len_body_uncompressed | ||
type: u4 | ||
- id: len_file_name | ||
type: u2 | ||
- id: len_extra | ||
type: u2 | ||
- id: file_name | ||
size: len_file_name | ||
- id: extra | ||
size: len_extra | ||
central_dir_entry: | ||
seq: | ||
- id: header_obs | ||
size: 12 | ||
- id: crc32 | ||
type: u4 | ||
- id: len_body_compressed | ||
type: u4 | ||
- id: len_body_uncompressed | ||
type: u4 | ||
- id: len_file_name | ||
type: u2 | ||
- id: len_extra | ||
type: u2 | ||
- id: len_comment | ||
type: u2 | ||
- id: disk_number_start | ||
type: u2 | ||
- id: int_file_attr | ||
type: u2 | ||
- id: ext_file_attr | ||
type: u4 | ||
- id: ofs_local_header | ||
type: s4 | ||
- id: file_name | ||
type: str | ||
size: len_file_name | ||
encoding: UTF-8 | ||
- id: extra | ||
size: len_extra | ||
- id: comment | ||
size: len_comment | ||
end_of_central_dir: | ||
seq: | ||
- id: header_obs | ||
size: 16 | ||
- id: len_comment | ||
type: u2 | ||
- id: comment | ||
size: len_comment |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#include <iostream> | ||
#include <streambuf> | ||
#include "duckdb/common/file_system.hpp" | ||
|
||
class FileHandleStreamBuf : public std::streambuf { | ||
public: | ||
FileHandleStreamBuf(duckdb::FileHandle* handle) : handle(handle) {} | ||
|
||
protected: | ||
// Override underflow() to handle reading from the custom file system | ||
int underflow() override { | ||
if (gptr() < egptr()) { | ||
return traits_type::to_int_type(*gptr()); | ||
} | ||
char* base = &buffer[0]; | ||
setg(base, base, base); | ||
std::size_t n = handle->Read(base, buffer.size()); | ||
if (n == 0) return traits_type::eof(); | ||
setg(base, base, base + n); | ||
return traits_type::to_int_type(*gptr()); | ||
} | ||
|
||
// Override overflow() if you need write capability | ||
int overflow(int c = traits_type::eof()) override { | ||
return traits_type::eof(); // Indicate always full buffer (no writing) | ||
} | ||
|
||
// Override seekoff to handle seeking | ||
std::streampos seekoff(std::streamoff off, std::ios_base::seekdir dir, | ||
std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override { | ||
if (dir == std::ios_base::cur) { | ||
off += handle->SeekPosition(); | ||
} else if (dir == std::ios_base::end) { | ||
off += handle->GetFileSize(); | ||
} | ||
handle->Seek(off); | ||
return handle->SeekPosition(); | ||
} | ||
|
||
private: | ||
duckdb::FileHandle* handle; | ||
std::vector<char> buffer = std::vector<char>(1024); | ||
}; | ||
|
||
class FileHandleStream : public std::istream { | ||
public: | ||
FileHandleStream(duckdb::FileHandle* handle) | ||
: std::istream(nullptr), buf(handle) { | ||
rdbuf(&buf); | ||
} | ||
|
||
private: | ||
FileHandleStreamBuf buf; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#pragma once | ||
|
||
#include <istream> | ||
#include <streambuf> | ||
#include <vector> | ||
#include "duckdb/common/file_system.hpp" | ||
|
||
namespace duckdb { | ||
|
||
class FileHandleStreamBuf : public std::streambuf { | ||
public: | ||
explicit FileHandleStreamBuf(FileHandle* handle); | ||
|
||
protected: | ||
// Override underflow() to handle reading from the custom file system | ||
int underflow() override; | ||
|
||
// Override overflow() if you need write capability | ||
int overflow(int c = traits_type::eof()) override; | ||
|
||
// Override seekoff to handle seeking | ||
std::streampos seekoff(std::streamoff off, std::ios_base::seekdir dir, | ||
std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override; | ||
|
||
private: | ||
FileHandle* handle; | ||
std::vector<char> buffer; | ||
}; | ||
|
||
class FileHandleStream : public std::istream { | ||
public: | ||
explicit FileHandleStream(FileHandle* handle); | ||
|
||
private: | ||
FileHandleStreamBuf buf; | ||
}; | ||
|
||
} // namespace duckdb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#include "ZipUtils.h" | ||
#include <iostream> | ||
#include <fstream> | ||
#include <vector> | ||
#include <algorithm> | ||
#include <cstring> | ||
|
||
class ZipUtils { | ||
public: | ||
static bool findEndOfCentralDirectory(std::istream& stream, EndOfCentralDirectoryRecord& eocd) { | ||
const uint32_t signatureEOCD = 0x06054b50; | ||
std::vector<char> buffer(4096); | ||
stream.seekg(0, std::ios::end); | ||
std::streampos fileSize = stream.tellg(); | ||
int64_t searchOffset = std::min(static_cast<int64_t>(fileSize), static_cast<int64_t>(buffer.size())); | ||
|
||
stream.seekg(-searchOffset, std::ios::end); | ||
stream.read(buffer.data(), searchOffset); | ||
auto foundPos = std::search(buffer.rbegin(), buffer.rend(), reinterpret_cast<const char*>(&signatureEOCD), reinterpret_cast<const char*>(&signatureEOCD) + sizeof(signatureEOCD)); | ||
|
||
if (foundPos != buffer.rend()) { | ||
size_t offset = std::distance(buffer.begin(), foundPos.base()) - sizeof(signatureEOCD); | ||
stream.seekg(-searchOffset + offset, std::ios::end); | ||
stream.read(reinterpret_cast<char*>(&eocd), sizeof(eocd)); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
static std::pair<uint32_t, uint32_t> findDataModel(std::istream& zipStream) { | ||
EndOfCentralDirectoryRecord eocd; | ||
if (!findEndOfCentralDirectory(zipStream, eocd)) { | ||
throw std::runtime_error("End of central directory not found."); | ||
} | ||
|
||
zipStream.seekg(eocd.centralDirectoryOffset, std::ios::beg); | ||
CentralDirectoryFileHeader cdHeader; | ||
|
||
for (int i = 0; i < eocd.numEntries; ++i) { | ||
zipStream.read(reinterpret_cast<char*>(&cdHeader), sizeof(cdHeader)); | ||
if (cdHeader.signature != 0x02014b50) { | ||
throw std::runtime_error("Invalid central directory file header signature."); | ||
} | ||
|
||
std::vector<char> filename(cdHeader.fileNameLength); | ||
zipStream.read(filename.data(), cdHeader.fileNameLength); | ||
zipStream.ignore(cdHeader.extraFieldLength + cdHeader.fileCommentLength); | ||
|
||
if (std::string(filename.begin(), filename.end()) == "DataModel") { | ||
return {cdHeader.localHeaderOffset, cdHeader.compressedSize}; | ||
} | ||
} | ||
|
||
throw std::runtime_error("DataModel not found in the zip file."); | ||
} | ||
}; |
Oops, something went wrong.