コード例 #1
0
ファイル: IListOps.cs プロジェクト: jschementi/iron
        public static object Repeat(UnaryOpStorage/*!*/ allocateStorage, JoinConversionStorage/*!*/ conversions,
            IList/*!*/ self, [DefaultProtocol, NotNull]Union<MutableString, int> repeat) {

            if (repeat.IsFixnum()) {
                return Repeat(allocateStorage, self, repeat.Fixnum());
            } else {
                return Repeat(conversions, self, repeat.String());
            }
        }
コード例 #2
0
ファイル: IListOps.cs プロジェクト: jschementi/iron
 public static MutableString Repeat(JoinConversionStorage/*!*/ conversions, IList/*!*/ self, [NotNull]MutableString/*!*/ separator) {
     return Join(conversions, self, separator);
 }
コード例 #3
0
ファイル: IListOps.cs プロジェクト: jschementi/iron
        public static MutableString/*!*/ JoinWithLazySeparatorConversion(
            JoinConversionStorage/*!*/ conversions, 
            ConversionStorage<MutableString>/*!*/ toStr,
            IList/*!*/ self, object separator) {

            if (self.Count == 0) {
                return MutableString.CreateEmpty();
            }

            return Join(conversions, self, separator != null ? Protocols.CastToString(toStr, separator) : null);
        }
コード例 #4
0
ファイル: IListOps.cs プロジェクト: jschementi/iron
 public static MutableString/*!*/ Join(JoinConversionStorage/*!*/ conversions, IList/*!*/ self) {
     return Join(conversions, self, conversions.Context.ItemSeparator);
 }
コード例 #5
0
ファイル: IListOps.cs プロジェクト: jschementi/iron
        public static MutableString/*!*/ Join(JoinConversionStorage/*!*/ conversions, IList/*!*/ self, MutableString separator) {
            var parts = new List<MutableString>(self.Count);
            bool? isBinary = (separator != null) ? separator.IsBinary : (bool?)null;
            Dictionary<object, bool> seen = null;
            
            // build a list of strings to join:
            JoinRecursive(conversions, self, parts, ref isBinary, ref seen);
            if (parts.Count == 0) {
                return MutableString.CreateEmpty();
            }

            if (separator != null && separator.IsBinary != isBinary && !separator.IsAscii()) {
                isBinary = true;
            }

            // calculate length:
            MutableString any = separator;
            int length = (separator != null) ? (isBinary.HasValue && isBinary.Value ? separator.GetByteCount() : separator.GetCharCount()) * (parts.Count - 1) : 0;
            for (int i = 0, n = parts.Count; i < n; i++) {
                var part = parts[i];
                if (part != null) {
                    length += (isBinary.HasValue && isBinary.Value) ? part.GetByteCount() : part.GetCharCount();
                    if (any == null) {
                        any = part;
                    }
                }
            }

            if (any == null) {
                return MutableString.CreateEmpty();
            }

            var result = isBinary.HasValue && isBinary.Value ? 
                MutableString.CreateBinary(length, any.Encoding) :
                MutableString.CreateMutable(length, any.Encoding);

            for (int i = 0, n = parts.Count; i < n; i++) {
                var part = parts[i];

                if (separator != null && i > 0) {
                    result.Append(separator);
                }

                if (part != null) {
                    result.Append(part);
                    result.TaintBy(part);
                }
            }

            if (separator != null) {
                result.TaintBy(separator);
            }
            if (!result.IsTainted || !result.IsUntrusted) {
                result.TaintBy(self, conversions.Context);
            }
            return result;
        }
コード例 #6
0
ファイル: IListOps.cs プロジェクト: jschementi/iron
        private static void JoinRecursive(JoinConversionStorage/*!*/ conversions, IList/*!*/ list, List<MutableString/*!*/>/*!*/ parts, 
            ref bool? isBinary, ref Dictionary<object, bool> seen) {

            foreach (object item in list) {
                if (item == null) {
                    parts.Add(null);
                    continue;
                }

                IList listItem = conversions.ToAry.Target(conversions.ToAry, item);
                if (listItem != null) {
                    bool _;
                    if (ReferenceEquals(listItem, list) || seen != null && seen.TryGetValue(listItem, out _)) {
                        throw RubyExceptions.CreateArgumentError("recursive array join");
                    }

                    if (seen == null) {
                        seen = new Dictionary<object, bool>(ReferenceEqualityComparer<object>.Instance);
                    }

                    seen.Add(listItem, true);
                    JoinRecursive(conversions, listItem, parts, ref isBinary, ref seen);
                    seen.Remove(listItem);
                    continue;
                }

                // try to_str first, then to_s:
                MutableString strItem = conversions.ToStr.Target(conversions.ToStr, item) ?? conversions.ToS.Target(conversions.ToS, item);
                parts.Add(strItem);
                isBinary = isBinary.HasValue ? (isBinary | strItem.IsBinary) : strItem.IsBinary;
            }
        }