示例#1
0
 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));
     }
 }
示例#2
0
        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;
            });
        }
示例#3
0
        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);
        }
示例#5
0
 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) { }
 }
示例#6
0
        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);
            });
        }
示例#7
0
        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);
            });
        }
示例#8
0
 private void ClearRepl()
 {
     DispatchQueue.DispatchSync(() =>
     {
         Native.c4repl_free(_repl);
         _repl = null;
         _desc = null;
     });
 }
示例#9
0
 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) { }
 }
示例#10
0
        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);
            });
        }
示例#11
0
        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);
                });
            }
        }
示例#12
0
        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);
示例#15
0
        // 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);
示例#24
0
 public static extern void c4repl_free(C4Replicator *repl);
 public static extern C4ReplicatorStatus c4repl_getStatus(C4Replicator *repl);
示例#26
0
 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);