示例#1
0
        private async Task HandleBlockChainResponse(string message)
        {
            var receiveBlocks = JsonConvert.DeserializeObject <List <SimpleBlock> >(message);

            receiveBlocks.OrderBy(block => block.Index);

            SimpleBlock latestBlockReceived = receiveBlocks.Last();
            SimpleBlock latestBlock         = blockChain.LatestBlock;

            if (latestBlockReceived.Index > latestBlock.Index)
            {
                if (latestBlock.Hash == latestBlockReceived.PreviousHash)
                {
                    logger.LogInformation("We can append the received block to our chain");
                    blockChain.Add(latestBlockReceived);
                    await Broadcast(ResponseLatestMessage());
                }
                else if (receiveBlocks.Count == 1)
                {
                    logger.LogInformation("We have to query the chain from our peer");
                    await Broadcast(QueryAllMessage());
                }
                else
                {
                    blockChain.ReplaceChain(receiveBlocks);
                }
            }
            else
            {
                logger.LogInformation("received blockchain is not longer than received blockchain. Do nothing");
            }
        }
示例#2
0
        public void Chain_should_reorg_if_disconnect()
        {
            var root   = new SimpleBlock("0");
            var chain  = new Chain <SimpleBlock>(root);
            var block1 = new SimpleBlock("1");

            block1.PreviousChainNodeID = root.ID;
            chain.ConnectChainNode(block1);
            var block2 = new SimpleBlock("2");

            block2.PreviousChainNodeID = root.ID;
            var block3 = new SimpleBlock("3");

            block3.PreviousChainNodeID = block2.ID;

            chain.ConnectChainNode(block2);
            chain.ConnectChainNode(block3);

            chain.ReversedActiveChain.Count().Should().Be(3);
            chain.ReversedActiveChain.First().Should().Be(block3);
            chain.ReversedActiveChain.First().Height.Should().Be(2);

            chain.ActiveChainChangeEvent += (object sender, ActiveChainChangeEventArgs e) =>
            {
                e.Old.ID.Should().Be("3");
                e.New.ID.Should().Be("1");
            };

            chain.DisconnectChainNode(block3);
            chain.DisconnectChainNode(block2);
            chain.ReversedActiveChain.Count().Should().Be(2);
            chain.ReversedActiveChain.First().Should().Be(block1);
            chain.ReversedActiveChain.First().Height.Should().Be(1);
        }
示例#3
0
        protected override void VisitSimpleBlock(SimpleBlock block, ExplodedGraphNode node)
        {
            var newProgramState = CleanStateAfterBlock(node.ProgramState, block);

            if (block is ForeachCollectionProducerBlock)
            {
                newProgramState = newProgramState.PopValue();
                EnqueueAllSuccessors(block, newProgramState);
                return;
            }

            var forInitializerBlock = block as ForInitializerBlock;

            if (forInitializerBlock != null)
            {
                newProgramState = newProgramState.PopValues(
                    forInitializerBlock.ForNode.Initializers.Count);

                newProgramState = newProgramState.PushValues(
                    Enumerable
                    .Range(0, forInitializerBlock.ForNode.Incrementors.Count)
                    .Select(i => new SymbolicValue()));

                EnqueueAllSuccessors(forInitializerBlock, newProgramState);
                return;
            }

            base.VisitSimpleBlock(block, node);
        }
示例#4
0
        public override ILineObject Generate(GenerationEnvironment env)
        {
            var ret = new SimpleBlock(new ILineObject[] {
                _ClearLabel.Generate(env),
                _InitCount.Generate(env),
                _SetMotion.Generate(env),
                _AdjustDirection.Generate(env),
            }).Statement();

            if (AutoCancel)
            {
                if (IsInAir)
                {
                    ret = new SimpleBlock(new ILineObject[] {
                        ret,
                        _SitCancel.Generate(env),
                    }).Statement();
                }
                else
                {
                    ret = new SimpleBlock(new ILineObject[] {
                        ret,
                        _FallCancel.Generate(env),
                    }).Statement();
                }
            }
            return(ret);
        }
示例#5
0
        /// <summary>
        /// 5.4.6. Consume a component value
        /// </summary>
        /// <returns></returns>
        private ComponentValue ConsumeComponentValue()
        {
            //Consume the next input token.
            cssToken token = ConsumeNextToken();

            //If the current input token is a <{-token>, <[-token>, or <(-token>, consume a simple block and return it.
            if (token.Type == enumTokenType.curly_bracket_left || token.Type == enumTokenType.square_bracket_left || token.Type == enumTokenType.round_bracket_left)
            {
                SimpleBlock simpleblock = ConsumeSimpleBlock();
                simpleblock.startindex = token.startIndex;

                return(simpleblock);
            }
            //Otherwise, if the current input token is a <function-token>, consume a function and return it.
            else if (token.Type == enumTokenType.function)
            {
                Function func = ConsumeFunction();
                func.startindex = token.startIndex;
                return(func);
            }
            else
            {
                //Otherwise, return the current input token.
                PreservedToken preservedtoken = new PreservedToken();
                preservedtoken.token      = token;
                preservedtoken.startindex = token.startIndex;
                preservedtoken.endindex   = token.endIndex;
                return(preservedtoken);
            }
        }
