la_int64_t OdinPatcher::Impl::laSkipCb(archive *a, void *userdata,
                                       la_int64_t request)
{
    (void) a;
    Impl *impl = static_cast<Impl *>(userdata);
    bool ret = true;

#ifdef __ANDROID__
    if (impl->fd >= 0) {
        if (lseek64(impl->fd, request, SEEK_CUR) < 0) {
            LOGE("%s: Failed to seek: %s", impl->info->inputPath().c_str(),
                 strerror(errno));
            ret = false;
        }
    } else {
#endif
        if (!impl->laFile.seek(request, io::File::SeekCurrent)) {
            LOGE("%s: Failed to seek: %s", impl->info->inputPath().c_str(),
                impl->laFile.errorString().c_str());
            ret = false;
        }
#ifdef __ANDROID__
    }
#endif

    if (ret) {
        impl->bytes += request;
        impl->updateProgress(impl->bytes, impl->maxBytes);
    } else {
        impl->error = ErrorCode::FileSeekError;
    }

    return ret ? request : -1;
}
la_ssize_t OdinPatcher::Impl::laReadCb(archive *a, void *userdata,
                                       const void **buffer)
{
    (void) a;
    Impl *impl = static_cast<Impl *>(userdata);
    *buffer = impl->laBuf;
    uint64_t bytesRead;
    bool ret = true;

#ifdef __ANDROID__
    if (impl->fd >= 0) {
        ssize_t n = read(impl->fd, impl->laBuf, sizeof(impl->laBuf));
        if (n < 0) {
            LOGE("%s: Failed to read: %s", impl->info->inputPath().c_str(),
                 strerror(errno));
            ret = false;
        } else {
            bytesRead = n;
        }
    } else {
#endif
        ret = impl->laFile.read(impl->laBuf, sizeof(impl->laBuf), &bytesRead);
        if (!ret && impl->laFile.error() == io::File::ErrorEndOfFile) {
            ret = true;
        }
        if (!ret) {
            LOGE("%s: Failed to read: %s", impl->info->inputPath().c_str(),
                 impl->laFile.errorString().c_str());
        }
#ifdef __ANDROID__
    }
#endif

    if (ret) {
        impl->bytes += bytesRead;
        impl->updateProgress(impl->bytes, impl->maxBytes);
    } else {
        impl->error = ErrorCode::FileReadError;
    }

    return ret ? (la_ssize_t) bytesRead : -1;
}
void MultiBootPatcher::Impl::laProgressCb(uint64_t bytes, void *userData)
{
    Impl *impl = static_cast<Impl *>(userData);
    impl->updateProgress(impl->bytes + bytes, impl->maxBytes);
}