Beispiel #1
0
        /// <summary>
        /// Returns all context data objects (depth first)
        /// </summary>
        internal static IEnumerable <PipelineContextData> Traverse(
            this PipelineContextData value,
            Boolean omitKeys)
        {
            yield return(value);

            if (value is ArrayContextData || value is DictionaryContextData)
            {
                var state = new TraversalState(null, value);
                while (state != null)
                {
                    if (state.MoveNext(omitKeys))
                    {
                        value = state.Current;
                        yield return(value);

                        if (value is ArrayContextData || value is DictionaryContextData)
                        {
                            state = new TraversalState(state, value);
                        }
                    }
                    else
                    {
                        state = state.Parent;
                    }
                }
            }
        }
Beispiel #2
0
 public TraversalState(
     TraversalState parent,
     PipelineContextData data)
 {
     Parent = parent;
     m_data = data;
 }
Beispiel #3
0
 public DictionaryContextDataPair(
     String key,
     PipelineContextData value)
 {
     Key   = key;
     Value = value;
 }
Beispiel #4
0
        internal static void AddBytes(
            this TemplateMemory memory,
            PipelineContextData value,
            Boolean traverse)
        {
            var bytes = CalculateBytes(memory, value, traverse);

            memory.AddBytes(bytes);
        }
Beispiel #5
0
        public static NumberContextData AssertNumber(
            this PipelineContextData value,
            String objectDescription)
        {
            if (value is NumberContextData num)
            {
                return(num);
            }

            throw new ArgumentException($"Unexpected type '{value?.GetType().Name}' encountered while reading '{objectDescription}'. The type '{nameof(NumberContextData)}' was expected.");
        }
Beispiel #6
0
        public static BooleanContextData AssertBoolean(
            this PipelineContextData value,
            String objectDescription)
        {
            if (value is BooleanContextData boolValue)
            {
                return(boolValue);
            }

            throw new ArgumentException($"Unexpected type '{value?.GetType().Name}' encountered while reading '{objectDescription}'. The type '{nameof(BooleanContextData)}' was expected.");
        }
Beispiel #7
0
        public static CaseSensitiveDictionaryContextData AssertCaseSensitiveDictionary(
            this PipelineContextData value,
            String objectDescription)
        {
            if (value is CaseSensitiveDictionaryContextData dictionary)
            {
                return(dictionary);
            }

            throw new ArgumentException($"Unexpected type '{value?.GetType().Name}' encountered while reading '{objectDescription}'. The type '{nameof(CaseSensitiveDictionaryContextData)}' was expected.");
        }
Beispiel #8
0
        internal static TemplateToken ToTemplateToken(this PipelineContextData data)
        {
            if (data is null)
            {
                return(new NullToken(null, null, null));
            }

            switch (data.Type)
            {
            case PipelineContextDataType.Dictionary:
                var dictionary = data.AssertDictionary("dictionary");
                var mapping    = new MappingToken(null, null, null);
                if (dictionary.Count > 0)
                {
                    foreach (var pair in dictionary)
                    {
                        var key   = new StringToken(null, null, null, pair.Key);
                        var value = pair.Value.ToTemplateToken();
                        mapping.Add(key, value);
                    }
                }
                return(mapping);

            case PipelineContextDataType.Array:
                var array    = data.AssertArray("array");
                var sequence = new SequenceToken(null, null, null);
                if (array.Count > 0)
                {
                    foreach (var item in array)
                    {
                        sequence.Add(item.ToTemplateToken());
                    }
                }
                return(sequence);

            case PipelineContextDataType.String:
                var stringData = data as StringContextData;
                return(new StringToken(null, null, null, stringData.Value));

            case PipelineContextDataType.Boolean:
                var booleanData = data as BooleanContextData;
                return(new BooleanToken(null, null, null, booleanData.Value));

            case PipelineContextDataType.Number:
                var numberData = data as NumberContextData;
                return(new NumberToken(null, null, null, numberData.Value));

            default:
                throw new NotSupportedException($"Unexpected {nameof(PipelineContextDataType)} type '{data.Type}'");
            }
        }
Beispiel #9
0
        internal static JToken ToJToken(this PipelineContextData value)
        {
            JToken result;

            if (value is StringContextData str)
            {
                result = str.Value ?? String.Empty;
            }
            else if (value is BooleanContextData booleanValue)
            {
                result = booleanValue.Value;
            }
            else if (value is NumberContextData num)
            {
                result = num.Value;
            }
            else if (value is ArrayContextData array)
            {
                var jarray = new JArray();

                foreach (var item in array)
                {
                    jarray.Add(item.ToJToken()); // Recurse
                }

                result = jarray;
            }
            else if (value is DictionaryContextData dictionary)
            {
                var jobject = new JObject();

                foreach (var pair in dictionary)
                {
                    var key    = pair.Key ?? String.Empty;
                    var value2 = pair.Value.ToJToken(); // Recurse

                    if (value2 != null)
                    {
                        jobject[key] = value2;
                    }
                }

                result = jobject;
            }
            else
            {
                throw new InvalidOperationException("Internal error reading the template. Expected a string, an array, or a dictionary");
            }

            return(result);
        }
Beispiel #10
0
        internal static Int32 CalculateBytes(
            this TemplateMemory memory,
            PipelineContextData value,
            Boolean traverse)
        {
            var enumerable = traverse ? value.Traverse() : new[] { value } as IEnumerable <PipelineContextData>;
            var result     = 0;

            foreach (var item in enumerable)
            {
                // This measurement doesn't have to be perfect
                // https://codeblog.jonskeet.uk/2011/04/05/of-memory-and-strings/
                switch (item?.Type)
                {
                case PipelineContextDataType.String:
                    var str = item.AssertString("string").Value;
                    checked
                    {
                        result += TemplateMemory.MinObjectSize + TemplateMemory.StringBaseOverhead + ((str?.Length ?? 0) * sizeof(Char));
                    }
                    break;

                case PipelineContextDataType.Array:
                case PipelineContextDataType.Dictionary:
                case PipelineContextDataType.Boolean:
                case PipelineContextDataType.Number:
                    // Min object size is good enough. Allows for base + a few fields.
                    checked
                    {
                        result += TemplateMemory.MinObjectSize;
                    }
                    break;

                case null:
                    checked
                    {
                        result += IntPtr.Size;
                    }
                    break;

                default:
                    throw new NotSupportedException($"Unexpected pipeline context data type '{item.Type}'");
                }
            }

            return(result);
        }
Beispiel #11
0
 /// <summary>
 /// Returns all context data objects (depth first)
 /// </summary>
 internal static IEnumerable <PipelineContextData> Traverse(this PipelineContextData value)
 {
     return(Traverse(value, omitKeys: false));
 }