예제 #1
0
        public void Create_Cache()
        {
            var sf     = new SmartFormatter();
            var format = FormatItemPool.GetFormat(sf.Settings, "the base string");
            var fc     = FormatCachePool.Get(format);

            Assert.AreEqual(format, fc.Format);
            Assert.IsAssignableFrom <Dictionary <string, object> >(fc.CachedObjects);
            fc.CachedObjects.Add("key", "value");
            Assert.IsTrue(fc.CachedObjects["key"].ToString() == "value");
            FormatCachePool.Release(fc);
        }
예제 #2
0
파일: Format.cs 프로젝트: Habi-Thapa/csv
        /// <summary>Returns a substring of the current Format.</summary>
        public Format Substring(int startIndex, int length)
        {
            startIndex = this.startIndex + startIndex;
            var endIndex = startIndex + length;

            // Validate the arguments:
            if (startIndex < this.startIndex || startIndex > this.endIndex) // || endIndex > this.endIndex)
            {
                throw new ArgumentOutOfRangeException("startIndex");
            }
            if (endIndex > this.endIndex)
            {
                throw new ArgumentOutOfRangeException("length");
            }

            // If startIndex and endIndex already match this item, we're done:
            if (startIndex == this.startIndex && endIndex == this.endIndex)
            {
                return(this);
            }

            var substring = FormatItemPool.GetFormat(SmartSettings, baseString, startIndex, endIndex);

            foreach (var item in Items)
            {
                if (item.endIndex <= startIndex)
                {
                    continue; // Skip first items
                }
                if (endIndex <= item.startIndex)
                {
                    break; // Done
                }
                var newItem = item;
                if (item is LiteralText) // See if we need to slice the LiteralText:
                {
                    if (startIndex > item.startIndex || item.endIndex > endIndex)
                    {
                        newItem = FormatItemPool.GetLiteralText(SmartSettings, substring, Math.Max(startIndex, item.startIndex), Math.Min(endIndex, item.endIndex));
                    }
                }
                else
                {
                    // item is a placeholder -- we can't split a placeholder though.
                    substring.HasNested = true;
                }

                substring.Items.Add(newItem);
            }

            return(substring);
        }
예제 #3
0
        public override bool TryEvalulateAllLiterals(IFormattingInfo formattingInfo)
        {
            var format = formattingInfo.Format;

            if (format == null)
            {
                return(false);
            }

            var parameters = format.Split('|', 4);

            if (parameters.Count < 2)
            {
                return(false);
            }

            var itemFormat = parameters[0];

            // Spacer
            if (parameters.Count >= 1)
            {
                formattingInfo.Write(parameters[0], null);
            }

            // Last spacer
            if (parameters.Count >= 3)
            {
                formattingInfo.Write(parameters[2], null);
            }

            // Two spacer
            if (parameters.Count >= 4)
            {
                formattingInfo.Write(parameters[3], null);
            }

            if (!itemFormat.HasNested)
            {
                // The format is not nested,
                // so we will treat it as an itemFormat:
                var newItemFormat  = FormatItemPool.GetFormat(m_SmartSettings, itemFormat.baseString, itemFormat.startIndex, itemFormat.endIndex, true);
                var newPlaceholder = FormatItemPool.GetPlaceholder(m_SmartSettings, newItemFormat, itemFormat.startIndex, 0, itemFormat, itemFormat.endIndex);
                newItemFormat.Items.Add(newPlaceholder);
                itemFormat = newItemFormat;
            }

            formattingInfo.Write(itemFormat, null);

            return(true);
        }
예제 #4
0
        public override bool TryEvaluateFormat(IFormattingInfo formattingInfo)
        {
            var format  = formattingInfo.Format;
            var current = formattingInfo.CurrentValue;

            // This method needs the Highest priority so that it comes before the PluralLocalizationExtension and ConditionalExtension

            // This extension requires at least IEnumerable
            if (!(current is IEnumerable enumerable))
            {
                return(false);
            }
            // Ignore Strings, because they're IEnumerable.
            // This issue might actually need a solution
            // for other objects that are IEnumerable.
            if (current is string)
            {
                return(false);
            }
            // If the object is IFormattable, ignore it
            if (current is IFormattable)
            {
                return(false);
            }

            // This extension requires a | to specify the spacer:
            if (format == null)
            {
                return(false);
            }
            var parameters = format.Split('|', 4);

            if (parameters.Count < 2)
            {
                return(false);
            }

            // Grab all formatting options:
            // They must be in one of these formats:
            // itemFormat|spacer
            // itemFormat|spacer|lastSpacer
            // itemFormat|spacer|lastSpacer|twoSpacer
            var itemFormat = parameters[0];
            var spacer     = parameters.Count >= 2 ? parameters[1].GetLiteralText() : "";
            var lastSpacer = parameters.Count >= 3 ? parameters[2].GetLiteralText() : spacer;
            var twoSpacer  = parameters.Count >= 4 ? parameters[3].GetLiteralText() : lastSpacer;

            if (!itemFormat.HasNested)
            {
                // The format is not nested,
                // so we will treat it as an itemFormat:
                var newItemFormat  = FormatItemPool.GetFormat(m_SmartSettings, itemFormat.baseString, itemFormat.startIndex, itemFormat.endIndex, true);
                var newPlaceholder = FormatItemPool.GetPlaceholder(m_SmartSettings, newItemFormat, itemFormat.startIndex, 0, itemFormat, itemFormat.endIndex);
                newItemFormat.Items.Add(newPlaceholder);
                itemFormat = newItemFormat;
            }

            // Let's buffer all items from the enumerable (to ensure the Count without double-enumeration):
            List <object> bufferItems = null;

            if (!(current is ICollection items))
            {
                bufferItems = ListPool <object> .Get();

                foreach (var item in enumerable)
                {
                    bufferItems.Add(item);
                }
                items = bufferItems;
            }

            var oldCollectionIndex = CollectionIndex; // In case we have nested arrays, we might need to restore the CollectionIndex

            CollectionIndex = -1;
            foreach (var item in items)
            {
                CollectionIndex += 1; // Keep track of the index

                // Determine which spacer to write:
                if (spacer == null || CollectionIndex == 0)
                {
                    // Don't write the spacer.
                }
                else if (CollectionIndex < items.Count - 1)
                {
                    formattingInfo.Write(spacer);
                }
                else if (CollectionIndex == 1)
                {
                    formattingInfo.Write(twoSpacer);
                }
                else
                {
                    formattingInfo.Write(lastSpacer);
                }

                // Output the nested format for this item:
                formattingInfo.Write(itemFormat, item);
            }

            CollectionIndex = oldCollectionIndex; // Restore the CollectionIndex

            if (bufferItems != null)
            {
                ListPool <object> .Release(bufferItems);
            }

            return(true);
        }