Ejemplo n.º 1
0
        public ProcessorState(Stream source, Stream target, int bufferSize, int flushThreshold, IEngineConfig config, IReadOnlyList <IOperationProvider> operationProviders)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            if (operationProviders == null)
            {
                throw new ArgumentNullException(nameof(operationProviders));
            }

            if (source.CanSeek)
            {
                try
                {
                    if (source.Length < bufferSize)
                    {
                        bufferSize = (int)source.Length;
                    }
                }
                catch
                {
                    //The stream may not support getting the length property (in NetworkStream for instance, which throw a NotSupportedException), suppress any errors in
                    //  accessing the property and continue with the specified buffer size
                }
            }
            //Buffer has to be at least as large as the largest BOM we could expect
            else if (bufferSize < 4)
            {
                bufferSize = 4;
            }

            _source             = source;
            _target             = target;
            Config              = config;
            _flushThreshold     = flushThreshold;
            CurrentBuffer       = new byte[bufferSize];
            CurrentBufferLength = ReadExactBytes(source, CurrentBuffer, 0, CurrentBuffer.Length);

            Encoding encoding = EncodingUtil.Detect(CurrentBuffer, CurrentBufferLength, out byte[] bom);

            EncodingConfig        = new EncodingConfig(Config, encoding);
            _bomSize              = bom.Length;
            CurrentBufferPosition = _bomSize;
            CurrentSequenceNumber = _bomSize;
            target.Write(bom, 0, _bomSize);

            bool explicitOnConfigurationRequired = false;
            Dictionary <Encoding, Trie <OperationTerminal> > byEncoding = TrieLookup.GetOrAdd(operationProviders, x => new Dictionary <Encoding, Trie <OperationTerminal> >());
            List <string> turnOnByDefault = OperationsToExplicitlySetOnByDefault.GetOrAdd(operationProviders, x =>
            {
                explicitOnConfigurationRequired = true;
                return(new List <string>());
            });

            if (!byEncoding.TryGetValue(encoding, out Trie <OperationTerminal> trie))
            {
                trie = new Trie <OperationTerminal>();

                for (int i = 0; i < operationProviders.Count; ++i)
                {
                    IOperation op = operationProviders[i].GetOperation(encoding, this);

                    if (op != null)
                    {
                        for (int j = 0; j < op.Tokens.Count; ++j)
                        {
                            if (op.Tokens[j] != null)
                            {
                                trie.AddPath(op.Tokens[j].Value, new OperationTerminal(op, j, op.Tokens[j].Length, op.Tokens[j].Start, op.Tokens[j].End));
                            }
                        }

                        if (explicitOnConfigurationRequired && op.IsInitialStateOn && !string.IsNullOrEmpty(op.Id))
                        {
                            turnOnByDefault.Add(op.Id);
                        }
                    }
                }

                byEncoding[encoding] = trie;
            }

            foreach (string state in turnOnByDefault)
            {
                config.Flags[state] = true;
            }

            _trie = new TrieEvaluator <OperationTerminal>(trie);

            if (bufferSize < _trie.MaxLength + 1)
            {
                byte[] tmp = new byte[_trie.MaxLength + 1];
                Buffer.BlockCopy(CurrentBuffer, CurrentBufferPosition, tmp, 0, CurrentBufferLength - CurrentBufferPosition);
                int nRead = ReadExactBytes(_source, tmp, CurrentBufferLength - CurrentBufferPosition, tmp.Length - CurrentBufferLength);
                CurrentBuffer         = tmp;
                CurrentBufferLength  += nRead - _bomSize;
                CurrentBufferPosition = 0;
                CurrentSequenceNumber = 0;
            }
        }
Ejemplo n.º 2
0
        public ProcessorState(Stream source, Stream target, int bufferSize, int flushThreshold, IEngineConfig config, IReadOnlyList <IOperationProvider> operationProviders)
        {
            bool sizedToStream = false;

            //Buffer has to be at least as large as the largest BOM we could expect
            if (bufferSize < 4)
            {
                bufferSize = 4;
            }
            else
            {
                try
                {
                    if (source.Length < bufferSize)
                    {
                        sizedToStream = true;
                        bufferSize    = (int)source.Length;
                    }
                }
                catch
                {
                    //The stream may not support getting the length property (in NetworkStream for instance, which throw a NotSupportedException), suppress any errors in
                    //  accessing the property and continue with the specified buffer size
                }
            }

            _source             = source;
            _target             = target;
            Config              = config;
            _flushThreshold     = flushThreshold;
            CurrentBuffer       = new byte[bufferSize];
            CurrentBufferLength = source.Read(CurrentBuffer, 0, CurrentBuffer.Length);

            byte[]   bom;
            Encoding encoding = EncodingUtil.Detect(CurrentBuffer, CurrentBufferLength, out bom);

            Encoding = encoding;
            CurrentBufferPosition = bom.Length;
            target.Write(bom, 0, bom.Length);

            Dictionary <Encoding, OperationTrie> byEncoding;

            if (!TrieLookup.TryGetValue(operationProviders, out byEncoding))
            {
                TrieLookup[operationProviders] = byEncoding = new Dictionary <Encoding, OperationTrie>();
            }

            if (!byEncoding.TryGetValue(encoding, out _trie))
            {
                List <IOperation> operations = new List <IOperation>(operationProviders.Count);

                for (int i = 0; i < operationProviders.Count; ++i)
                {
                    IOperation op = operationProviders[i].GetOperation(encoding, this);
                    if (op != null)
                    {
                        operations.Add(op);
                    }
                }

                byEncoding[encoding] = _trie = OperationTrie.Create(operations);
            }

            if (bufferSize < _trie.MaxLength && !sizedToStream)
            {
                byte[] tmp = new byte[_trie.MaxLength];
                Buffer.BlockCopy(CurrentBuffer, CurrentBufferPosition, tmp, 0, CurrentBufferLength - CurrentBufferPosition);
                int nRead = _source.Read(tmp, CurrentBufferLength - CurrentBufferPosition, tmp.Length - CurrentBufferLength);
                CurrentBuffer         = tmp;
                CurrentBufferLength  += nRead;
                CurrentBufferPosition = 0;
            }
        }