示例#6
0
        public void SendBlock(IBlock Block)
        {
            switch (Block.Type)
            {
            case BlockType.SimpleBlock:
                SimpleBlock sb = Block as SimpleBlock;
                Send(WorldMap.Key, 0, Block.Position.X, Block.Position.Y, Block.ID);
                break;

            case BlockType.BackgroundBlock:
                BackgroundBlock bb = Block as BackgroundBlock;
                Send(WorldMap.Key, 1, Block.Position.X, Block.Position.Y, Block.ID);
                break;

            case BlockType.RotatableBlock:
                RotatableBlock rb = Block as RotatableBlock;
                Send(WorldMap.Key, 0, Block.Position.X, Block.Position.Y, Block.ID, (int)rb.Rotation);
                break;

            case BlockType.ValuedBlock:
                ValuedBlock vb = Block as ValuedBlock;
                Send(WorldMap.Key, 0, Block.Position.X, Block.Position.Y, Block.ID, vb.Value);
                break;

            case BlockType.PortalBlock:
                PortalBlock pb = Block as PortalBlock;
                Send(WorldMap.Key, 0, Block.Position.X, Block.Position.Y, Block.ID, (int)pb.Rotation, pb.Identificator, pb.Target);
                break;
            }
        }
示例#7
0
        /// <summary>
        ///  5.4.3. Consume a qualified rule
        /// </summary>
        /// <returns></returns>
        private QualifiedRule ConsumeQualifiedRule()
        {
            //To consume a qualified rule:
            //Create a new qualified rule with its prelude initially set to an empty list, and its value initially set to nothing.

            QualifiedRule rule = new QualifiedRule();
            // set operation is performed by CTOR.

            int startindex = -1;

            cssToken token = null;

            while (true)
            {
                //Repeatedly consume the next input token:
                token = ConsumeNextToken();

                if (startindex == -1)
                {
                    startindex = token.startIndex;
                }

                //<EOF-token>
                if (token.Type == enumTokenType.EOF)
                {
                    //This is a parse error. Return nothing.
                    return(null);
                }
                //<{-token>
                else if (token.Type == enumTokenType.curly_bracket_left)
                {
                    //Consume a simple block and assign it to the qualified rule’s block. Return the qualified rule.
                    SimpleBlock block = ConsumeSimpleBlock();

                    block.startindex = token.startIndex;

                    rule.block = block;

                    rule.startindex = startindex;
                    rule.endindex   = block.endindex;

                    return(rule);
                }

                //simple block with an associated token of <{-token>

                //???????TODO: this must be an mistake in the syntax paper..

                //Assign the block to the qualified rule’s block. Return the qualified rule.
                //anything else
                else
                {
                    //Reconsume the current input token. Consume a component value. Append the returned value to the qualified rule’s prelude.

                    ReconsumeToken();
                    ComponentValue value = ConsumeComponentValue();
                    rule.prelude.Add(value);
                }
            }
        }
示例#8
0
        public void Chain_should_not_connect_root_block()
        {
            var    chain  = this.CreateSingleChain();
            var    root   = new SimpleBlock("0");
            Action action = () => chain.ConnectChainNode(root);

            action.Should().Throw <Exception>();
        }
示例#9
0
        protected override void VisitSimpleBlock(SimpleBlock block, ExplodedGraphNode node)
        {
            var newProgramState = node.ProgramState;

            var usingFinalizerBlock = block as UsingEndBlock;

            if (usingFinalizerBlock != null)
            {
                foreach (var explodedGraphCheck in explodedGraphChecks)
                {
                    newProgramState = explodedGraphCheck.PreProcessUsingStatement(node.ProgramPoint, newProgramState);
                }
                newProgramState = CleanStateAfterBlock(newProgramState, block);
                EnqueueAllSuccessors(block, newProgramState);
                return;
            }

            newProgramState = CleanStateAfterBlock(newProgramState, block);

            if (block is ForeachCollectionProducerBlock)
            {
                newProgramState = newProgramState.PopValue();
                EnqueueAllSuccessors(block, newProgramState);
                return;
            }

            var forInitializerBlock = block as ForInitializerBlock;

            if (forInitializerBlock != null)
            {
                newProgramState = newProgramState.PopValues(
                    forInitializerBlock.ForNode.Initializers.Count);

                newProgramState = newProgramState.PushValues(
                    Enumerable
                    .Range(0, forInitializerBlock.ForNode.Incrementors.Count)
                    .Select(i => new SymbolicValue()));

                EnqueueAllSuccessors(forInitializerBlock, newProgramState);
                return;
            }

            var lockBlock = block as LockBlock;

            if (lockBlock != null)
            {
                newProgramState = newProgramState.PopValue();

                newProgramState = newProgramState.RemoveSymbols(IsFieldSymbol);

                EnqueueAllSuccessors(block, newProgramState);
                return;
            }

            base.VisitSimpleBlock(block, node);
        }
