/// <summary> /// Returns <b>true</b> if a Ruby file is successfully loaded, <b>false</b> if it is already loaded. /// </summary> /// <param name="globalScope"> /// A scope against which the file should be executed or null to create a new scope. /// </param> /// <param name="self"></param> /// <param name="path"></param> /// <param name="flags"></param> /// <param name="loaded"></param> /// <returns>True if the file was loaded/executed by this call.</returns> public bool LoadFile(Scope globalScope, object self, MutableString /*!*/ path, LoadFlags flags, out object loaded) { Assert.NotNull(path); string assemblyName, typeName; string strPath = path.ConvertToString(); if (TryParseAssemblyName(strPath, out typeName, out assemblyName)) { if (AlreadyLoaded(strPath, (string)null, flags)) { loaded = ((flags & LoadFlags.ResolveLoaded) != 0) ? GetAssembly(assemblyName, true, false) : null; return(false); } Assembly assembly = LoadAssembly(assemblyName, typeName, false, false); if (assembly != null) { FileLoaded(path.Clone(), flags); loaded = assembly; return(true); } } return(LoadFromPath(globalScope, self, strPath, path.Encoding, flags, out loaded)); }
public void ICloneable_op_Clone() { ICloneable expected = new MutableString("One"); var actual = expected.Clone(); Assert.Equal(expected, actual); Assert.NotSame(expected, actual); }
private MatchData(Match/*!*/ match, MutableString/*!*/ originalString, int[] kIndices) { Debug.Assert(match.Success); _match = match; // TODO (opt): create groups instead? _originalString = originalString.Clone().Freeze(); _kIndices = kIndices; IsTainted = originalString.IsTainted; }
public static object BlockReplaceAll(ConversionStorage<MutableString>/*!*/ tosConversion, RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, [NotNull]RubyRegex pattern) { object blockResult; MutableString result; self.TrackChanges(); object r = BlockReplaceAll(tosConversion, scope, self, block, pattern, out blockResult, out result) ? blockResult : (result ?? self.Clone()); RequireNoVersionChange(self); return r; }
public static object SetHashElement(RubyContext /*!*/ context, IDictionary <object, object> /*!*/ obj, object key, object value) { MutableString str = key as MutableString; if (str != null) { key = str.Duplicate(context, false, str.Clone()).Freeze(); } else { key = BaseSymbolDictionary.NullToObj(key); } return(obj[key] = value); }
public LexicalMatch MatchBeginning(string value) { if (null == value) { throw new ArgumentNullException("value"); } if (0 == value.Length) { return(null); } var result = Match(value); if (null != result) { return(result); } var substring = new MutableString(value); var clone = substring.Clone(); #if NET20 foreach (var word in IEnumerableExtensionMethods.Reverse(substring.ToString().Split(' '))) #else foreach (var word in substring.ToString().Split(' ').Reverse()) #endif { if (0 == word.Length) { continue; } substring.RemoveFromEnd(word).Trim(); result = Match(substring); if (null == result) { continue; } result.Suffix = clone.Suffix(substring).Trim(); return(result); } return(null); }
public static MutableString RemoveSubstringInPlace(RubyScope/*!*/ scope, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex, [DefaultProtocol]int occurrance) { if (regex.IsEmpty) { return self.Clone().TaintBy(regex, scope); } MatchData match = RegexpOps.Match(scope, regex, self); if (match == null || !RegexpOps.NormalizeGroupIndex(ref occurrance, match.GroupCount)) { return null; } return match.GroupSuccess(occurrance) ? RemoveSubstringInPlace(self, match.GetGroupStart(occurrance), match.GetGroupLength(occurrance)).TaintBy(regex, scope) : null; }
public static void TestHashCodeMultithread(TestedClass testWhat) { Int32 threadCount = 2; Int32 iterationsCount = 1000000; BinaryArray a = new BinaryArray(); MutableString s = new MutableString(); Barrier beforeWrite = new Barrier(threadCount); Barrier beforeRead = new Barrier(threadCount); Action <int> action = (x) => { while (index < iterationsCount) { beforeWrite.SignalAndWait(); if ((previousIndex % threadCount) == x) { index++; expectedHash = index; switch (testWhat) { case TestedClass.BinaryArray: a.Assign(index); break; case TestedClass.MutableString: s.Assign(index); expectedHash = s.Clone().GetHashCode(); break; } a.Assign(index); if ((index % 100000) == 0) { Console.WriteLine("Index = " + index); } } beforeRead.SignalAndWait(); int currentHash = 0; switch (testWhat) { case TestedClass.BinaryArray: currentHash = a.GetHashCode(); break; case TestedClass.MutableString: currentHash = s.GetHashCode(); break; } Assert.AreEqual(currentHash, expectedHash); previousIndex = index; } }; Task[] t = new Task[threadCount]; for (int i = 0; i < threadCount; ++i) { int id = i; t[i] = new Task(() => action(id)); t[i].Start(); } Task.WaitAll(t); }
public static MutableString/*!*/ Squeeze(RubyContext/*!*/ context, MutableString/*!*/ self, [NotNull]params object[] args) { MutableString result = self.Clone(); SqueezeMutableString(result, Protocols.CastToStrings(context, args)); return result; }
public static MutableString ReplaceAll(RubyScope/*!*/ scope, MutableString/*!*/ self, [DefaultProtocol, NotNull]RubyRegex/*!*/ pattern, [DefaultProtocol, NotNull]MutableString/*!*/ replacement) { return ReplaceAll(scope, self, replacement, pattern) ?? self.Clone(); }
public static object BlockReplaceFirst(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, [NotNull]MutableString matchString) { object blockResult; MutableString result; var regex = new RubyRegex(Regex.Escape(matchString.ToString()), RubyRegexOptions.NONE); return BlockReplaceFirst(scope, self, block, regex, out blockResult, out result) ? blockResult : (result ?? self.Clone()); }
public static object BlockReplaceFirst(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ pattern) { object blockResult; MutableString result; return BlockReplaceFirst(scope, self, block, pattern, out blockResult, out result) ? blockResult : (result ?? self.Clone()); }
public static MutableString/*!*/ Chop(MutableString/*!*/ self) { return self.IsEmpty ? self.CreateInstance().TaintBy(self) : ChopInteral(self.Clone()); }
public void IListTest(IListTestType type) { MutableString s = new MutableString(); MutableString s1 = new MutableString(); if (type == IListTestType.Contains) { s.Assign("qwertyui"); Assert.AreEqual(s.Contains('r'), true); Assert.AreEqual(s.Contains('q'), true); Assert.AreEqual(s.Contains('i'), true); Assert.AreEqual(s.Contains('a'), false); Assert.AreEqual(s.Contains('s'), false); Assert.AreEqual(s.Contains('d'), false); } if (type == IListTestType.CopyTo) { s.Assign("sadfsf"); s1.Assign("r"); s1.CopyTo(s); Assert.AreEqual(s1, "r"); Assert.AreEqual(s, "r"); s.Assign("sadfsf"); s1.Assign("r"); s.CopyTo(s1); Assert.AreEqual(s1, "sadfsf"); Assert.AreEqual(s, "sadfsf"); s.Assign("qwer"); Array.Resize(ref ar1, 10); s.CopyTo(ar1, 0); Assert.AreEqual(ar1[0], 'q'); Assert.AreEqual(ar1[1], 'w'); Assert.AreEqual(ar1[2], 'e'); Assert.AreEqual(ar1[3], 'r'); } if (type == IListTestType.IndexOf) { s.Assign("qwertyui"); Assert.AreEqual(s.IndexOf('r'), 3); Assert.AreEqual(s.IndexOf('q'), 0); Assert.AreEqual(s.IndexOf('i'), 7); Assert.AreEqual(s.IndexOf('a'), -1); Assert.AreEqual(s.IndexOf('s'), -1); Assert.AreEqual(s.IndexOf('d'), -1); } if (type == IListTestType.Insert) { s.Assign("qazxcv"); s.Insert(0, '1'); Assert.AreEqual(s, "1qazxcv"); s.Insert(2, '2'); Assert.AreEqual(s, "1q2azxcv"); s.Insert(8, '8'); Assert.AreEqual(s, "1q2azxcv8"); } if (type == IListTestType.Remove) { s.Assign("qwaedszf"); s.Remove('e'); Assert.AreEqual(s, "qwadszf"); s.Remove('q'); Assert.AreEqual(s, "wadszf"); s.Remove('f'); Assert.AreEqual(s, "wadsz"); } if (type == IListTestType.RemoveAt) { s.Assign("qwaedszf"); s.RemoveAt(3); Assert.AreEqual(s, "qwadszf"); s.RemoveAt(0); Assert.AreEqual(s, "wadszf"); s.RemoveAt(5); Assert.AreEqual(s, "wadsz"); } if (type == IListTestType.Equals) { s.Assign("sd"); Assert.AreEqual(s.Equals(s), true); Assert.AreEqual(MutableString.Equals(s, s), true); s1.Assign("sd"); Assert.AreEqual(s.Equals(s1), true); Assert.AreEqual(true, s.Equals((IReadOnlyString)s1)); s1.Assign("sdsd"); Assert.AreEqual(s.Equals(s1), false); Assert.AreEqual(false, s.Equals((IReadOnlyString)s1)); Assert.AreEqual(s1.Equals("sdsd"), true); Assert.AreEqual(s1.Equals("sdsd1"), false); Assert.AreEqual(s1.Equals("sdsq"), false); Assert.AreEqual(s1.Equals((MutableString)null), false); Assert.AreEqual(MutableString.Equals(null, null), true); Assert.AreEqual(MutableString.Equals(s, null), false); Assert.AreEqual(MutableString.Equals(null, s), false); Assert.AreEqual(MutableString.Equals(new MutableString(), new MutableString()), true); } if (type == IListTestType.Clone) { s.Assign("qwer"); MutableString s2 = s.Clone(); Assert.AreEqual(s2, "qwer"); Assert.AreEqual(s2, s); } if (type == IListTestType.CompareTo) { s.Assign("qwer"); s1.Assign("qwzz"); Assert.AreEqual(s.CompareTo(s1) < 0, true); Assert.AreEqual(MutableString.Compare(s, s1) < 0, true); Assert.AreEqual(s1.CompareTo(s) > 0, true); Assert.AreEqual(MutableString.Compare(s1, s) > 0, true); s1.Assign("qwer"); Assert.AreEqual(s.CompareTo(s1), 0); Assert.AreEqual(s1.CompareTo(s), 0); Assert.AreEqual(MutableString.Compare(s, s1), 0); } }
// Expand directory path - these cases exist: // // 1. Empty string or nil means return current directory // 2. ~ with non-existent HOME directory throws exception // 3. ~, ~/ or ~\ which expands to HOME // 4. ~foo is left unexpanded // 5. Expand to full path if path is a relative path // // No attempt is made to determine whether the path is valid or not // Returned path is always canonicalized to forward slashes private static MutableString/*!*/ ExpandPath(RubyContext/*!*/ context, MutableString/*!*/ path) { PlatformAdaptationLayer pal = context.DomainManager.Platform; int length = path.Length; bool raisingRubyException = false; try { if (path == null || length == 0) return RubyUtils.CanonicalizePath(MutableString.Create(Directory.GetCurrentDirectory())); if (path.GetChar(0) == '~') { if (length == 1 || (path.GetChar(1) == Path.DirectorySeparatorChar || path.GetChar(1) == Path.AltDirectorySeparatorChar)) { string homeDirectory = pal.GetEnvironmentVariable("HOME"); if (homeDirectory == null) { raisingRubyException = true; throw RubyExceptions.CreateArgumentError("couldn't find HOME environment -- expanding `~'"); } if (length <= 2) { path = MutableString.Create(homeDirectory); } else { path = MutableString.Create(Path.Combine(homeDirectory, path.GetSlice(2).ConvertToString())); } return RubyUtils.CanonicalizePath(path); } else { return path; } } else { string pathStr = path.ConvertToString(); MutableString result = RubyUtils.CanonicalizePath(MutableString.Create(Path.GetFullPath(pathStr))); // Path.GetFullPath("c:/winDOWS/foo") returns "c:/winDOWS/foo", but Path.GetFullPath("c:/winDOWS/~") returns "c:/Windows/~". // So we special-case it as this is not the Ruby behavior. Also, the Ruby behavior is very complicated about when it // matches the case of the input argument, and when it matches the case of the file system. It can match the file system case // for part of the result and not the rest. So we restrict the special-case to a very limited scenarios that unblock real-world code. if (pathStr[pathStr.Length - 1] == '~' && String.Compare(pathStr, result.ConvertToString(), true) == 0) { result = path.Clone(); } return result; } } catch (Exception e) { if (raisingRubyException) { throw; } // Re-throw exception as a reasonable Ruby exception throw RubyErrno.CreateEINVAL(path.ConvertToString(), e); } }
/// <summary> /// Returns <b>true</b> if a Ruby file is successfully loaded, <b>false</b> if it is already loaded. /// </summary> /// <param name="globalScope"> /// A scope against which the file should be executed or null to create a new scope. /// </param> /// <param name="self"></param> /// <param name="path"></param> /// <param name="flags"></param> /// <param name="loaded"></param> /// <returns>True if the file was loaded/executed by this call.</returns> public bool LoadFile(Scope globalScope, object self, MutableString/*!*/ path, LoadFlags flags, out object loaded) { Assert.NotNull(path); string assemblyName, typeName; string strPath = path.ConvertToString(); if (TryParseAssemblyName(strPath, out typeName, out assemblyName)) { if (AlreadyLoaded(strPath, (string)null, flags)) { loaded = ((flags & LoadFlags.ResolveLoaded) != 0) ? GetAssembly(assemblyName, true, false) : null; return false; } Assembly assembly = LoadAssembly(assemblyName, typeName, false, false); if (assembly != null) { FileLoaded(path.Clone(), flags); loaded = assembly; return true; } } return LoadFromPath(globalScope, self, strPath, path.Encoding, flags, out loaded); }
public static MutableString FirstChar(MutableString/*!*/ self) { if (self.IsEmpty) { return self.Clone(); } // TODO: optimize var enumerator = self.GetCharacters(); enumerator.MoveNext(); return enumerator.Current.ToMutableString(self.Encoding); }
public static MutableString Encode( ConversionStorage<IDictionary<object, object>>/*!*/ toHash, ConversionStorage<MutableString>/*!*/ toStr, MutableString/*!*/ self, [Optional]object toEncoding, [Optional]object fromEncoding, [DefaultParameterValue(null), DefaultProtocol]IDictionary<object, object> options) { // TODO: optimize return EncodeInPlace(toHash, toStr, self.Clone(), toEncoding, fromEncoding, options); }
public static MutableString/*!*/ Chop(MutableString/*!*/ self) { return (self.Length == 0) ? self.CreateInstance().TaintBy(self) : ChopInteral(self.Clone()); }
// returns true if block jumped // "result" will be null if there is no successful match private static bool BlockReplaceFirst(RubyScope/*!*/ scope, MutableString/*!*/ input, BlockParam/*!*/ block, RubyRegex/*!*/ pattern, out object blockResult, out MutableString result) { var matchScope = scope.GetInnerMostClosureScope(); MatchData match = RegexpOps.Match(scope, pattern, input); if (match == null || !match.Success) { result = null; blockResult = null; matchScope.CurrentMatch = null; return false; } // copy upfront so that no modifications to the input string are included in the result: result = input.Clone(); matchScope.CurrentMatch = match; if (block.Yield(MutableString.Create(match.Value), out blockResult)) { return true; } // resets the $~ scope variable to the last match (skipd if block jumped): matchScope.CurrentMatch = match; MutableString replacement = Protocols.ConvertToString(scope.RubyContext, blockResult); result.TaintBy(replacement); // Note - we don't interpolate special sequences like \1 in block return value result.Replace(match.Index, match.Length, replacement); blockResult = null; return false; }
public static MutableString/*!*/ ReplaceAll(ConversionStorage<MutableString>/*!*/ toS, BinaryOpStorage/*!*/ hashDefault, RubyScope/*!*/ scope, MutableString/*!*/ self, [DefaultProtocol, NotNull]RubyRegex/*!*/ pattern, [DefaultProtocol, NotNull]Union<IDictionary<object, object>, MutableString>/*!*/ replacement) { return ReplaceAll(toS, hashDefault, scope, self, replacement, pattern) ?? self.Clone(); }
public static object BlockReplaceAll(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, [NotNull]RubyRegex pattern) { object blockResult; MutableString result; uint version = self.Version; object r = BlockReplaceAll(scope, self, block, pattern, out blockResult, out result) ? blockResult : (result ?? self.Clone()); RequireNoVersionChange(version, self); return r; }
internal static MatchData Create(Match/*!*/ match, MutableString/*!*/ input, bool freezeInput, string/*!*/ encodedInput, RubyEncoding kcoding, int kStart) { if (!match.Success) { return null; } int[] kIndices; if (kcoding != null) { // TODO (opt): minimize GetByteCount calls, remove ToCharArray: char[] kCodedChars = encodedInput.ToCharArray(); Encoding encoding = kcoding.StrictEncoding; kIndices = new int[match.Groups.Count * 2]; for (int i = 0; i < match.Groups.Count; i++) { var group = match.Groups[i]; if (group.Success) { // group start index: kIndices[i * 2] = kStart + encoding.GetByteCount(kCodedChars, 0, group.Index); // group length: kIndices[i * 2 + 1] = encoding.GetByteCount(kCodedChars, group.Index, group.Length); } else { kIndices[i * 2] = -1; } } } else { kIndices = null; } if (freezeInput) { input = input.Clone().Freeze(); } return new MatchData(match, input, kIndices); }
public static object BlockReplaceAll(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, [NotNull]MutableString matchString) { object blockResult; MutableString result; var regex = new RubyRegex(Regex.Escape(matchString.ToString()), RubyRegexOptions.NONE); uint version = self.Version; object r = BlockReplaceAll(scope, self, block, regex, out blockResult, out result) ? blockResult : (result ?? self.Clone()); RequireNoVersionChange(version, self); return r; }
public static MutableString/*!*/ LeftJustify(MutableString/*!*/ self, [DefaultProtocol]int width, [DefaultProtocol, NotNull]MutableString/*!*/ padding) { if (padding.Length == 0) { throw RubyExceptions.CreateArgumentError("zero width padding"); } int count = width - self.Length; if (count <= 0) { return self; } int iterations = count / padding.Length; int remainder = count % padding.Length; MutableString result = self.Clone().TaintBy(padding); for (int i = 0; i < iterations; i++) { result.Append(padding); } result.Append(padding, 0, remainder); return result; }
public static MutableString/*!*/ Succ(MutableString/*!*/ self) { return SuccInPlace(self.Clone()); }
public static MutableString RemoveSubstringInPlace(RubyScope/*!*/ scope, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex, [DefaultProtocol]int occurrance) { if (regex.IsEmpty) { return self.Clone().TaintBy(regex, scope); } Group group = MatchRegexp(scope, self, regex, occurrance); return group == null ? null : RemoveSubstringInPlace(self, group.Index, group.Length).TaintBy(regex, scope); }
public static MutableString/*!*/ GetReversed(MutableString/*!*/ self) { return self.Clone().Reverse(); }
public static MutableString/*!*/ UpCase(MutableString/*!*/ self) { MutableString result = self.Clone(); UpCaseMutableString(result); return result; }
public static MutableString RemoveSubstringInPlace(RubyScope/*!*/ scope, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex) { if (regex.IsEmpty) { return self.Clone().TaintBy(regex, scope); } MatchData match = RegexpOps.Match(scope, regex, self); if (match == null || !match.Success) { return null; } return RemoveSubstringInPlace(self, match.Index, match.Length).TaintBy(regex, scope); }
public static object BlockReplaceAll(ConversionStorage<MutableString>/*!*/ tosConversion, RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, [NotNull]MutableString matchString) { object blockResult; MutableString result; // TODO: var regex = new RubyRegex(MutableString.CreateMutable(Regex.Escape(matchString.ToString()), matchString.Encoding), RubyRegexOptions.NONE); self.TrackChanges(); object r = BlockReplaceAll(tosConversion, scope, self, block, regex, out blockResult, out result) ? blockResult : (result ?? self.Clone()); RequireNoVersionChange(self); return r; }
public static MutableString/*!*/ Capitalize(MutableString/*!*/ self) { MutableString result = self.Clone(); CapitalizeMutableString(result); return result; }
public static MutableString/*!*/ Squeeze(RubyContext/*!*/ context, MutableString/*!*/ self, [DefaultProtocol, NotNull, NotNullItems]params MutableString/*!*/[]/*!*/ args) { MutableString result = self.Clone(); SqueezeMutableString(result, args); return result; }
private static MutableString InternalChomp(MutableString/*!*/ self, MutableString separator) { if (separator == null) { return self.Clone(); } // Remove multiple trailing CR/LFs if (separator.Length == 0) { return ChompTrailingCarriageReturns(self, false).TaintBy(self); } // Remove single trailing CR/LFs MutableString result = self.Clone(); int length = result.Length; if (separator.Length == 1 && separator.GetChar(0) == '\n') { if (length > 1 && result.GetChar(length - 2) == '\r' && result.GetChar(length - 1) == '\n') { result.Remove(length - 2, 2); } else if (length > 0 && (self.GetChar(length - 1) == '\n' || result.GetChar(length - 1) == '\r')) { result.Remove(length - 1, 1); } } else if (EndsWith(result, separator)) { result.Remove(length - separator.Length, separator.Length); } return result; }
internal static MutableString/*!*/ Translate(MutableString/*!*/ src, MutableString/*!*/ from, MutableString/*!*/ to, bool inplace, bool squeeze, out bool anyCharacterMaps) { Assert.NotNull(src, from, to); if (from.IsEmpty) { anyCharacterMaps = false; return inplace ? src : src.Clone(); } MutableString dst; if (inplace) { dst = src; } else { dst = src.CreateInstance().TaintBy(src); } // TODO: KCODE src.RequireCompatibleEncoding(from); dst.RequireCompatibleEncoding(to); from.SwitchToCharacters(); to.SwitchToCharacters(); CharacterMap map = CharacterMap.Create(from, to); if (to.IsEmpty) { anyCharacterMaps = MutableString.TranslateRemove(src, dst, map); } else if (squeeze) { anyCharacterMaps = MutableString.TranslateSqueeze(src, dst, map); } else { anyCharacterMaps = MutableString.Translate(src, dst, map); } return dst; }