private void Init(bool canRead, bool canWrite, bool canSeek, bool canRelease) { #if (VERBOSE_DEBUG) DebugOutput("GpgmeCbsData.Init(" + canRead.ToString() + "," + canWrite.ToString() + "," + canSeek.ToString() + "," + canRelease.ToString() + ")"); #endif _handle = IncGlobalHandle(); // increment the global handle _cbs = new _gpgme_data_cbs(); _cbs_lfs = new _gpgme_data_cbs_lfs(); // Read function if (canRead) { _cbs.read = InternalReadCallback; _cbs_lfs.read = InternalReadCallback; } else { _cbs.read = null; _cbs_lfs.read = null; } // Write function if (canWrite) { _cbs.write = InternalWriteCallback; _cbs_lfs.write = InternalWriteCallback; } else { _cbs.write = null; _cbs_lfs.write = null; } // Seek function if (canSeek) { _cbs.seek = InternalSeekCallback; _cbs_lfs.seek = InternalSeekLfsCallback; } else { _cbs.seek = null; _cbs_lfs.seek = null; } // Release if (canRelease) { _cbs.release = InternalReleaseCallback; _cbs_lfs.release = InternalReleaseCallback; } else { _cbs.release = null; _cbs_lfs.release = null; } _pinned_cbs = GCHandle.Alloc(_cbs); _pinned_cbs_lfs = GCHandle.Alloc(_cbs_lfs); if (libgpgme.use_lfs) { _cbs_ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(_cbs_lfs)); Marshal.StructureToPtr(_cbs_lfs, _cbs_ptr, false); } else { _cbs_ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(_cbs)); Marshal.StructureToPtr(_cbs, _cbs_ptr, false); } int err = libgpgme.NativeMethods.gpgme_data_new_from_cbs( out dataPtr, _cbs_ptr, _handle); #if (VERBOSE_DEBUG) DebugOutput("gpgme_data_new_from_cbs(..) DONE."); #endif gpg_err_code_t errcode = libgpgme.gpgme_err_code(err); if (errcode == gpg_err_code_t.GPG_ERR_NO_ERROR) { return; } if (errcode == gpg_err_code_t.GPG_ERR_ENOMEM) { throw new OutOfMemoryException("Not enough memory available to create user defined GPGME data object."); } throw new GeneralErrorException("Unknown error " + errcode + " (" + err + ")"); }
internal static extern int gpgme_data_new_from_cbs( [Out] out IntPtr dh, [In][MarshalAs(UnmanagedType.FunctionPtr)] _gpgme_data_cbs cbs, //gpgme_data_cbs_t [In] IntPtr handle);