示例#10
0
        public void HashTest()
        {
            var block = new SimpleBlock(2, "2", 0, "new block");

            var hashProvider = new SHA256HashProvider();

            hashProvider.Hash(block);

            Assert.Equal(block.Hash, "b77f43514bcd6c8c963b94c0bb66cbd6da8f5606599f9a32581d22368df02a81");
        }
示例#11
0
        /// <summary>
        /// 5.4.7. Consume a simple block
        /// </summary>
        /// <returns></returns>
        private SimpleBlock ConsumeSimpleBlock()
        {
            //The ending token is the mirror variant of the current input token. (E.g. if it was called with <[-token>, the ending token is <]-token>.)

            enumTokenType endTokenType = enumTokenType.curly_bracket_right;

            if (currentToken.Type == enumTokenType.curly_bracket_left)
            {
                endTokenType = enumTokenType.curly_bracket_right;
            }
            else if (currentToken.Type == enumTokenType.round_bracket_left)
            {
                endTokenType = enumTokenType.round_bracket_right;
            }
            else if (currentToken.Type == enumTokenType.square_bracket_left)
            {
                endTokenType = enumTokenType.square_bracket_right;
            }

            //Create a simple block with its associated token set to the current input token and with a value with is initially an empty list.

            SimpleBlock simpleblock = new SimpleBlock();

            simpleblock.token = currentToken;

            cssToken token;

            while (true)
            {
                token = ConsumeNextToken();
                //Repeatedly consume the next input token and process it as follows:

                //<EOF-token>
                //ending token
                if (token.Type == enumTokenType.EOF || token.Type == endTokenType)
                {
                    //Return the block.
                    simpleblock.endindex = token.endIndex;
                    if (token.Type == enumTokenType.EOF)
                    {
                        simpleblock.endindex = simpleblock.endindex - 1;
                    }
                    return(simpleblock);
                }
                //anything else
                else
                {
                    //Reconsume the current input token. Consume a component value and append it to the value of the block.
                    ReconsumeToken();
                    ComponentValue value = ConsumeComponentValue();
                    simpleblock.value.Add(value);
                }
            }
        }
示例#12
0
        public void Chain_should_not_connect_dangling_block()
        {
            var chain         = this.CreateSingleChain();
            var danglingBlock = new SimpleBlock("_0");

            danglingBlock.PreviousChainNodeID = "_1";
            Action action = () => chain.ConnectChainNode(danglingBlock);

            action.Should().ThrowExactly <DanglingChainNodeException>()
            .Where(e => e.Node.ID == "_0");
        }
示例#13
0
        public void Chain_should_not_connect_dup_block()
        {
            var chain = this.CreateSingleChain();
            var block = new SimpleBlock("8");

            block.PreviousChainNodeID = "7";
            Action action = () => chain.ConnectChainNode(block);

            action.Should().Throw <DuplicateChainNodeException>()
            .Where(e => e.Node == block);
        }
示例#14
0
        protected virtual void VisitSimpleBlock(SimpleBlock block, ExplodedGraphNode node)
        {
            var newProgramState = CleanStateAfterBlock(node.ProgramState, block);

            if (block is JumpBlock jumpBlock &&
                IsValueConsumingStatement(jumpBlock.JumpNode))
            {
                newProgramState = newProgramState.PopValue();
            }

            EnqueueAllSuccessors(block, newProgramState);
        }
示例#15
0
        public async void Post([FromBody] string value)
        {
            SimpleBlock lastBlock = _blockChain.LatestBlock;
            SimpleBlock newBlock  = _blockFactory.CreateBlock(lastBlock, value);

            _blockChain.Add(newBlock);
            await _p2PService.Broadcast(_p2PService.ResponseLatestMessage());

            string s = JsonConvert.SerializeObject(newBlock);

            _logger.LogInformation("Block added: " + s);
        }
        protected override void VisitSimpleBlock(SimpleBlock block, ExplodedGraphNode node)
        {
            var newProgramState = node.ProgramState;

            if (block is UsingEndBlock usingFinalizerBlock)
            {
                newProgramState = InvokeChecks(newProgramState, (ps, check) => check.PreProcessUsingStatement(node.ProgramPoint, ps));
                newProgramState = CleanStateAfterBlock(newProgramState, block);
                EnqueueAllSuccessors(block, newProgramState);
                return;
            }

            newProgramState = CleanStateAfterBlock(newProgramState, block);

            if (block is ForeachCollectionProducerBlock)
            {
                newProgramState = newProgramState.PopValue();
                EnqueueAllSuccessors(block, newProgramState);
                return;
            }

            if (block is ForInitializerBlock forInitializerBlock)
            {
                newProgramState = newProgramState.PopValues(
                    forInitializerBlock.ForNode.Initializers.Count);

                newProgramState = newProgramState.PushValues(
                    Enumerable
                    .Range(0, forInitializerBlock.ForNode.Incrementors.Count)
                    .Select(i => new SymbolicValue()));

                EnqueueAllSuccessors(forInitializerBlock, newProgramState);
                return;
            }

            if (block is LockBlock lockBlock)
            {
                newProgramState = newProgramState.PopValue();

                newProgramState = newProgramState.RemoveSymbols(IsFieldSymbol);

                EnqueueAllSuccessors(block, newProgramState);
                return;
            }

            if (block is JumpBlock jumpBlock &&
                jumpBlock.JumpNode.IsKind(SyntaxKind.YieldReturnStatement))
            {
                newProgramState = newProgramState.RemoveSymbols(IsFieldSymbol);
            }

            base.VisitSimpleBlock(block, node);
        }
        public static IItemWriter <T, AnyContent> HtmlContent <T>(
            this IItemWriter <T, AnyContent> target,
            string html)
            where T : AnyContentElement
        {
            var htmlBlock = new SimpleBlock();

            htmlBlock.Value           = html;
            htmlBlock.Helper          = target.Helper;
            htmlBlock.DisableEncoding = true;
            target.Item.AddContent(htmlBlock);
            return(target);
        }
