xar unarchiver (.xar, .pkg, .xip)
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

add memory-mapped io FILE* interop

+85
+85
memfile.cr
··· 1 + # memory map crystal IO to C interop FILE* 2 + 3 + @[Link("c")] 4 + lib LibC 5 + alias FILE = Void 6 + 7 + {% if flag?(:darwin) %} 8 + fun funopen( 9 + cookie : Void*, 10 + readfn : (Void*, UInt8*, LibC::SizeT) -> LibC::SizeT, 11 + writefn : Void*, 12 + seekfn : (Void*, LibC::OffT, Int32) -> LibC::OffT, 13 + closefn : (Void*) -> Int32 14 + ) : FILE* 15 + {% else %} 16 + fun fopencookie( 17 + cookie : Void*, 18 + mode : LibC::Char*, 19 + ops : CookieIO 20 + ) : FILE* 21 + 22 + struct CookieIO 23 + read : (Void*, UInt8*, LibC::SizeT) -> LibC::SizeT 24 + write : Void* 25 + seek : (Void*, LibC::OffT, Int32) -> LibC::OffT 26 + close : (Void*) -> Int32 27 + end 28 + {% end %} 29 + end 30 + 31 + module MemFile 32 + class IOCookie 33 + getter io : IO 34 + 35 + def initialize(@io : IO) 36 + end 37 + end 38 + 39 + def self.from_io(io : IO) : Pointer(LibC::FILE) 40 + cookie = Box.box(IOCookie.new(io)) 41 + 42 + read_cb = ->(cookie_ptr : Void*, buf : UInt8*, size : LibC::SizeT) : LibC::SizeT { 43 + wrapper = Box(IOCookie).unbox(cookie_ptr) 44 + begin 45 + bytes_read = wrapper.io.read(Slice.new(buf, size)) 46 + bytes_read.to_u64 47 + rescue 48 + 0.to_u64 49 + end 50 + } 51 + 52 + seek_cb = ->(cookie_ptr : Void*, offset : LibC::OffT, whence : Int32) : LibC::OffT { 53 + wrapper = Box(IOCookie).unbox(cookie_ptr) 54 + begin 55 + wrapper.io.seek(offset, IO::Seek.new(whence)) 56 + wrapper.io.pos.to_i64 57 + rescue 58 + -1.to_i64 59 + end 60 + } 61 + 62 + close_cb = ->(cookie_ptr : Void*) : Int32 { 63 + Box(IOCookie).unbox(cookie_ptr) # let GC handle it 64 + 0 65 + } 66 + 67 + {% if flag?(:darwin) %} 68 + LibC.funopen( 69 + cookie.as(Void*), 70 + read_cb, 71 + Pointer(Void).null, 72 + seek_cb, 73 + close_cb 74 + ) 75 + {% else %} 76 + ops = LibC::CookieIO.new( 77 + read: read_cb, 78 + write: Pointer(Void).null, 79 + seek: seek_cb, 80 + close: close_cb 81 + ) 82 + LibC.fopencookie(cookie.as(Void*), "r".to_unsafe, ops) 83 + {% end %} 84 + end 85 + end