123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- using Invercargill;
- using Gee;
- namespace Ppub {
- public class Builder {
- private Series<BuilderAsset> assets = new Series<BuilderAsset>();
- private uint64 position = 0;
- public void add_metadata(Metadata metadata) {
- var data = (uint8[])metadata.to_string().to_utf8();
- var mis = new MemoryInputStream.from_data(data);
- var compress = new CompressionInfo(mis);
- mis.seek(0, SeekType.SET);
- add_asset("metadata", "application/x-ppub-metadata", mis, empty<string>(), compress);
- }
- public void add_asset(string name, string mimetype, InputStream stream, Enumerable<string> flags, CompressionInfo compression) {
- lock(assets) {
- var asset = new BuilderAsset();
- asset.name = name;
- asset.start_location = position;
- asset.end_location = position + compression.size_in_ppub;
- asset.mimetype = mimetype;
- asset.stream = stream;
- // Exclude any gzip flags, as we will add that later if we are compressing the content
- asset.flags = flags.where(f => f != "gzip").to_vector();
- if(compression.compress) {
- asset.flags.add("gzip");
- }
-
- position += compression.size_in_ppub;
- assets.add(asset);
- }
- }
- public void write(OutputStream stream) throws IOError {
- var index_entries = assets.to_string(a => a.to_string());
- print(index_entries);
- var index_data = (uint8[])index_entries.to_utf8();
- var header_data = (uint8[])(@"$(Publication.MAGIC)\n$(index_data.length)\n".to_utf8());
- stream.write(header_data);
- stream.write(index_data);
- foreach (var asset in assets) {
- if(asset.flags.any(f => f == "gzip")) {
- var compressor = new ZlibCompressor(ZlibCompressorFormat.GZIP, 9);
- var conv_stream = new ConverterInputStream(asset.stream, compressor);
- stream.splice(conv_stream, OutputStreamSpliceFlags.CLOSE_SOURCE);
- }
- else {
- stream.splice(asset.stream, OutputStreamSpliceFlags.CLOSE_SOURCE);
- }
- }
- }
- }
- public class BuilderAsset : Asset {
-
- public InputStream stream {get; set;}
- }
- public class CompressionInfo {
- public bool compress {get; private set;}
- public uint64 uncompressed_size {get; private set;}
- public uint64 compressed_size {get; private set;}
- public CompressionInfo.uncompressed(uint64 size) {
- compress = false;
- uncompressed_size = size;
- }
- public CompressionInfo(InputStream stream, CompressionPolicy policy = CompressionPolicy.AUTO) throws IOError {
- var uncompressed_counter = new InputStreamMonitor(stream);
- var compressor = new ZlibCompressor(ZlibCompressorFormat.GZIP, 9);
- var conv_stream = new ConverterInputStream(uncompressed_counter, compressor);
- var compressed_counter = new InputStreamMonitor(conv_stream);
-
- compressed_counter.count_to_end();
- uncompressed_size = uncompressed_counter.bytes_read;
- compressed_size = compressed_counter.bytes_read;
- switch (policy) {
- case CompressionPolicy.AUTO:
- compress = uncompressed_size > compressed_size;
- break;
- case CompressionPolicy.ALWAYS_COMPRESS:
- compress = true;
- break;
- case CompressionPolicy.NEVER_COMPRESS:
- compress = false;
- break;
- }
- }
- public uint64 size_in_ppub {
- get {
- return compress ? compressed_size : uncompressed_size;
- }
- }
- }
- public enum CompressionPolicy {
- AUTO,
- ALWAYS_COMPRESS,
- NEVER_COMPRESS
- }
- public static string guess_mimetype(string name, uint8[] sample) {
- if(name == "metadata") {
- return "application/x-ppub-metadata";
- }
- if(name.has_suffix(".ppvm")) {
- return "application/x-ppvm";
- }
- bool result_uncertain;
- var content_type = ContentType.guess(name, sample, out result_uncertain);
- var mime = ContentType.get_mime_type(content_type);
- return mime ?? "application/octet-stream";
- }
- }
|