示例#18
0
        public void VerifyTest()
        {
            var blockWithValidHash   = new SimpleBlock(2, "2", 0, "new block", "b77f43514bcd6c8c963b94c0bb66cbd6da8f5606599f9a32581d22368df02a81");
            var blockWithInvalidHash = new SimpleBlock(2, "2", 0, "new block", "b22f43514bcd6c8c963b94c0bb66cbd6da8f5606599f9a32581d22322df02a22");

            var hashProvider = new SHA256HashProvider();

            var validBlockResult   = hashProvider.Verify(blockWithValidHash);
            var invalidBlockResult = hashProvider.Verify(blockWithInvalidHash);

            Assert.True(validBlockResult);
            Assert.False(invalidBlockResult);
        }
示例#19
0
 public Vector3 GetBlockCenter(Vector3 query, int level, IBlock block)
 {
     if (level == block.Level - 1)
     {
         int id = BlockUtility.FindSubArea(block, query);
         return(BlockUtility.ChildPositions(block)[id]);
     }
     else
     {
         int     id        = BlockUtility.FindSubArea(block, query);
         Vector3 subcenter = BlockUtility.ChildPositions(block)[id];
         IBlock  b         = new SimpleBlock(subcenter, block.Level - 1);
         return(GetBlockCenter(query, level, b));
     }
 }
示例#20
0
 // TODO: Find an easier/clearer/faster way to do this
 public IEnumerable <StatementNode> Visit(SimpleBlock block)
 // To extract values from a block, we extract every value from each statement and then return them.
 // However, it's not as straightforward as it sounds, since we have an array of statements, and each
 // statement will return an array of ValueNodes. Means we end up with a IEnumerable<StatementNode>[], which we need to flatten
 // into a IEnumerable<StatementNode> before returning. In code that gives :
 //
 // - Content.Select(ExtractValue) applies the ValueExtractor.ExtractValue method to each StatementNode in the block,
 //   which returns a IEnumerable<StatementNode> for each statement in Content.
 //   => returns a IEnumerable<StatementNode>[]
 //
 // - SelectMany(node => node) transforms the IEnumerable<StatementNode>[] returned by the previous operation into a lat IEnumerable<StatementNode>
 //   => returns a IEnumerable<StatementNode>
 => block.Content
 .Select(Flatten)
 .SelectMany(node => node);
示例#21
0
        private Chain <SimpleBlock> CreateSingleChain()
        {
            var block = new SimpleBlock("0");

            block.Height = 0;
            var chain = new Chain <SimpleBlock>(block);

            for (int i = 1; i != 10; ++i)
            {
                block = new SimpleBlock(i.ToString());
                block.PreviousChainNodeID = (i - 1).ToString();
                chain.ConnectChainNode(block);
            }

            return(chain);
        }
示例#22
0
        public override bool Equals(System.Object Obj)
        {
            if (Obj == null)
            {
                return(false);
            }

            SimpleBlock Block = Obj as SimpleBlock;

            if ((System.Object)Block == null)
            {
                return(false);
            }

            return(this == Block);
        }
示例#23
0
    public static GraphNode ToGraphNode(SimpleBlock block)
    {
        var root = new GraphNode(block.GetHashCode(), "\"block\"");

        root.AddProperty("color", "darkviolet");
        root.AddProperty("tooltip", nameof(SimpleBlock));

        foreach (var statement in block.Content)
        {
            var statementNode = ToGraphNode((dynamic)statement);

            statementNode.AddProperty("tooltip", "statement");

            root.AddNode(statementNode);
        }

        return(root);
    }
示例#24
0
 public bool IsSameAs(IBlock Block)
 {
     if (this.Type == Block.Type)
     {
         SimpleBlock SBlock = Block as SimpleBlock;
         if (SBlock == this)
         {
             return(true);
         }
         else
         {
             return(false);
         }
     }
     else
     {
         return(false);
     }
 }
        public static IItemWriter <T, AnyContent> Content <T>(
            this IItemWriter <T, AnyContent> target,
            object value)
            where T : AnyContentElement
        {
            var itemWriter = value as IItemWriter;

            if (itemWriter != null)
            {
                target.Item.AddContent(itemWriter.Item);
            }
            else
            {
                var block = new SimpleBlock();
                block.Value  = value;
                block.Helper = target.Helper;
                target.Item.AddContent(block);
            }
            return(target);
        }
