public static void c4repl_setOptions(C4Replicator *repl, byte[] optionsDictFleece) { fixed(byte *optionsDictFleece_ = optionsDictFleece) { NativeRaw.c4repl_setOptions(repl, new FLSlice(optionsDictFleece_, optionsDictFleece == null ? 0 : (ulong)optionsDictFleece.Length)); } }
private void Dispose(bool finalizing) { DispatchQueue.DispatchSync(() => { if (_disposed) { return; } if (!finalizing) { _nativeParams?.Dispose(); if (Status.Activity != ReplicatorActivityLevel.Stopped) { var newStatus = new ReplicatorStatus(ReplicatorActivityLevel.Stopped, Status.Progress, null); _statusChanged.Fire(this, new ReplicatorStatusChangedEventArgs(newStatus)); Status = newStatus; } } Stop(); Native.c4repl_free(_repl); _repl = null; _disposed = true; }); }
public static IDictionary <string, object> bridge_c4repl_getResponseHeaders(C4Replicator *repl) { var result = c4repl_getResponseHeaders(repl); return(FLSliceExtensions.ToObject(NativeRaw.FLValue_FromTrustedData((FLSlice)result)) as IDictionary <string, object>); }
private static void StateChanged(C4Replicator *replicator, C4ReplicatorStatus state, void *context) { var id = (long)context; var obj = _StaticMap[id]; obj._callback?.Invoke(state, obj._context); }
private static void StateChanged(C4Replicator *replicator, C4ReplicatorStatus state, void *context) { // Don't throw exceptions here, it will bubble up to native code try { var id = (long)context; var obj = _StaticMap[id]; obj._stateChangedCallback?.Invoke(state, obj._context); } catch (Exception) { } }
private static void OnDocError(C4Replicator *repl, bool pushing, C4Slice docID, C4Error error, bool transient, void *context) { var replicator = GCHandle.FromIntPtr((IntPtr)context).Target as Replicator; replicator?.DispatchQueue.DispatchAsync(() => { replicator.OnDocError(error, pushing, docID.CreateString() ?? "", transient); }); }
private static void StatusChangedCallback(C4Replicator *repl, C4ReplicatorStatus status, void *context) { var replicator = GCHandle.FromIntPtr((IntPtr)context).Target as Replicator; replicator?.DispatchQueue.DispatchSync(() => { replicator.StatusChangedCallback(status); }); }
private void ClearRepl() { DispatchQueue.DispatchSync(() => { Native.c4repl_free(_repl); _repl = null; _desc = null; }); }
private static void OnError(C4Replicator *replicator, bool pushing, C4Slice docID, C4Error error, bool transient, void *context) { // Don't throw exceptions here, it will bubble up to native code try { var id = (long)context; var obj = _StaticMap[id]; obj._errorCallback?.Invoke(pushing, docID.CreateString(), error, transient, obj._context); } catch (Exception) { } }
private static void StatusChangedCallback(C4Replicator *repl, C4ReplicatorStatus status, void *context) { var replicator = GCHandle.FromIntPtr((IntPtr)context).Target as Replicator; if (replicator == null) { return; } replicator.WaitPendingConflictTasks(status); replicator.DispatchQueue.DispatchSync(() => { replicator.StatusChangedCallback(status); }); }
private static void OnDocEnded(C4Replicator *repl, bool pushing, IntPtr numDocs, C4DocumentEnded **docs, void *context) { if (docs == null || numDocs == IntPtr.Zero) { return; } var replicatedDocumentsContainConflict = new List <ReplicatedDocument>(); var documentReplications = new List <ReplicatedDocument>(); for (int i = 0; i < (int)numDocs; i++) { var current = docs[i]; if (!pushing && current->error.domain == C4ErrorDomain.LiteCoreDomain && current->error.code == (int)C4ErrorCode.Conflict) { replicatedDocumentsContainConflict.Add(new ReplicatedDocument(current->docID.CreateString() ?? "", current->flags, current->error, current->errorIsTransient)); } else { documentReplications.Add(new ReplicatedDocument(current->docID.CreateString() ?? "", current->flags, current->error, current->errorIsTransient)); } } var replicator = GCHandle.FromIntPtr((IntPtr)context).Target as Replicator; if (documentReplications.Count > 0) { replicator?.DispatchQueue.DispatchAsync(() => { replicator.OnDocEnded(documentReplications, pushing); }); } if (replicatedDocumentsContainConflict.Count > 0) { replicator?.DispatchQueue.DispatchAsync(() => { replicator.OnDocEndedWithConflict(replicatedDocumentsContainConflict); }); } }
private static void OnDocEnded(C4Replicator *repl, bool pushing, IntPtr numDocs, C4DocumentEnded **docs, void *context) { if (docs == null || numDocs == IntPtr.Zero) { return; } var documentReplications = new ReplicatedDocument[(int)numDocs]; for (int i = 0; i < (int)numDocs; i++) { var current = docs[i]; documentReplications[i] = new ReplicatedDocument(current->docID.CreateString() ?? "", current->flags, current->error, current->errorIsTransient); } var replicator = GCHandle.FromIntPtr((IntPtr)context).Target as Replicator; replicator?.DispatchQueue.DispatchAsync(() => { replicator.OnDocEnded(documentReplications, pushing); }); }
public static extern bool c4repl_isDocumentPending(C4Replicator *repl, FLSlice docID, C4Error *outErr);
public static extern FLSliceResult c4repl_getPendingDocIDs(C4Replicator *repl, C4Error *outErr);
// Must be called from within the ThreadSafety private void StartInternal() { _desc = ToString(); // Cache this; it may be called a lot when logging // Target: var addr = new C4Address(); var scheme = new C4String(); var host = new C4String(); var path = new C4String(); Database otherDB = null; var remoteUrl = Config.RemoteUrl; string dbNameStr = null; if (remoteUrl != null) { var pathStr = String.Concat(remoteUrl.Segments.Take(remoteUrl.Segments.Length - 1)); dbNameStr = remoteUrl.Segments.Last().TrimEnd('/'); scheme = new C4String(remoteUrl.Scheme); host = new C4String(remoteUrl.Host); path = new C4String(pathStr); addr.scheme = scheme.AsC4Slice(); addr.hostname = host.AsC4Slice(); addr.port = (ushort)remoteUrl.Port; addr.path = path.AsC4Slice(); } else { otherDB = Config.OtherDB; } var options = Config.Options; var userInfo = remoteUrl?.UserInfo?.Split(':'); if (userInfo?.Length == 2) { throw new ArgumentException( "Embedded credentials in a URL (username:password@url) are not allowed; use the BasicAuthenticator class instead"); } Config.Authenticator?.Authenticate(options); options.Build(); var push = Config.ReplicatorType.HasFlag(ReplicatorType.Push); var pull = Config.ReplicatorType.HasFlag(ReplicatorType.Pull); var continuous = Config.Continuous; // Clear the reset flag, it is a one-time thing Config.Options.Reset = false; var socketFactory = Config.SocketFactory; socketFactory.context = GCHandle.ToIntPtr(GCHandle.Alloc(this)).ToPointer(); _nativeParams = new ReplicatorParameters(options) { Push = Mkmode(push, continuous), Pull = Mkmode(pull, continuous), Context = this, OnDocumentError = OnDocError, OnStatusChanged = StatusChangedCallback, SocketFactory = &socketFactory }; var err = new C4Error(); var status = default(C4ReplicatorStatus); _stopping = false; _databaseThreadSafety.DoLocked(() => { C4Error localErr; _repl = Native.c4repl_new(Config.Database.c4db, addr, dbNameStr, otherDB != null ? otherDB.c4db : null, _nativeParams.C4Params, &localErr); err = localErr; if (_repl != null) { status = Native.c4repl_getStatus(_repl); Config.Database.ActiveReplications.Add(this); } else { status = new C4ReplicatorStatus { error = err, level = C4ReplicatorActivityLevel.Stopped, progress = new C4Progress() }; } }); scheme.Dispose(); path.Dispose(); host.Dispose(); UpdateStateProperties(status); DispatchQueue.DispatchSync(() => StatusChangedCallback(status)); }
public void c4repl_stop(C4Replicator *repl) => Native.c4repl_stop(repl);
public C4ReplicatorStatus c4repl_getStatus(C4Replicator *repl) => Native.c4repl_getStatus(repl);
public C4Slice c4repl_getResponseHeaders(C4Replicator *repl) => Native.c4repl_getResponseHeaders(repl);
public static extern bool c4repl_setProgressLevel(C4Replicator *repl, C4ReplicatorProgressLevel level, C4Error *outErr);
public static byte[] c4repl_getPendingDocIDs(C4Replicator *repl, C4Error *outErr) { using (var retVal = NativeRaw.c4repl_getPendingDocIDs(repl, outErr)) { return(((FLSlice)retVal).ToArrayFast()); } }
public static extern void c4repl_setHostReachable(C4Replicator *repl, [MarshalAs(UnmanagedType.U1)] bool reachable);
public static extern void c4repl_start(C4Replicator *repl, [MarshalAs(UnmanagedType.U1)] bool reset);
public static extern void c4repl_stop(C4Replicator *repl);
public static extern void c4repl_free(C4Replicator *repl);
public static extern C4ReplicatorStatus c4repl_getStatus(C4Replicator *repl);
public static extern C4Slice c4repl_getResponseHeaders(C4Replicator *repl);
public static bool c4repl_isDocumentPending(C4Replicator *repl, string docID, C4Error *outErr) { using (var docID_ = new C4String(docID)) { return(NativeRaw.c4repl_isDocumentPending(repl, docID_.AsFLSlice(), outErr)); } }
public static extern bool c4repl_retry(C4Replicator *repl, C4Error *outError);
public static extern void c4repl_setOptions(C4Replicator *repl, FLSlice optionsDictFleece);
public static extern C4Cert *c4repl_getPeerTLSCertificate(C4Replicator *repl, C4Error *outErr);