Ejemplo n.º 1
0
        /// <summary>
        /// Get a supported class from the connection. Resource is unlocked after the action called is ended.
        /// </summary>
        public static void Get <T, C>(string path, out Teple <LockShared, T> resource) where C : Connection <C>, IGetValue <T>, new()
        {
            _lock.Take();

            // get the type of connection
            Type sourceType = typeof(C);
            ArrayRig <IConnection> source;

            // check if there are currently any types of connections like this
            if (!_sources.TryGetValue(sourceType, out source))
            {
                // create the dictionary
                source = new ArrayRig <IConnection>();
                _sources[sourceType] = source;
            }

            // try get the connection
            C connection = source.GetSingle(c => c.Path == path) as C;

            // if the connection doesn't exist
            if (connection == null)
            {
                // create a new connection
                connection      = new C();
                connection.Path = path;
                // add to the source
                source.Add(connection);
            }

            // unlock the sources lock
            _lock.Release();

            // get the resource
            connection.Get(out resource);
        }
Ejemplo n.º 2
0
 public void Get(out Teple <LockShared, FileStream> fileStream)
 {
     if (!State.Is(ConnectionState.Open))
     {
         Open();
     }
     _locker.Take();
     fileStream = new Teple <LockShared, FileStream>(_locker, _fileStream);
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Get the current stream writer for this connection. Makes the request if not already made.
 /// </summary>
 public void Get(out Teple <LockShared, ByteBuffer> stream)
 {
     if (!State.Is(ConnectionState.Open))
     {
         Open();
     }
     _locker.Take();
     stream = new Teple <LockShared, ByteBuffer>(_locker, ByteStream);
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Pop an item from the cache. If the item has a single entry within the cache
        /// the size of the cache will be reduced.
        /// </summary>
        public void Pop()
        {
            _lock.Take();
            // move to the next queued item
            if (!_queue.Next())
            {
                _lock.Release();
                return;
            }

            // get the lookup record
            Teple <long, long, TValue> current = _lookup[_queue.Current];

            while (current.ArgA == 0)
            {
                if (!_queue.Next())
                {
                    _lock.Release();
                    return;
                }
                current = _lookup[_queue.Current];
            }

            _peeked = false;

            // are there duplicate entries for the current item
            if (current.ArgA == 1)
            {
                // no, decrement the size of the current item
                _size -= current.ArgB;
                // remove the lookup entry
                _lookup.Remove(_queue.Current);

                _lock.Release();

                // is the callback set?
                if (_onRemoved.Action != null)
                {
                    // yes, run it
                    _onRemoved.Run(current.ArgC);
                }
            }
            else
            {
                // yes, decrement the number of cache entries
                --current.ArgA;

                _lock.Release();
            }
        }
Ejemplo n.º 5
0
        public void UpdateAsset(string name)
        {
            _assetLock.Take();
            long milliseconds = _time.Milliseconds;

            if (Assets.ContainsKey(name))
            {
                Teple <long, long> stats = Assets[name];
                ++stats.ArgA;
                stats.ArgB      += milliseconds - AssetTicks[name];
                AssetTicks[name] = milliseconds;
            }
            else
            {
                Assets.Add(name, new Teple <long, long>(1, 0));
                AssetTicks.Add(name, milliseconds);
            }
            ++AssetCount;
            _assetLock.Release();
        }
Ejemplo n.º 6
0
        //-------------------------------------------//

        /// <summary>
        /// Run loop of the text template.
        /// </summary>
        protected void Run(string str, int index, IAction <StringBuilder> onRan,
                           TreeSearch <char, Teple <string, ActionRoll <StringBuilder, string, int> > > .DynamicSearch search)
        {
            int end = index + Global.BufferSizeLocal;

            if (end > str.Length)
            {
                end = str.Length;
            }

            Teple <string, ActionRoll <StringBuilder, string, int> > result = null;

            // iterate the string
            for (int i = index; i < end; ++i)
            {
                // has a replacement string been found?
                if (search.Next(str[i]))
                {
                    // yes, set the current result
                    result = search.Values.Pop();
                }
                else
                {
                    // no, has a replacement been found?
                    if (result != null)
                    {
                        // yes, append the replacement
                        if (result.ArgA != null)
                        {
                            onRan.ArgA.Append(result.ArgA);
                        }
                        if (result.ArgB != null)
                        {
                            result.ArgB.Run(onRan.ArgA, str, str.Length - 1);
                        }
                        result = null;
                    }

                    // append the non-matching character
                    onRan.ArgA.Append(str[i]);
                }
            }

            // was the last character to be replaced?
            if (result != null)
            {
                // yes, append the replacement
                if (result.ArgA != null)
                {
                    onRan.ArgA.Append(result.ArgA);
                }
                if (result.ArgB != null)
                {
                    result.ArgB.Run(onRan.ArgA, str, str.Length - 1);
                }
            }

            if (index < end)
            {
                ManagerUpdate.Control.AddSingle(Run, str, index, onRan, search);
            }
            else
            {
                onRan.Run();
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Send data to the remote host
        /// </summary>
        public void Send(byte[] buffer, int index, int count, IAction onSent = null)
        {
            // skip 0 bytes
            if (count == 0)
            {
                return;
            }

            if (onSent != null)
            {
                _callbackLock.Take();

                // enqueue bytes in the buffer
                var length = _sendBuffer.TakeItem().EnqueueGetCount(buffer, index, count);
                _sendBuffer.Release();
                if (_currentCallbackAction == null)
                {
                    _currentCallbackAction = onSent;
                    _currentCallbackIndex  = _lastCallbackIndex = length;
                }
                else
                {
                    _lastCallbackIndex = length - _lastCallbackIndex;
                    _callbacks.Enqueue(Teple.New(_lastCallbackIndex, onSent));
                }

                _callbackLock.Release();
            }
            else
            {
                // enqueue bytes from the stream
                _sendBuffer.TakeItem().Enqueue(buffer, index, count);
                _sendBuffer.Release();
            }

            // is the socket currently sending?
            if (_sendLock.TryTake)
            {
                // ensure not disposing
                if (_disposing)
                {
                    _sendLock.Release();
                    return;
                }

                try {
                    StartSend();
                } catch (SocketException ex) {
                    _sendLock.Release();
                    if (ex.SocketErrorCode == SocketError.ConnectionReset)
                    {
                        return;
                    }
                    ProcessError(ex);
                } catch (Exception ex) {
                    _sendLock.Release();
                    // handle the error outside the lock
                    ProcessError(ex);
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Load this elements children. This is the final function of all built elements.
        /// </summary>
        protected async void Build(Ticker ticker, Element element, Elements elements)
        {
            if (_singleChildren != null)
            {
                // initiaize the parent cache used to keep track of the desired indices of added elements.
                // Once an element is added to the cache an index is used to insert each new child as they
                // are built
                Dictionary <string, Teple <Element, int> > parentCache = new Dictionary <string, Teple <Element, int> >();

                // iterate the children to action
                foreach (var child in _singleChildren)
                {
                    ticker.Push();
                    switch (child.Value.Action)
                    {
                    case BuilderAction.Replace:

                        ManagerUpdate.Control.AddSingle(child.Value.BuildReplaceChild, ticker, elements, element, child.Key);

                        break;

                    case BuilderAction.Add:

                        if (parentCache == null)
                        {
                            parentCache = new Dictionary <string, Teple <Element, int> >();
                        }
                        ;
                        Teple <Element, int> next;
                        if (parentCache.TryGetValue(child.Key, out next))
                        {
                            ++next.ArgB;
                        }
                        else
                        {
                            next      = new Teple <Element, int>(element.FindChild(child.Key), 0);
                            next.ArgB = next.ArgA.ChildCount;
                            parentCache.Add(child.Key, next);
                        }
                        ManagerUpdate.Control.AddSingle(child.Value.BuildAddedChild, ticker, elements, next.ArgA, next.ArgB);

                        break;

                    default:

                        var childElement = element.FindChild(child.Key);
                        if (childElement == null)
                        {
                            Log.Error("Child element '" + child.Key + "' not found in '" + element + "'.");
                        }
                        ManagerUpdate.Control.AddSingle(child.Value.Build, ticker, childElement, elements);

                        break;
                    }
                }
            }

            if (_multiChildren != null)
            {
                // initiaize the parent cache used to keep track of the desired indices of added elements.
                // Once an element is added to the cache an index is used to insert each new child as they
                // are built
                Dictionary <string, Teple <Element, int> > parentCache = new Dictionary <string, Teple <Element, int> >();

                // iterate the children to action
                foreach (var collection in _multiChildren)
                {
                    foreach (var child in collection.Value)
                    {
                        ticker.Push();

                        switch (child.Action)
                        {
                        case BuilderAction.Replace:

                            // add an action to build the replacement child
                            ManagerUpdate.Control.AddSingle(child.BuildReplaceChild, ticker, elements, element, collection.Key);

                            break;

                        case BuilderAction.Add:

                            // create a cache of references
                            if (parentCache == null)
                            {
                                parentCache = new Dictionary <string, Teple <Element, int> >();
                            }
                            ;
                            Teple <Element, int> next;
                            if (parentCache.TryGetValue(collection.Key, out next))
                            {
                                ++next.ArgB;
                            }
                            else
                            {
                                next      = new Teple <Element, int>(element.FindChild(collection.Key), 0);
                                next.ArgB = next.ArgA.ChildCount;
                                parentCache.Add(collection.Key, next);
                            }
                            ManagerUpdate.Control.AddSingle(child.BuildAddedChild, ticker, elements, next.ArgA, next.ArgB);

                            break;

                        case BuilderAction.Remove:

                            var removeElement = element.FindChild(collection.Key);
                            if (removeElement == null)
                            {
                                Log.Error("Child element '" + collection.Key + "' was not found in '" + element + "' to be removed.");
                            }
                            else
                            {
                                removeElement.Remove();
                            }

                            break;

                        default:

                            var childElement = element.FindChild(collection.Key);
                            if (childElement == null)
                            {
                                Log.Error("Child element '" + collection.Key + "' not found in '" + element + "' to be altered.");
                            }
                            else
                            {
                                ManagerUpdate.Control.AddSingle(child.Build, ticker, childElement, elements);
                            }

                            break;
                        }
                    }
                }
            }

            // have any attributes been specified?
            if (Attributes != null)
            {
                // yes, iterate the attributes
                foreach (var attribute in Attributes)
                {
                    if (attribute.Value.ArgB == null)
                    {
                        element.SetAttribute(attribute.Key, attribute.Value.ArgA);
                    }
                    else if (attribute.Value.ArgA == null)
                    {
                        element.RemoveAttribute(attribute.Key);
                    }
                    else
                    {
                        element.SetAttribute(attribute.Key, await attribute.Value.ArgB.RunAsync() ?? attribute.Value.ArgA);
                    }
                }
            }

            // has the content been specified?
            if (Content != null)
            {
                // yes, iterate and add the content
                foreach (var content in Content)
                {
                    element.Content.Add(content.ArgB == null ? content.ArgA : await content.ArgB.RunAsync() ?? content.ArgA);
                }
            }

            ticker.Pull();
        }
Ejemplo n.º 9
0
        //----------------------------------//

        /// <summary>
        /// Refresh the headers from the header index.
        /// </summary>
        protected unsafe void RefreshHeaders()
        {
            // set the builder index
            _builder.Length = _refreshBuilderIndex;

            if (_refreshBuilderIndex == 0)
            {
                _builder.Append(_version);
                _builder.Append(Chars.Space);
                _builder.Append(_statusCode);
                _builder.Append(Chars.Space);
                _builder.AppendLine(_statusDescription);
            }

            if (_refreshDefinedHeaders)
            {
                _refreshDefinedHeaders = false;

                // iterate the headers from the index to be refreshed
                for (int i = _refreshDefinedHeaderIndex; i < _definedHeaders.Count; ++i)
                {
                    // persist the header
                    Teple <HttpResponseHeader, Teple <string, int> > header = _definedHeaders[i];

                    header.ArgB.ArgB = _builder.Length;

                    string value;
                    if (_definedSingles.TryGetValue(header.ArgA, out value))
                    {
                        // yes, check refresh
                        if (!_refreshDefinedHeaders)
                        {
                            // yes, set the header index
                            _refreshDefinedHeaderIndex = i;
                            _refreshBuilderIndex       = header.ArgB.ArgB;

                            // flip the refresh flag
                            _refreshDefinedHeaders = true;
                        }

                        // remove the single-shot header from the collection
                        _definedSingles.Remove(header.ArgA);

                        if (header.ArgB.ArgA == null)
                        {
                            // remove the header from the collection
                            _definedHeaders.RemoveQuick(i);
                            --i;
                        }

                        // append the header key and value
                        _builder.Append(header.ArgA.GetString());
                        _builder.Append(Chars.Colon);
                        _builder.Append(Chars.Space);
                        _builder.AppendLine(value);
                    }
                    else
                    {
                        // append the header key and value
                        _builder.Append(header.ArgA.GetString());
                        _builder.Append(Chars.Colon);
                        _builder.Append(Chars.Space);
                        _builder.AppendLine(header.ArgB.ArgA);
                    }
                }

                _refreshCustomHeaders     = true;
                _refreshCustomHeaderIndex = 0;
            }

            if (_refreshCustomHeaders)
            {
                _refreshCustomHeaders = false;

                // iterate the headers from the index to be refreshed
                for (int i = _refreshCustomHeaderIndex; i < _customHeaders.Count; ++i)
                {
                    // persist the header
                    Teple <string, Teple <string, int> > header = _customHeaders[i];

                    header.ArgB.ArgB = _builder.Length;

                    string value;
                    if (_customSingles.TryGetValue(header.ArgA, out value))
                    {
                        // yes, check refresh
                        if (!_refreshCustomHeaders)
                        {
                            // yes, set the header index
                            _refreshCustomHeaderIndex = i;
                            _refreshBuilderIndex      = header.ArgB.ArgB;

                            // flip the refresh flag
                            _refreshCustomHeaders = true;
                        }

                        // remove the single-shot header from the collection
                        _customSingles.Remove(header.ArgA);

                        if (header.ArgB.ArgA == null)
                        {
                            // remove the header from the collection
                            _customHeaders.RemoveQuick(i);
                            --i;
                        }

                        // append the header key and value
                        _builder.Append(header.ArgA);
                        _builder.Append(Chars.Colon);
                        _builder.Append(Chars.Space);
                        _builder.AppendLine(value);
                    }
                    else
                    {
                        // append the header key and value
                        _builder.Append(header.ArgA);
                        _builder.Append(Chars.Colon);
                        _builder.Append(Chars.Space);
                        _builder.AppendLine(header.ArgB.ArgA);
                    }
                }
            }


            foreach (var single in _definedSingles)
            {
                // append the header key and value
                _builder.Append(single.Key.GetString());
                _builder.Append(Chars.Colon);
                _builder.Append(Chars.Space);
                _builder.AppendLine(single.Value);
            }

            _definedSingles.Clear();

            foreach (var single in _customSingles)
            {
                // append the header key and value
                _builder.Append(single.Key);
                _builder.Append(Chars.Colon);
                _builder.Append(Chars.Space);
                _builder.AppendLine(single.Value);
            }

            _customSingles.Clear();

            _builder.AppendLine();

            // should the status code be reset?
            if (_statusCode != 200)
            {
                // yes, reset it
                StatusCode = 200;
                // reset the status description
                _statusDescription = "OK";
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// On socket data being received.
        /// </summary>
        private unsafe void OnReceiveSocketData(IAsyncResult ar)
        {
            int count = 0;

            try {
                // end the receive
                count = Socket.EndReceiveFrom(ar, ref _receiveEndPoint);
            } catch (Exception ex) {
                // release the read lock
                _syncLock.ReleaseRead();

                ProcessError(ex);
                return;
            }

            if (count > 0)
            {
                // is the received buffer chunked?
                byte flag = _receiveBuffer[0];
                if (flag < 60 || flag >= 188)
                {
                    count -= ChunkHeaderSize;

                    int chunkId;
                    int chunkIndex;
                    int chunkCount;

                    // sanity check for correct number of bytes received
                    if (count < 0)
                    {
                        _syncLock.ReleaseRead();
                        ProcessError("Socket didn't receive enough data for chunked information.");
                        return;
                    }

                    // yes, read the chunk details
                    fixed(byte *intP = &_receiveBuffer[1])
                    {
                        chunkId = *(int *)intP;
                    }

                    fixed(byte *intP = &_receiveBuffer[5])
                    {
                        chunkIndex = *(int *)intP;
                    }

                    fixed(byte *intP = &_receiveBuffer[9])
                    {
                        chunkCount = *(int *)intP;
                    }

                    // sanity check for the chunk data being valid
                    if (chunkIndex >= chunkCount)
                    {
                        _syncLock.ReleaseRead();
                        ProcessError("Socket received invalid chunk index and count information.");
                        return;
                    }

                    // write
                    ChunkedGram chunkedGram;
                    if (_receivedChunks.TryGetValue(chunkId, out chunkedGram))
                    {
                        chunkedGram.Length += count;
                        chunkedGram.Chunks.Insert(Teple.New(count, _receiveBuffer), chunkIndex);

                        // have all chunks been added?
                        if (chunkedGram.Chunks.Count == chunkCount)
                        {
                            // yes, remove from the collection
                            _receivedChunks.Remove(chunkId);

                            // create a byte buffer for the entire message
                            byte[] result = new byte[chunkedGram.Length];
                            int    index  = 0;
                            foreach (var chunk in chunkedGram.Chunks)
                            {
                                int length = chunk.ArgA;
                                Micron.CopyMemory(chunk.ArgB, ChunkHeaderSize, result, index, length);
                                index += length;
                            }

                            // reference the endpoint from which the data was received
                            IPEndPoint endpoint = (IPEndPoint)_receiveEndPoint;

                            // run the callback
                            _onReceive.AddRun(ActionSet.New(OnReceive,
                                                            endpoint,
                                                            result,
                                                            chunkedGram.Length));
                        }
                        else
                        {
                            // no, create a new receive buffer
                            _receiveBuffer = BufferCache.Get();
                        }
                    }
                    else
                    {
                        chunkedGram = new ChunkedGram {
                            Chunks    = new ArrayRig <Teple <int, byte[]> >(chunkCount),
                            Timestamp = Time.Timestamp
                        };

                        _receivedChunks.Add(chunkId, chunkedGram);

                        chunkedGram.Chunks.Add(Teple.New(count, _receiveBuffer));
                        chunkedGram.Length += count;

                        // create a new receive buffer
                        _receiveBuffer = BufferCache.Get();
                    }
                }
                else
                {
                    // no, copy the received buffer
                    --count;
                    byte[] buffer = BufferCache.Get(count);
                    Micron.CopyMemory(_receiveBuffer, 1, buffer, 0, count);

                    // reference the endpoint from which the data was received
                    IPEndPoint endpoint = (IPEndPoint)_receiveEndPoint;

                    // run the callback
                    _onReceive.AddRun(ActionSet.New(OnReceive,
                                                    endpoint,
                                                    buffer,
                                                    count));
                }
            }

            if (_receivedChunks.Count > 0)
            {
                // check for any chunked data timeouts
                ArrayRig <int> toRemove = null;
                foreach (var chunkedGram in _receivedChunks)
                {
                    if (Time.Timestamp - chunkedGram.Value.Timestamp > ChunkedGramTimeout)
                    {
                        if (toRemove == null)
                        {
                            toRemove = new ArrayRig <int>();
                        }
                        toRemove.Add(chunkedGram.Key);
                    }
                }
                if (toRemove != null)
                {
                    foreach (var chunkId in toRemove)
                    {
                        ChunkedGram chunked;
                        if (_receivedChunks.TryGetValue(chunkId, out chunked))
                        {
                            _receivedChunks.Remove(chunkId);
                            chunked.Chunks.Dispose();
                        }
                    }
                }
            }

            // release the read lock
            _syncLock.ReleaseRead();

            // create the endpoint for receiving data
            _receiveEndPoint = new IPEndPoint(RemoteEndPoint.Address, RemoteEndPoint.Port);

            try {
                // start receiving again
                Socket.BeginReceiveFrom(_receiveBuffer, 0, Global.BufferSizeLocal, SocketFlags.None,
                                        ref _receiveEndPoint, OnReceiveSocketData, null);
            } catch (Exception ex) {
                ProcessError(ex);
                return;
            }
        }
Ejemplo n.º 11
0
        public bool MoveNext()
        {
            if (_first)
            {
                _first = false;
                return(_node != null);
            }

            while (true)
            {
                // is there the potential to iterate over the current nodes children?
                if (_node.ArraySet)
                {
                    // push current enumerator onto the stack
                    _nodeEnumerators.Add(new Teple <IEnumerator <Node>, bool>(_currentEnumerator, _list));
                    _currentEnumerator = _node.Array.GetEnumerator();
                    if (_currentEnumerator.MoveNext())
                    {
                        _list = true;
                        _node = _currentEnumerator.Current;
                        return(true);
                    }
                }
                if (_node.DictionarySet)
                {
                    // push current enumerator onto the stack
                    _nodeEnumerators.Add(new Teple <IEnumerator <Node>, bool>(_currentEnumerator, _list));
                    _currentEnumerator = _node.Dictionary.Values.GetEnumerator();
                    if (_currentEnumerator.MoveNext())
                    {
                        _list = false;
                        _node = _currentEnumerator.Current;
                        return(true);
                    }
                }

                while (true)
                {
                    // move the current enumerator
                    if (_currentEnumerator.MoveNext())
                    {
                        _node = _currentEnumerator.Current;
                        return(true);
                    }

                    if (_list)
                    {
                        _list = false;
                        if (_node.DictionarySet)
                        {
                            // set the first enumerator as this nodes list
                            _currentEnumerator = _node.Dictionary.Values.GetEnumerator();
                            if (_currentEnumerator.MoveNext())
                            {
                                _node = _currentEnumerator.Current;
                                return(true);
                            }
                        }
                    }

                    // any node enumerators to pop?
                    if (_nodeEnumerators.Count == 0)
                    {
                        return(false);
                    }

                    // pop last enumerator off stack if it exists
                    Teple <IEnumerator <Node>, bool> next = _nodeEnumerators.Pop();
                    _currentEnumerator = next.ArgA;
                    _list = next.ArgB;

                    // move up a node
                    _node = _node.Parent;
                }
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Add the value or retrieve an existing value in a single threadsafe call.
        /// </summary>
        public TValue AddOrGet(TKey key, TValue item)
        {
            _lock.Take();

            // get the item size
            long itemSize = _getItemSize == null ? 1L : _getItemSize(item);

            // does the item already exist in the cache?
            Teple <long, long, TValue> cached;

            if (_lookup.TryGetValue(key, out cached) && cached.ArgA > 0)
            {
                // yes, add the item to the end of the queue
                _queue.Enqueue(key);
                // increment the number of duplicate items in the lookup
                ++cached.ArgA;

                _lock.Release();
                return(cached.ArgC);
            }

            // is the item too large for the cache?
            if (itemSize > MaxItemSize)
            {
                // yes, skip adding it
                _lock.Release();
                return(item);
            }

            // add the item size to the current total
            _size += itemSize;

            // add the item to the current queue
            _queue.Enqueue(key);
            // add the item to the lookup
            _lookup[key] = new Teple <long, long, TValue>(1L, itemSize, item);

            // has the cache overflowed?
            if (_size > MaxSize)
            {
                // while the size has overflowed, iterate
                while (_size > MaxSize)
                {
                    // move to the next queued item
                    _queue.Next();
                    _peeked = false;

                    // get the lookup record
                    Teple <long, long, TValue> current = _lookup[_queue.Current];

                    if (current.ArgA == 0)
                    {
                        continue;
                    }

                    // are there duplicate entries for the current item
                    if (current.ArgA == 1)
                    {
                        // no, decrement the size of the current item
                        _size -= current.ArgB;
                        // remove the lookup entry
                        _lookup.Remove(_queue.Current);

                        // is the callback set?
                        if (_onRemoved.Action != null)
                        {
                            // yes, run it
                            _onRemoved.Run(current.ArgC);
                        }
                    }
                    else
                    {
                        // yes, decrement the number of cache entries
                        --current.ArgA;
                    }
                }
            }

            _lock.Release();

            return(item);
        }