示例#26
0
        public void IsValidNewBlockTest()
        {
            var hasher  = new SHA256HashProvider();
            var factory = new SimpleBlockFactory(hasher);

            var blockchain = new SimpleBlockChain(hasher, factory);

            var genesisBlock = factory.CreateGenesisBlock();

            var blockWithBadIndex = new SimpleBlock(0, "1", 0, "new block", "0");

            Assert.False(blockchain.IsValidNewBlock(genesisBlock, blockWithBadIndex));

            var blockWithBadHash = new SimpleBlock(1, "1", 0, "new block", "VERY BAD HASH");

            Assert.False(blockchain.IsValidNewBlock(genesisBlock, blockWithBadHash));

            var validBlock = new SimpleBlock(2, "2", 0, "new block");

            hasher.Hash(validBlock);
            Assert.False(blockchain.IsValidNewBlock(genesisBlock, blockWithBadHash));
        }
示例#27
0
        /// <summary>
        /// 5.4.2. Consume an at-rule
        /// </summary>
        /// <returns></returns>
        private AtRule ConsumeAtRule()
        {
            //To consume an at-rule:
            //Create a new at-rule with its name set to the value of the current input token, its prelude initially set to an empty list, and its value initially set to nothing.
            AtRule rule = new AtRule();

            int startindex = -1;

            cssToken token = null;

            while (true)
            {
                //Repeatedly consume the next input token:
                token = ConsumeNextToken();
                if (startindex == -1)
                {
                    startindex = token.startIndex;
                }

                //<semicolon-token>
                //<EOF-token>
                if (token.Type == enumTokenType.semicolon || token.Type == enumTokenType.EOF)
                {
                    //Return the at-rule.
                    rule.startindex = startindex;
                    rule.endindex   = token.endIndex;

                    if (token.Type == enumTokenType.EOF)
                    {
                        rule.endindex = rule.endindex - 1;
                    }
                    return(rule);
                }
                //<{-token>
                else if (token.Type == enumTokenType.curly_bracket_left)
                {
                    //Consume a simple block and assign it to the at-rule’s block. Return the at-rule.
                    SimpleBlock simpleblock = ConsumeSimpleBlock();
                    simpleblock.startindex = token.startIndex;
                    rule.block             = simpleblock;

                    rule.startindex = startindex;
                    rule.endindex   = simpleblock.endindex;

                    return(rule);
                }
                //simple block with an associated token of <{-token>
                //Assign the block to the at-rule’s block. Return the at-rule.

                ///TODO: ???? check what does this means???

                //anything else
                else
                {
                    //Reconsume the current input token. Consume a component value. Append the returned value to the at-rule’s prelude.
                    ReconsumeToken();
                    ComponentValue value = ConsumeComponentValue();
                    rule.prelude.Add(value);
                }
            }
        }
