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

Configure Feed

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

at master 85 lines 1.9 kB view raw
1# memory map crystal IO to C interop FILE* 2 3@[Link("c")] 4lib 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 %} 29end 30 31module 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 85end