コード例 #1
0
ファイル: BufferExtensions.cs プロジェクト: amacal/xenon
 public Task <BufferEntry> Handle(BufferEntry entry)
 {
     return(Task.Run(() =>
     {
         callback(entry);
         return entry;
     }));
 }
コード例 #2
0
ファイル: BufferWindow.cs プロジェクト: amacal/xenon
        public async Task Process(BufferHandler handler)
        {
            int started    = 0;
            int registered = 0;

            Queue <byte[]> memory             = new Queue <byte[]>(blockCount + 1);
            Queue <Task <BufferEntry> > tasks = new Queue <Task <BufferEntry> >(blockCount);

            BufferBlock[] blocks = new BufferBlock[(source.Length - 1) / blockSize + 1];

            void newBlockIfNotExists(int id)
            {
                if (blocks.Length > id && blocks[id] == null)
                {
                    blocks[id] = new BufferBlock
                    {
                        Request = new SemaphoreSlim(0, blocks.Length - id),
                        Ready   = new ManualResetEventSlim(false)
                    };
                }
            }

            void enableBlock(int id, byte[] data, int size)
            {
                blocks[id].Data = data;
                blocks[id].Size = size;
                blocks[id].Ready.Set();
            }

            async Task <bool> readNextBlock(int id)
            {
                byte[] data;

                if (memory.Count == 0)
                {
                    data = new byte[blockSize];
                }
                else
                {
                    data = memory.Dequeue();
                }

                int read = await ReadNext(data).ConfigureAwait(false);

                if (read == 0)
                {
                    return(false);
                }

                for (int i = 0; i <= 1; i++)
                {
                    newBlockIfNotExists(id + i);
                }

                enableBlock(id, data, read);
                return(true);
            }

            while (true)
            {
                if (await readNextBlock(registered++).ConfigureAwait(false) == false)
                {
                    break;
                }

                while (tasks.Count == blockCount)
                {
                    List <Task> wait = new List <Task> {
                        tasks.Peek()
                    };

                    if (blocks.Length > registered)
                    {
                        wait.Add(blocks[registered].Request.WaitAsync());
                    }

                    int index = Task.WaitAny(wait.ToArray());

                    if (index == 0)
                    {
                        BufferEntry entry = tasks.Dequeue().Result;
                        BufferBlock block = blocks[entry.Id];

                        //Console.WriteLine($"awaited block {entry.Id}");

                        blocks[entry.Id] = null;
                        memory.Enqueue(block.Data);

                        block.Request.Dispose();
                        block.Ready.Dispose();
                        block.Data = null;
                    }
                    else
                    {
                        //Console.WriteLine($"awaited request");

                        if (await readNextBlock(registered++).ConfigureAwait(false) == false)
                        {
                            break;
                        }
                    }
                }

                //Console.WriteLine($"started block {started}");
                tasks.Enqueue(handler.Handle(new BufferEntry(started++, blocks)));
            }

            while (started < blocks.Length)
            {
                tasks.Enqueue(handler.Handle(new BufferEntry(started++, blocks)));
            }

            while (tasks.Count > 0)
            {
                await tasks.Dequeue();
            }
        }
コード例 #3
0
ファイル: XenonReader.cs プロジェクト: amacal/xenon
        private int Handle(BufferEntry entry, XenonHierarchy hierarchy, ref int position)
        {
            //Console.WriteLine($"el {position}");

            byte value;
            bool self = false;

            if (entry.GetByteAt(position++) != '<')
            {
                return(-1);
            }

            int starting = position;

            if ((position = XenonScanner.NextElementName(entry, starting)) == -1)
            {
                return(-1);
            }

            // handle element start
            int previousId = 0;
            int owner      = hierarchy.Add(starting, position - starting);

            if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1)
            {
                return(-1);
            }

            if ((value = entry.GetByteAt(position)) == 0)
            {
                return(-1);
            }

            int append(int id)
            {
                if (previousId == 0)
                {
                    hierarchy.SetFirst(owner, id);
                    previousId = id;
                }
                else
                {
                    hierarchy.SetNext(previousId, id);
                    previousId = id;
                }

                return(id);
            }

            int addToHierarchy(int index, int length)
            {
                return(append(hierarchy.Add(index, length)));
            }

            int contentId = append(hierarchy.Add());

            void setContent(int index, int length)
            {
                if (contentId != 0)
                {
                    hierarchy.SetPosition(contentId, index);
                    hierarchy.SetLength(contentId, length);
                    contentId = 0;
                }
                else
                {
                    addToHierarchy(index, length);
                }
            }

            while (value != '/' && value != '>')
            {
                starting = position;
                if ((position = XenonScanner.NextAttributeName(entry, starting)) == -1)
                {
                    return(-1);
                }

                // handle attribute name
                int nameId = addToHierarchy(starting, position - starting);

                if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1)
                {
                    return(-1);
                }

                if (entry.GetByteAt(position++) != '=')
                {
                    return(-1);
                }

                if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1)
                {
                    return(-1);
                }

                if (entry.GetByteAt(position++) != '"')
                {
                    return(-1);
                }

                starting = position;
                if ((position = XenonScanner.NextAttributeValue(entry, starting)) == -1)
                {
                    return(-1);
                }

                // handle attribute value
                int valueId = hierarchy.Add(starting, position - starting);
                hierarchy.SetFirst(nameId, valueId);

                if (entry.GetByteAt(position++) != '"')
                {
                    return(-1);
                }

                if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1)
                {
                    return(-1);
                }

                if ((value = entry.GetByteAt(position)) == 0)
                {
                    return(-1);
                }
            }

            if (value == '/')
            {
                if ((value = entry.GetByteAt(++position)) == 0)
                {
                    return(-1);
                }

                self = true;
            }

            if (value != '>')
            {
                return(-1);
            }

            if (self == false)
            {
                position = position + 1;

                while (true)
                {
                    starting = position;

                    if ((position = XenonScanner.SkipWhiteCharactersForward(entry, position)) == -1)
                    {
                        return(-1);
                    }

                    if (starting == position)
                    {
                        if ((value = entry.GetByteAt(position)) == 0)
                        {
                            return(-1);
                        }

                        if (value == '<')
                        {
                            if ((value = entry.GetByteAt(position + 1)) == 0)
                            {
                                return(-1);
                            }

                            if (value == '/')
                            {
                                starting = position + 2;
                                if ((position = XenonScanner.NextElementName(entry, starting + 2)) == -1)
                                {
                                    return(-1);
                                }

                                // handle element end

                                if ((value = entry.GetByteAt(position)) != '>')
                                {
                                    return(-1);
                                }

                                //Console.WriteLine($"cl {position}");
                                return(owner);
                            }

                            if ((starting = Handle(entry, hierarchy, ref position)) == -1)
                            {
                                return(-1);
                            }

                            append(starting);
                            position++;

                            continue;
                        }
                    }

                    if ((position = XenonScanner.NextContent(entry, position)) == -1)
                    {
                        return(-1);
                    }

                    setContent(starting, position - starting);
                }
            }

            return(owner);
        }
コード例 #4
0
ファイル: XenonNode.cs プロジェクト: amacal/xenon
 protected XenonNode(int id, BufferEntry entry, XenonHierarchy hierarchy)
 {
     this.id        = id;
     this.entry     = entry;
     this.hierarchy = hierarchy;
 }
コード例 #5
0
ファイル: XenonDocument.cs プロジェクト: amacal/xenon
 public XenonDocument(BufferEntry entry, XenonHierarchy hierarchy)
     : base(hierarchy.GetFirst(0), entry, hierarchy)
 {
 }