示例#28
0
        /// <summary>
        /// The @import at-rule is a simple statement. After its name, it takes a single string or url() function to indicate the stylesheet that it should import.
        /// </summary>
        /// <param name="rule"></param>
        /// <returns></returns>
        private static CSSRule ParseImportRule(AtRule rule, string baseurl, bool downloadImportRule, ref string OriginalCss)
        {
            /// the import starts with import atkeyword token.
            /// it should have been checked before calling this method, can be ignored.
            PreservedToken token = rule.prelude[0] as PreservedToken;

            int count = rule.prelude.Count;

            CSSImportRule importrule = new CSSImportRule();
            string        media      = string.Empty;

            int startindex = -1;
            int endindex   = -1;

            for (int i = 0; i < count; i++)
            {
                if (startindex < 0)
                {
                    startindex = rule.prelude[i].startindex;
                }

                if (rule.prelude[i].endindex > endindex)
                {
                    endindex = rule.prelude[i].endindex;
                }

                if (rule.prelude[i].Type == CompoenentValueType.preservedToken)
                {
                    PreservedToken preservedToken = rule.prelude[i] as PreservedToken;

                    /// ignore the whitespace and at-keyword token.
                    if (preservedToken.token.Type == enumTokenType.at_keyword || (string.IsNullOrEmpty(importrule.href) && preservedToken.token.Type == enumTokenType.whitespace))
                    {
                        continue;
                    }

                    if (string.IsNullOrEmpty(importrule.href))
                    {
                        if (preservedToken.token.Type == enumTokenType.String)
                        {
                            string_token stringtoken = preservedToken.token as string_token;
                            string       url         = string.Empty;

                            if (string.IsNullOrEmpty(baseurl))
                            {
                                url = stringtoken.value;
                            }
                            else
                            {
                                url = PathHelper.combine(baseurl, stringtoken.value);
                            }

                            importrule.href = url;
                            if (downloadImportRule && !string.IsNullOrEmpty(url))
                            {
                                importrule.stylesheet = CSSParser.ParseCSSStyleSheetFromUrl(url);
                            }
                        }
                        else if (preservedToken.token.Type == enumTokenType.url)
                        {
                            url_token urltoken = preservedToken.token as url_token;

                            string url = string.Empty;
                            if (string.IsNullOrEmpty(baseurl))
                            {
                                url = urltoken.value;
                            }
                            else
                            {
                                url = PathHelper.combine(baseurl, urltoken.value);
                            }

                            importrule.href = url;
                            if (downloadImportRule && !string.IsNullOrEmpty(url))
                            {
                                importrule.stylesheet = CSSParser.ParseCSSStyleSheetFromUrl(url);
                            }
                        }
                        else
                        {
                            // must start with a string or url token as the next.
                            string error = "this is an error";
                        }
                    }
                    else
                    {
                        // the import rule has href already, next is the media rules.
                        if (preservedToken.token.Type == enumTokenType.comma || preservedToken.token.Type == enumTokenType.semicolon)
                        {
                            if (!string.IsNullOrEmpty(media))
                            {
                                importrule.media.appendMedium(media.Trim());
                                media = string.Empty;
                            }
                        }
                        else
                        {
                            // can be delim token.
                            if (string.IsNullOrEmpty(media) && preservedToken.token.Type == enumTokenType.whitespace)
                            {
                                // the start of whitespace will be ignored.
                            }
                            else
                            {
                                media += preservedToken.token.GetString(ref OriginalCss);
                            }
                        }
                    }
                }

                else if (rule.prelude[i].Type == CompoenentValueType.function)
                {
                    Function urlfunction = rule.prelude[i] as Function;
                    string   href        = string.Empty;
                    if (urlfunction.name == "url")
                    {
                        foreach (var item in urlfunction.value)
                        {
                            if (item.Type == CompoenentValueType.preservedToken)
                            {
                                PreservedToken pretoken = item as PreservedToken;
                                if (pretoken.token.Type == enumTokenType.String)
                                {
                                    string_token stringtoken = pretoken.token as string_token;
                                    href += stringtoken.value;
                                }
                            }
                        }
                    }

                    if (!string.IsNullOrEmpty(href))
                    {
                        importrule.href = href;
                    }
                }

                else if (rule.prelude[i].Type == CompoenentValueType.simpleBlock)
                {
                    // simple block is the block like  screen and (min-width:300);
                    SimpleBlock block = rule.prelude[i] as SimpleBlock;

                    string mediarule = string.Empty;
                    foreach (var item in block.value)
                    {
                        if (item.Type == CompoenentValueType.preservedToken)
                        {
                            PreservedToken pretoken = item as PreservedToken;
                            mediarule += pretoken.token.GetString(ref OriginalCss);

                            if (token.token.endIndex > endindex)
                            {
                                endindex = token.token.endIndex;
                            }
                        }
                    }

                    if (block.token.Type == enumTokenType.round_bracket_left || block.token.Type == enumTokenType.round_bracket_right)
                    {
                        mediarule = "(" + mediarule + ")";
                    }
                    else if (block.token.Type == enumTokenType.square_bracket_left || block.token.Type == enumTokenType.square_bracket_right)
                    {
                        mediarule = "[" + mediarule + "]";
                    }
                    else if (block.token.Type == enumTokenType.curly_bracket_left || block.token.Type == enumTokenType.curly_bracket_right)
                    {
                        mediarule = "{" + mediarule + "}";
                    }

                    media += mediarule;
                }
            }

            if (!string.IsNullOrEmpty(media))
            {
                importrule.media.appendMedium(media.Trim());
                media = string.Empty;
            }

            importrule.StartIndex = startindex;
            if (rule.endindex > endindex)
            {
                endindex = rule.endindex;
            }
            importrule.EndIndex = endindex;

            int endselectorindex = rule.prelude[0].endindex + 1;

            ///import rule does not have one extra char like {
            // importrule.EndSelectorIndex = endselectorindex - importrule.StartIndex + 1;
            importrule.EndSelectorIndex = endselectorindex - importrule.StartIndex;

            return(importrule);
        }
