| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- //go:build ios
- // +build ios
- package mobile
- /*
- #cgo CFLAGS: -x objective-c
- #cgo LDFLAGS: -framework Foundation
- #import <stdlib.h>
- #import <stdbool.h>
- bool iosExistsPath(const char* path);
- void* iosParseUrl(const char* url);
- const void* iosReadFromURL(void* url, int* len);
- const int iosWriteToURL(void* url, const void* bytes, int len);
- */
- import "C"
- import (
- "errors"
- "io"
- "unsafe"
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/storage/repository"
- )
- type secureReadCloser struct {
- url unsafe.Pointer
- closer func()
- data []byte
- offset int
- }
- // Declare conformity to ReadCloser interface
- var _ io.ReadCloser = (*secureReadCloser)(nil)
- func (s *secureReadCloser) Read(p []byte) (int, error) {
- if s.data == nil {
- var length C.int
- s.data = C.GoBytes(C.iosReadFromURL(s.url, &length), length)
- }
- count := len(p)
- remain := len(s.data) - s.offset
- var err error
- if count >= remain {
- count = remain
- err = io.EOF
- }
- newOffset := s.offset + count
- o := 0
- for i := s.offset; i < newOffset; i++ {
- p[o] = s.data[i]
- o++
- }
- s.offset = newOffset
- return count, err
- }
- func (s *secureReadCloser) Close() error {
- if s.closer != nil {
- s.closer()
- }
- s.url = nil
- return nil
- }
- type secureWriteCloser struct {
- url unsafe.Pointer
- closer func()
- offset int
- }
- // Declare conformity to WriteCloser interface
- var _ io.WriteCloser = (*secureWriteCloser)(nil)
- func (s *secureWriteCloser) Write(p []byte) (int, error) {
- count := int(C.iosWriteToURL(s.url, C.CBytes(p), C.int(len(p))))
- s.offset += count
- return count, nil
- }
- func (s *secureWriteCloser) Close() error {
- if s.closer != nil {
- s.closer()
- }
- s.url = nil
- return nil
- }
- func existsURI(u fyne.URI) (bool, error) {
- if u.Scheme() != "file" {
- return true, errors.New("cannot check existence of " + u.Scheme() + " on iOS")
- }
- cStr := C.CString(u.Path())
- defer C.free(unsafe.Pointer(cStr))
- exists := C.iosExistsPath(cStr)
- return bool(exists), nil
- }
- func nativeFileOpen(f *fileOpen) (io.ReadCloser, error) {
- if f.uri == nil || f.uri.String() == "" {
- return nil, nil
- }
- cStr := C.CString(f.uri.String())
- defer C.free(unsafe.Pointer(cStr))
- url := C.iosParseUrl(cStr)
- fileStruct := &secureReadCloser{url: url, closer: f.done}
- return fileStruct, nil
- }
- func nativeFileSave(f *fileSave) (io.WriteCloser, error) {
- if f.uri == nil || f.uri.String() == "" {
- return nil, nil
- }
- cStr := C.CString(f.uri.String())
- defer C.free(unsafe.Pointer(cStr))
- url := C.iosParseUrl(cStr)
- fileStruct := &secureWriteCloser{url: url, closer: f.done}
- return fileStruct, nil
- }
- func registerRepository(d *mobileDriver) {
- repo := &mobileFileRepo{}
- repository.Register("file", repo)
- }
|