Exemple #1
0
        /// <param name="input"> input tokenstream </param>
        /// <param name="synonyms"> synonym map </param>
        /// <param name="ignoreCase"> case-folds input for matching with <see cref="Character.ToLower(int, CultureInfo)"/>
        ///                   in using <see cref="CultureInfo.InvariantCulture"/>.
        ///                   Note, if you set this to <c>true</c>, its your responsibility to lowercase
        ///                   the input entries when you create the <see cref="SynonymMap"/>.</param>
        public SynonymFilter(TokenStream input, SynonymMap synonyms, bool ignoreCase)
            : base(input)
        {
            termAtt    = AddAttribute <ICharTermAttribute>();
            posIncrAtt = AddAttribute <IPositionIncrementAttribute>();
            posLenAtt  = AddAttribute <IPositionLengthAttribute>();
            typeAtt    = AddAttribute <ITypeAttribute>();
            offsetAtt  = AddAttribute <IOffsetAttribute>();

            this.synonyms   = synonyms;
            this.ignoreCase = ignoreCase;
            this.fst        = synonyms.Fst;
            if (fst == null)
            {
                throw new ArgumentException("fst must be non-null");
            }
            this.fstReader = fst.GetBytesReader();

            // Must be 1+ so that when roll buffer is at full
            // lookahead we can distinguish this full buffer from
            // the empty buffer:
            rollBufferSize = 1 + synonyms.MaxHorizontalContext;

            futureInputs  = new PendingInput[rollBufferSize];
            futureOutputs = new PendingOutputs[rollBufferSize];
            for (int pos = 0; pos < rollBufferSize; pos++)
            {
                futureInputs[pos]  = new PendingInput();
                futureOutputs[pos] = new PendingOutputs();
            }

            //System.out.println("FSTFilt maxH=" + synonyms.maxHorizontalContext);

            scratchArc = new FST.Arc <BytesRef>();
        }
Exemple #2
0
        /// <param name="input"> input tokenstream </param>
        /// <param name="synonyms"> synonym map </param>
        /// <param name="ignoreCase"> case-folds input for matching with <seealso cref="Character#toLowerCase(int)"/>.
        ///                   Note, if you set this to true, its your responsibility to lowercase
        ///                   the input entries when you create the <seealso cref="SynonymMap"/> </param>
        public SynonymFilter(TokenStream input, SynonymMap synonyms, bool ignoreCase) : base(input)
        {
            this.synonyms   = synonyms;
            this.ignoreCase = ignoreCase;
            this.fst        = synonyms.fst;
            if (fst == null)
            {
                throw new System.ArgumentException("fst must be non-null");
            }
            this.fstReader = fst.BytesReader;

            // Must be 1+ so that when roll buffer is at full
            // lookahead we can distinguish this full buffer from
            // the empty buffer:
            rollBufferSize = 1 + synonyms.maxHorizontalContext;

            futureInputs  = new PendingInput[rollBufferSize];
            futureOutputs = new PendingOutputs[rollBufferSize];
            for (int pos = 0; pos < rollBufferSize; pos++)
            {
                futureInputs[pos]  = new PendingInput();
                futureOutputs[pos] = new PendingOutputs();
            }

            //System.out.println("FSTFilt maxH=" + synonyms.maxHorizontalContext);

            scratchArc = new FST.Arc <>();
        }
Exemple #3
0
        private void AddPendingOutput()
        {
            var pendingOutput = new PendingOutput();

            pendingOutput.Changed += PendingOutput_Changed;
            PendingOutputs.Add(pendingOutput);
            RecalculateTransaction();
        }
 private void RemovePendingOutputAction(PendingOutput item)
 {
     if (PendingOutputs.Remove(item))
     {
         item.Changed -= PendingOutput_Changed;
         RecalculateCreateTransaction();
     }
 }
 private void RecalculateCreateTransaction()
 {
     if (PendingOutputs.Count > 0 && PendingOutputs.All(x => x.IsValid()))
     {
         EstimatedFee = 0;
         EstimatedRemainingBalance          = 0;
         FinishCreateTransaction.Executable = true;
     }
     else
     {
         FinishCreateTransaction.Executable = false;
     }
 }