示例#29
0
        /// <summary>
        /// consume a list of cssrule from simpleblock,
        /// Recursive.
        /// </summary>
        /// <param name="block"></param>
        /// <returns></returns>
        private static CSSRuleList ParseMediaRuleList(SimpleBlock block, ref int endindex, CSSMediaRule parentmediarule, ref string OriginalCss)
        {
            int         count    = block.value.Count;
            CSSRuleList rulelist = new CSSRuleList();

            MediaRuleParseState state = MediaRuleParseState.init;

            CSSStyleRule stylerule = null;
            CSSMediaRule mediarule = null;

            string media = string.Empty;
            string wholeconditiontext = string.Empty;

            int startindex = -1;

            for (int i = 0; i < count; i++)
            {
                if (block.value[i].endindex > endindex)
                {
                    endindex = block.value[i].endindex;
                }

                if (startindex < 0)
                {
                    startindex = block.value[i].startindex;
                }

                switch (state)
                {
                case MediaRuleParseState.init:
                {
                    if (block.value[i].Type == CompoenentValueType.preservedToken)
                    {
                        PreservedToken pretoken = block.value[i] as PreservedToken;

                        if (pretoken.token.Type == enumTokenType.whitespace)
                        {
                            // ignored whitespace at the beginning.
                        }
                        else if (pretoken.token.Type == enumTokenType.at_keyword)
                        {
                            // at keyword token, only handle media now.
                            // others to be added.
                            at_keyword_token token = pretoken.token as at_keyword_token;
                            if (token.value.ToLower() == "media")
                            {
                                state = MediaRuleParseState.mediarule;
                                i     = i - 1;     // reconsume to have correct startindex.
                            }
                            else
                            {
                                // other at rules.
                                state = MediaRuleParseState.OtherAtRule;
                                i     = i - 1;
                            }
                        }

                        /// else treat as regular style rule.
                        else
                        {
                            state = MediaRuleParseState.stylerule;
                            i     = i - 1;     // reconsume.
                        }
                    }
                    break;
                }

                case MediaRuleParseState.stylerule:
                {
                    if (stylerule == null)
                    {
                        stylerule  = new CSSStyleRule();
                        startindex = block.value[i].startindex;
                    }

                    if (block.value[i].Type == CompoenentValueType.preservedToken)
                    {
                        PreservedToken pretoken = block.value[i] as PreservedToken;
                        // not a defined way to parse the selector, assembly them back and give it to selector module.
                        // in the new way of getting selectorText, we have not need to assign it any more.
                        //stylerule.selectorText += pretoken.token.getString();
                    }
                    else if (block.value[i].Type == CompoenentValueType.simpleBlock)
                    {
                        int endselectorindex = block.value[i].startindex;

                        stylerule.style = ParseDeclarations(block.value[i] as SimpleBlock, ref endindex, ref OriginalCss);

                        stylerule.StartIndex = startindex;
                        stylerule.EndIndex   = endindex;

                        stylerule.EndSelectorIndex = endselectorindex - stylerule.StartIndex;

                        stylerule.parentRule = parentmediarule;

                        stylerule.parentStyleSheet = parentmediarule.parentStyleSheet;

                        rulelist.appendRule(stylerule);
                        stylerule = null;

                        state      = MediaRuleParseState.init;
                        startindex = -1;
                    }


                    break;
                }

                case MediaRuleParseState.mediarule:
                {
                    if (mediarule == null)
                    {
                        mediarule          = new CSSMediaRule();
                        media              = string.Empty;
                        wholeconditiontext = string.Empty;
                        startindex         = block.value[i].startindex;

                        mediarule.parentStyleSheet = parentmediarule.parentStyleSheet;
                        mediarule.parentRule       = parentmediarule;
                    }

                    if (block.value[i].Type == CompoenentValueType.preservedToken)
                    {
                        PreservedToken pretoken = block.value[i] as PreservedToken;

                        if (pretoken.token.Type == enumTokenType.comma)
                        {
                            if (!string.IsNullOrEmpty(media))
                            {
                                mediarule.media.appendMedium(media.Trim());
                                media = string.Empty;
                            }
                            wholeconditiontext += ",";
                        }
                        else
                        {
                            // can be delim token.
                            if (string.IsNullOrEmpty(media) && pretoken.token.Type == enumTokenType.whitespace)
                            {
                                // the start of whitespace will be ignored.
                            }
                            else
                            {
                                media += pretoken.token.GetString(ref OriginalCss);
                                wholeconditiontext += pretoken.token.GetString(ref OriginalCss);
                            }
                        }
                    }
                    else if (block.value[i].Type == CompoenentValueType.simpleBlock)
                    {
                        CSSRuleList mediarulelist = ParseMediaRuleList(block.value[i] as SimpleBlock, ref endindex, mediarule, ref OriginalCss);

                        mediarule.cssRules = mediarulelist;

                        if (!string.IsNullOrEmpty(media))
                        {
                            mediarule.media.appendMedium(media.Trim());
                            wholeconditiontext += media;
                        }

                        mediarule.conditionText = wholeconditiontext;
                        mediarule.selectorText  = wholeconditiontext;        /// NON-W3C.

                        mediarule.StartIndex = startindex;
                        mediarule.EndIndex   = endindex;

                        rulelist.appendRule(mediarule);

                        state              = 0;
                        mediarule          = null;
                        media              = string.Empty;
                        wholeconditiontext = string.Empty;
                        startindex         = -1;
                    }

                    break;
                }

                case MediaRuleParseState.OtherAtRule:
                {
                    //if (mediarule == null)
                    //{
                    //    mediarule = new CSSMediaRule();
                    //    media = string.Empty;
                    //    wholeconditiontext = string.Empty;
                    //    startindex = block.value[i].startindex;

                    //    mediarule.parentStyleSheet = parentmediarule.parentStyleSheet;
                    //    mediarule.parentRule = parentmediarule;
                    //}

                    if (block.value[i].Type == CompoenentValueType.preservedToken)
                    {
                        //PreservedToken pretoken = block.value[i] as PreservedToken;

                        //if (pretoken.token.Type == enumTokenType.comma)
                        //{
                        //    if (!string.IsNullOrEmpty(media))
                        //    {
                        //        mediarule.media.appendMedium(media.Trim());
                        //        media = string.Empty;
                        //    }
                        //    wholeconditiontext += ",";
                        //}
                        //else
                        //{
                        //    // can be delim token.
                        //    if (string.IsNullOrEmpty(media) && pretoken.token.Type == enumTokenType.whitespace)
                        //    {
                        //        // the start of whitespace will be ignored.
                        //    }
                        //    else
                        //    {
                        //        media += pretoken.token.GetString(ref OriginalCss);
                        //        wholeconditiontext += pretoken.token.GetString(ref OriginalCss);
                        //    }
                        //}
                    }
                    else if (block.value[i].Type == CompoenentValueType.simpleBlock)
                    {
                        // not implemented now.
                        //CSSRuleList mediarulelist = ParseMediaRuleList(block.value[i] as SimpleBlock, ref endindex, mediarule, ref OriginalCss);

                        //mediarule.cssRules = mediarulelist;

                        //if (!string.IsNullOrEmpty(media))
                        //{
                        //    mediarule.media.appendMedium(media.Trim());
                        //    wholeconditiontext += media;
                        //}

                        //mediarule.conditionText = wholeconditiontext;
                        //mediarule.selectorText = wholeconditiontext; /// NON-W3C.

                        //mediarule.StartIndex = startindex;
                        //mediarule.EndIndex = endindex;

                        //rulelist.appendRule(mediarule);

                        state      = MediaRuleParseState.init;
                        startindex = -1;
                    }

                    break;
                }

                default:
                    break;
                }
            }


            if (stylerule != null)
            {
                if (stylerule.EndIndex > stylerule.StartIndex)
                {
                    rulelist.appendRule(stylerule);
                }
                stylerule = null;
            }

            if (mediarule != null)
            {
                rulelist.appendRule(mediarule);
                mediarule = null;
            }
            return(rulelist);
        }
