1 /* 2 * Compression utility header 3 * 4 * Copyright: 5 * (C) 2014 Jack Lloyd 6 * (C) 2015 Etienne Cimon 7 * 8 * License: 9 * Botan is released under the Simplified BSD License (see LICENSE.md) 10 */ 11 12 module botan.compression.compress_utils; 13 14 import memutils.hashmap; 15 import botan.utils.mem_ops; 16 import botan.compression.compress; 17 import memutils.unique; 18 19 /* 20 * Allocation Size Tracking Helper for Zlib/Bzlib/LZMA 21 */ 22 class CompressionAllocInfo 23 { 24 public: 25 extern(C) static void* malloc(T)(void* self, T n, T size) nothrow 26 { 27 return (cast(CompressionAllocInfo)self).doMalloc(n, size); 28 } 29 30 extern(C) static void free(void* self, void* ptr) nothrow 31 { 32 (cast(CompressionAllocInfo)self).doFree(ptr); 33 } 34 35 private: 36 void* doMalloc(size_t n, size_t size) nothrow 37 { 38 import core.stdc.stdlib : malloc; 39 const size_t total_sz = n * size; 40 41 void* ptr = malloc(total_sz); 42 try m_current_allocs[ptr] = total_sz; 43 catch(Exception e) assert(false, e.msg); 44 return ptr; 45 } 46 void doFree(void* ptr) nothrow 47 { 48 if (ptr) 49 { 50 import core.stdc.stdlib : free; 51 size_t* sz; 52 try sz = ptr in m_current_allocs; 53 catch (Exception e) assert(false, e.msg); 54 if (sz is null) 55 assert(false, "CompressionAllocInfo.free got pointer not allocated by us"); 56 57 clearMem(ptr, *sz); 58 free(ptr); 59 try m_current_allocs.remove(ptr); 60 catch (Exception e) assert(false, e.msg); 61 } 62 } 63 64 HashMap!(void*, size_t) m_current_allocs; 65 } 66 67 /** 68 * Wrapper for Zlib/Bzlib/LZMA stream types 69 */ 70 abstract class ZlibStyleStream(Stream, ByteType) : CompressionStream 71 { 72 public: 73 override void nextIn(ubyte* b, size_t len) 74 { 75 m_stream.next_in = cast(ByteType*)(b); 76 m_stream.avail_in = cast(uint)len; 77 } 78 79 override void nextOut(ubyte* b, size_t len) 80 { 81 m_stream.next_out = cast(ByteType*)(b); 82 m_stream.avail_out = cast(uint)len; 83 } 84 85 override size_t availIn() const { return m_stream.avail_in; } 86 87 override size_t availOut() const { return m_stream.avail_out; } 88 89 this() 90 { 91 clearMem(&m_stream, 1); 92 m_allocs = new CompressionAllocInfo; 93 } 94 95 ~this() 96 { 97 clearMem(&m_stream, 1); 98 m_allocs.free(); 99 } 100 101 protected: 102 alias stream_t = Stream; 103 104 stream_t* streamp() { return &m_stream; } 105 106 CompressionAllocInfo alloc() { return m_allocs.get(); } 107 private: 108 stream_t m_stream; 109 Unique!CompressionAllocInfo m_allocs; 110 }