Exemple #6
0
        private void RemovePendingOutput(PendingOutput item)
        {
            if (PendingOutputs.Remove(item))
            {
                item.Changed -= PendingOutput_Changed;

                if (PendingOutputs.Count == 0)
                {
                    AddPendingOutput();
                }

                RecalculateTransaction();
            }
        }
Exemple #7
0
        private void SignTransaction(bool publish)
        {
            var outputs = PendingOutputs.Select(po =>
            {
                var script = po.BuildOutputScript().Script;
                return(new Transaction.Output(po.OutputAmount, Transaction.Output.LatestPkScriptVersion, script));
            }).ToArray();
            var shell = ViewModelLocator.ShellViewModel as ShellViewModel;

            if (shell != null)
            {
                Func <string, Task> action = (passphrase) => SignTransactionWithPassphrase(passphrase, outputs, publish);
                shell.VisibleDialogContent = new PassphraseDialogViewModel(shell, "Enter passphrase to sign transaction", "Sign", action);
            }
        }
Exemple #8
0
        private async void AddPendingOutput()
        {
            var pendingOutput = new PendingOutput();

            pendingOutput.Changed += PendingOutput_Changed;
            PendingOutputs.Add(pendingOutput);

            try
            {
                await RecalculatePendingTransaction();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error");
            }
        }
Exemple #9
0
        private void RecalculateTransaction()
        {
            if (PendingOutputs.Count > 0 && PendingOutputs.All(x => x.IsValid))
            {
                // TODO: calculate estimated fee
                EstimatedFee = 0;
                EstimatedRemainingBalance = 0;

                // TODO: only make executable if we know the transaction can be created
                FinishCreateTransaction.Executable = true;
            }
            else
            {
                EstimatedFee = null;
                EstimatedRemainingBalance          = null;
                FinishCreateTransaction.Executable = false;
            }
        }
Exemple #10
0
        private async void RemovePendingOutput(PendingOutput item)
        {
            if (PendingOutputs.Remove(item))
            {
                item.Changed -= PendingOutput_Changed;

                if (PendingOutputs.Count == 0)
                {
                    AddPendingOutput();
                }

                try
                {
                    await RecalculatePendingTransaction();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error");
                }
            }
        }
Exemple #11
0
        private async Task <bool> SignTransactionWithPassphrase(string passphrase, Transaction tx, bool publishImmediately)
        {
            Tuple <Transaction, bool> signingResponse;
            var walletClient = App.Current.Synchronizer.WalletRpcClient;

            try
            {
                signingResponse = await walletClient.SignTransactionAsync(passphrase, tx);
            }
            catch (RpcException ex) when(ex.Status.StatusCode == StatusCode.InvalidArgument)
            {
                MessageBox.Show(ex.Status.Detail);
                return(false);
            }
            var complete = signingResponse.Item2;

            if (!complete)
            {
                MessageBox.Show("Failed to create transaction input signatures.");
                return(false);
            }
            var signedTransaction = signingResponse.Item1;

            if (!publishImmediately)
            {
                MessageBox.Show("Reviewing signed transaction before publishing is not implemented yet.");
                return(false);
            }

            var serializedTransaction = signedTransaction.Serialize();
            var publishedTxHash       = await walletClient.PublishTransactionAsync(signedTransaction.Serialize());

            _pendingTransaction = null;
            _unusedChangeScripts.Remove(SelectedAccount.Account);
            PendingOutputs.Clear();
            AddPendingOutput();
            PublishedTxHash = publishedTxHash.ToString();

            return(true);
        }
Exemple #12
0
 private void FinishCreateTransactionAction()
 {
     try
     {
         if (SignTransaction)
         {
             var outputs = PendingOutputs.Select(po => new Transaction.Output(po.OutputAmount, po.BuildOutputScript().Script)).ToArray();
             var shell   = (ShellViewModel)_parentViewModel;
             Func <string, Task> action = (passphrase) => SignTransactionWithPassphrase(passphrase, outputs, PublishTransaction);
             var dialog = new PassphraseDialogViewModel(shell, "Enter passphrase to sign transaction", "Sign", action);
             PostMessage(new OpenDialogMessage(dialog));
         }
         else
         {
             ShowUnsignedTransaction();
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message);
     }
 }