示例#30
0
        /// <summary>
        /// Consume a list of declaration from a simple block.
        /// </summary>
        /// <param name="block"></param>
        /// <returns></returns>
        private static CSSStyleDeclaration ParseDeclarations(SimpleBlock block, ref int endindex, ref string CssText)
        {
            CSSStyleDeclaration declarations = new CSSStyleDeclaration();
            string csstext = string.Empty;

            CSSDeclaration onedeclaration = null;
            bool           colonfound     = false; // check value before or after colon.

            int valuecount = block.value.Count;

            for (int i = 0; i < valuecount; i++)
            {
                ComponentValue item = block.value[i];

                if (item.endindex > endindex)
                {
                    endindex = item.endindex;
                }

                if (item.Type == CompoenentValueType.preservedToken)
                {
                    PreservedToken token = item as PreservedToken;

                    if (token.token.Type == enumTokenType.ident)
                    {
                        // the first ident is the start of one declaration.
                        if (onedeclaration == null)
                        {
                            onedeclaration = new CSSDeclaration();
                            ident_token identtoken = token.token as ident_token;
                            onedeclaration.propertyname = identtoken.value;
                            colonfound = false;
                        }
                        else
                        {
                            onedeclaration.value += token.token.GetString(ref CssText);
                        }
                    }
                    else if (token.token.Type == enumTokenType.semicolon || token.token.Type == enumTokenType.EOF)
                    {
                        // this is the end of one declaration.
                        declarations.item.Add(onedeclaration);
                        onedeclaration = null;
                        colonfound     = false;
                    }

                    else if (colonfound == false)
                    {
                        if (token.token.Type == enumTokenType.colon)
                        {
                            colonfound = true;
                        }
                        else if (token.token.Type == enumTokenType.whitespace)
                        {
                            // white space do nothing.
                        }
                        else
                        {
                            // the next one must be white space or colon, otherwise, error.
                            //TODO: onError.
                        }
                    }

                    else if (token.token.Type == enumTokenType.delim && ((delim_token)token.token).value == '!')
                    {
                        if ((i + 1) < valuecount)
                        {
                            if (block.value[i + 1].Type == CompoenentValueType.preservedToken)
                            {
                                PreservedToken important = block.value[i + 1] as PreservedToken;
                                if (important.token.Type == enumTokenType.ident)
                                {
                                    ident_token importantident = important.token as ident_token;
                                    if (importantident.value.ToLower() == "important" && onedeclaration != null)
                                    {
                                        onedeclaration.important = true;
                                    }
                                }
                            }

                            // has to consume the important now, because value has been processed.
                            i = i + 1;
                        }
                    }
                    else
                    {
                        /// append the value to declaration value.
                        if (onedeclaration != null)
                        {
                            onedeclaration.value += token.token.GetString(ref CssText);
                        }
                    }
                }
                else if (item.Type == CompoenentValueType.function)
                {
                    Function func = item as Function;

                    if (onedeclaration == null)
                    {
                        onedeclaration = new CSSDeclaration();
                        onedeclaration.propertyname = func.getString(ref CssText);
                        colonfound = false;
                    }
                    else
                    {
                        if (colonfound)
                        {
                            onedeclaration.value += func.getString(ref CssText);
                        }
                        else
                        {
                            onedeclaration.propertyname += func.getString(ref CssText);
                        }
                    }
                }
            }



            if (onedeclaration != null && !string.IsNullOrEmpty(onedeclaration.propertyname))
            {
                declarations.item.Add(onedeclaration);
                onedeclaration = null;
                colonfound     = false;
            }


            if (block.endindex > endindex)
            {
                endindex = block.endindex;
            }

            return(declarations);
        }