Exemple #13
0
        public override bool IncrementToken()
        {
            //System.out.println("\nS: incrToken inputSkipCount=" + inputSkipCount + " nextRead=" + nextRead + " nextWrite=" + nextWrite);

            while (true)
            {
                // First play back any buffered future inputs/outputs
                // w/o running parsing again:
                while (inputSkipCount != 0)
                {
                    // At each position, we first output the original
                    // token

                    // TODO: maybe just a PendingState class, holding
                    // both input & outputs?
                    PendingInput   input   = futureInputs[nextRead];
                    PendingOutputs outputs = futureOutputs[nextRead];

                    //System.out.println("  cycle nextRead=" + nextRead + " nextWrite=" + nextWrite + " inputSkipCount="+ inputSkipCount + " input.keepOrig=" + input.keepOrig + " input.consumed=" + input.consumed + " input.state=" + input.state);

                    if (!input.consumed && (input.keepOrig || !input.matched))
                    {
                        if (input.state != null)
                        {
                            // Return a previously saved token (because we
                            // had to lookahead):
                            RestoreState(input.state);
                        }
                        else
                        {
                            // Pass-through case: return token we just pulled
                            // but didn't capture:
                            if (Debugging.AssertsEnabled)
                            {
                                Debugging.Assert(inputSkipCount == 1, "inputSkipCount={0} nextRead={1}", inputSkipCount, nextRead);
                            }
                        }
                        input.Reset();
                        if (outputs.count > 0)
                        {
                            outputs.posIncr = 0;
                        }
                        else
                        {
                            nextRead = RollIncr(nextRead);
                            inputSkipCount--;
                        }
                        //System.out.println("  return token=" + termAtt.toString());
                        return(true);
                    }
                    else if (outputs.upto < outputs.count)
                    {
                        // Still have pending outputs to replay at this
                        // position
                        input.Reset();
                        int      posIncr = outputs.posIncr;
                        CharsRef output  = outputs.PullNext();
                        ClearAttributes();
                        termAtt.CopyBuffer(output.Chars, output.Offset, output.Length);
                        typeAtt.Type = TYPE_SYNONYM;
                        int endOffset = outputs.LastEndOffset;
                        if (endOffset == -1)
                        {
                            endOffset = input.endOffset;
                        }
                        offsetAtt.SetOffset(input.startOffset, endOffset);
                        posIncrAtt.PositionIncrement = posIncr;
                        posLenAtt.PositionLength     = outputs.LastPosLength;
                        if (outputs.count == 0)
                        {
                            // Done with the buffered input and all outputs at
                            // this position
                            nextRead = RollIncr(nextRead);
                            inputSkipCount--;
                        }
                        //System.out.println("  return token=" + termAtt.toString());
                        return(true);
                    }
                    else
                    {
                        // Done with the buffered input and all outputs at
                        // this position
                        input.Reset();
                        nextRead = RollIncr(nextRead);
                        inputSkipCount--;
                    }
                }

                if (finished && nextRead == nextWrite)
                {
                    // End case: if any output syns went beyond end of
                    // input stream, enumerate them now:
                    PendingOutputs outputs = futureOutputs[nextRead];
                    if (outputs.upto < outputs.count)
                    {
                        int      posIncr = outputs.posIncr;
                        CharsRef output  = outputs.PullNext();
                        futureInputs[nextRead].Reset();
                        if (outputs.count == 0)
                        {
                            nextWrite = nextRead = RollIncr(nextRead);
                        }
                        ClearAttributes();
                        // Keep offset from last input token:
                        offsetAtt.SetOffset(lastStartOffset, lastEndOffset);
                        termAtt.CopyBuffer(output.Chars, output.Offset, output.Length);
                        typeAtt.Type = TYPE_SYNONYM;
                        //System.out.println("  set posIncr=" + outputs.posIncr + " outputs=" + outputs);
                        posIncrAtt.PositionIncrement = posIncr;
                        //System.out.println("  return token=" + termAtt.toString());
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }

                // Find new synonym matches:
                Parse();
            }
        }
        /// <param name="input"> input tokenstream </param>
        /// <param name="synonyms"> synonym map </param>
        /// <param name="ignoreCase"> case-folds input for matching with <seealso cref="Character#toLowerCase(int)"/>.
        ///                   Note, if you set this to true, its your responsibility to lowercase
        ///                   the input entries when you create the <seealso cref="SynonymMap"/> </param>
        public SynonymFilter(TokenStream input, SynonymMap synonyms, bool ignoreCase)
            : base(input)
        {
            termAtt = AddAttribute<ICharTermAttribute>();
            posIncrAtt = AddAttribute<IPositionIncrementAttribute>();
            posLenAtt = AddAttribute<IPositionLengthAttribute>();
            typeAtt = AddAttribute<ITypeAttribute>();
            offsetAtt = AddAttribute<IOffsetAttribute>();

            this.synonyms = synonyms;
            this.ignoreCase = ignoreCase;
            this.fst = synonyms.fst;
            if (fst == null)
            {
                throw new System.ArgumentException("fst must be non-null");
            }
            this.fstReader = fst.BytesReader;

            // Must be 1+ so that when roll buffer is at full
            // lookahead we can distinguish this full buffer from
            // the empty buffer:
            rollBufferSize = 1 + synonyms.maxHorizontalContext;

            futureInputs = new PendingInput[rollBufferSize];
            futureOutputs = new PendingOutputs[rollBufferSize];
            for (int pos = 0; pos < rollBufferSize; pos++)
            {
                futureInputs[pos] = new PendingInput();
                futureOutputs[pos] = new PendingOutputs();
            }

            //System.out.println("FSTFilt maxH=" + synonyms.maxHorizontalContext);

            scratchArc = new FST.Arc<BytesRef>();
        }
Exemple #15
0
        private async Task RecalculatePendingTransaction()
        {
            if (PendingOutputs.Count == 0 || PendingOutputs.Any(x => !x.IsValid))
            {
                UnsetPendingTransaction();
                return;
            }

            var walletClient = App.Current.Synchronizer?.WalletRpcClient;

            var outputs = PendingOutputs.Select(po =>
            {
                var amount = po.OutputAmount;
                var script = po.BuildOutputScript().Script;
                return(new Transaction.Output(amount, Transaction.Output.LatestPkScriptVersion, script));
            }).ToArray();

            TransactionAuthor.InputSource inputSource = async targetAmount =>
            {
                var inputs = new Transaction.Input[0];
                // TODO: don't hardcode confs
                var funding = await walletClient.FundTransactionAsync(SelectedAccount.Account, targetAmount, 1);

                if (funding.Item2 >= targetAmount)
                {
                    inputs = funding.Item1.Select(o =>
                                                  Transaction.Input.CreateFromPrefix(new Transaction.OutPoint(o.TransactionHash, o.OutputIndex, o.Tree),
                                                                                     TransactionRules.MaxInputSequence)).ToArray();
                }
                return(Tuple.Create(funding.Item2, inputs));
            };
            TransactionAuthor.ChangeSource changeSource = async() =>
            {
                // Use cached change script if one has already been generated for this account.
                var          selectedAccount = SelectedAccount.Account;
                OutputScript cachedScript;
                if (_unusedChangeScripts.TryGetValue(selectedAccount, out cachedScript))
                {
                    return(cachedScript);
                }

                var changeAddress = await walletClient.NextInternalAddressAsync(SelectedAccount.Account);

                var changeScript = Address.Decode(changeAddress).BuildScript();
                _unusedChangeScripts[selectedAccount] = changeScript;
                return(changeScript);
            };

            try
            {
                var r = await TransactionAuthor.BuildUnsignedTransaction(outputs, TransactionFees.DefaultFeePerKb, inputSource, changeSource);

                Amount totalAccountBalance;
                using (var walletGuard = await App.Current.Synchronizer.WalletMutex.LockAsync())
                {
                    totalAccountBalance = walletGuard.Instance.LookupAccountProperties(SelectedAccount.Account).TotalBalance;
                }
                SetPendingTransaction(totalAccountBalance, r.Item1, r.Item2, outputs.Sum(o => o.Amount));
            }
            catch (Exception ex)
            {
                UnsetPendingTransaction();

                // Insufficient funds will need a nicer error displayed somehow.  For now, hide it
                // while disabling the UI to create the transaction.  All other errors are unexpected.
                if (!(ex is InsufficientFundsException))
                {
                    throw;
                }
            }
        }