public static RubyIO /*!*/ OpenPipe(RubyContext /*!*/ context, RubyClass /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ command, [DefaultProtocol, Optional, NotNull] MutableString modeString) { bool preserveEndOfLines; IOMode mode = RubyIO.ParseIOMode(modeString.ConvertToString(), out preserveEndOfLines); ProcessStartInfo startInfo = KernelOps.GetShell(context, command); startInfo.UseShellExecute = false; if (mode == IOMode.ReadOnlyFromStart) { startInfo.RedirectStandardOutput = true; } else if (mode == IOMode.WriteOnlyAppend || mode == IOMode.WriteOnlyTruncate) { startInfo.RedirectStandardInput = true; } else { startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardInput = true; } Process process; try { process = Process.Start(startInfo); } catch (Exception e) { throw new Errno.NoEntryError(startInfo.FileName, e); } context.ChildProcessExitStatus = new RubyProcess.Status(process); StreamReader reader = null; StreamWriter writer = null; if (startInfo.RedirectStandardOutput) { reader = process.StandardOutput; } if (startInfo.RedirectStandardInput) { writer = process.StandardInput; } return(new RubyIO(context, reader, writer, modeString.ConvertToString())); }
public static MutableString GetVariable(RubyContext /*!*/ context, object /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ name) { PlatformAdaptationLayer pal = context.DomainManager.Platform; string value = pal.GetEnvironmentVariable(name.ConvertToString()); return((value != null) ? FrozenString(context, value) : null); }
private static int GetMonthComponent(ConversionStorage <int> /*!*/ conversionStorage, ConversionStorage <MutableString> /*!*/ strConversionStorage, object[] components, int index) { const int defValue = 1; if (index >= components.Length || components[index] == null) { return(defValue); } MutableString asStr = Protocols.TryCastToString(strConversionStorage, components[index]); if (asStr != null) { string str = asStr.ConvertToString(); if (str.Length == 3) { string strLower = str.ToLowerInvariant(); int monthIndex = _Months.FindIndex(delegate(string obj) { return(obj == strLower); }); if (monthIndex != -1) { return(monthIndex + 1); } } components[index] = asStr; // fall through after modifying the array } return(GetComponent(conversionStorage, components, index, defValue, false)); }
private Regex /*!*/ TransformPattern(RubyEncoding encoding, RubyRegexOptions kc) { // We can reuse cached CLR regex if it was created for the same k-coding: if (_cachedRegex != null && kc == _cachedKCode) { return(_cachedRegex); } string pattern; if (kc != 0 || encoding == RubyEncoding.Binary) { pattern = _pattern.ToString(encoding.Encoding); } else { pattern = _pattern.ConvertToString(); } Regex result; try { result = new Regex(RegexpTransformer.Transform(pattern, _options, out _hasGAnchor), ToClrOptions(_options)); } catch (Exception e) { throw new RegexpError(e.Message); } _cachedKCode = kc; _cachedRegex = result; return(result); }
public static MutableString /*!*/ DirName(RubyClass /*!*/ self, [NotNull] MutableString /*!*/ path) { string strPath = path.ConvertToString(); string directoryName = strPath; if (IsValidPath(strPath)) { strPath = StripPathCharacters(strPath); // handle top-level UNC paths directoryName = Path.GetDirectoryName(strPath); if (directoryName == null) { return(self.Context.EncodePath(strPath)); } string fileName = Path.GetFileName(strPath); if (!String.IsNullOrEmpty(fileName)) { directoryName = StripPathCharacters(strPath.Substring(0, strPath.LastIndexOf(fileName, StringComparison.Ordinal))); } } else { if (directoryName.Length > 1) { directoryName = "//"; } } directoryName = String.IsNullOrEmpty(directoryName) ? "." : directoryName; return(self.Context.EncodePath(directoryName)); }
public static RubyArray /*!*/ ReadLines(RubyClass /*!*/ self, [DefaultProtocol, NotNull] MutableString path, [DefaultProtocol] MutableString separator) { using (RubyIO io = new RubyIO(self.Context, File.OpenRead(path.ConvertToString()), "r")) { return(ReadLines(self.Context, io, separator)); } }
// 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; try { if (path == null || length == 0) { return(Glob.CanonicalizePath(MutableString.Create(Directory.GetCurrentDirectory()))); } if (length == 1 && path.GetChar(0) == '~') { return(Glob.CanonicalizePath(MutableString.Create(Path.GetFullPath(pal.GetEnvironmentVariable("HOME"))))); } if (path.GetChar(0) == '~' && (path.GetChar(1) == Path.DirectorySeparatorChar || path.GetChar(1) == Path.AltDirectorySeparatorChar)) { string homeDirectory = pal.GetEnvironmentVariable("HOME"); return(Glob.CanonicalizePath(length < 3 ? MutableString.Create(homeDirectory) : MutableString.Create(Path.Combine(homeDirectory, path.GetSlice(2).ConvertToString())))); } else { return(Glob.CanonicalizePath(MutableString.Create(Path.GetFullPath(path.ConvertToString())))); } } catch (Exception e) { // Re-throw exception as a reasonable Ruby exception throw new Errno.InvalidError(path.ConvertToString(), e); } }
public static void ForEach(BlockParam block, RubyClass /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ path, [DefaultProtocol] MutableString separator, [DefaultProtocol, DefaultParameterValue(-1)] int limit) { using (RubyIO io = new RubyIO(self.Context, File.OpenRead(path.ConvertToString()), IOMode.ReadOnly)) { Each(self.Context, block, io, separator, limit); } }
public static MutableString /*!*/ Read(ConversionStorage <int> /*!*/ fixnumCast, RubyClass /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ path, [DefaultParameterValue(null)] object lengthObj, [DefaultParameterValue(0)] object offsetObj) { var site = fixnumCast.GetSite(ConvertToFixnumAction.Make(fixnumCast.Context)); int length = (lengthObj != null) ? site.Target(site, lengthObj) : 0; int offset = (offsetObj != null) ? site.Target(site, offsetObj) : 0; if (offset < 0) { throw RubyExceptions.CreateEINVAL(); } if (length < 0) { throw RubyExceptions.CreateArgumentError("negative length {0} given", length); } using (RubyIO io = new RubyFile(self.Context, path.ConvertToString(), IOMode.ReadOnly)) { if (offset > 0) { io.Seek(offset, SeekOrigin.Begin); } if (lengthObj == null) { return(Read(io)); } else { return(Read(io, length, null)); } } }
public static RubyArray /*!*/ ReadLines(RubyClass /*!*/ self, [DefaultProtocol, NotNull] MutableString path, [DefaultProtocol] MutableString separator, [DefaultProtocol, DefaultParameterValue(-1)] int limit) { using (RubyIO io = new RubyIO(self.Context, File.OpenRead(path.ConvertToString()), IOMode.ReadOnly)) { return(ReadLines(self.Context, io, separator, limit)); } }
private Regex /*!*/ Transform(ref RubyEncoding encoding, MutableString /*!*/ input, int start, out string strInput) { ContractUtils.RequiresNotNull(input, "input"); // K-coding of the current operation (the current KCODE gets preference over the KCODE regex option): RubyRegexOptions kc = _options & RubyRegexOptions.EncodingMask; if (kc != 0) { encoding = _pattern.Encoding; } else { kc = RubyEncoding.ToRegexOption(encoding); } // Convert input to a string. Force k-coding if necessary. if (kc != 0) { // Handling multi-byte K-coded characters is not entirely correct here. // Three cases to be considered: // 1) Multi-byte character is explicitly contained in the pattern: /�*/ // 2) Subsequent escapes form a complete character: /\342\202\254*/ or /\xe2\x82\xac*/ // 3) Subsequent escapes form an incomplete character: /[\x7f-\xff]{1,3}/ // // In the first two cases we want to "group" the byte triplet so that regex operators like *, +, ? and {n,m} operate on // the entire character, not just the last byte. We could unescape the bytes and replace them with complete Unicode characters. // Then we could encode the input using the same K-coding and we would get a match. // However, case 3) requires the opposite: to match the bytes we need to encode the input using binary encoding. // Using this encoding makes *+? operators operate on the last byte (encoded as UTF16 character). // // The right solution would require the regex engine to handle multi-byte escaped characters, which it doesn't. // // TODO: // A correct workaround would be to wrap the byte sequence that forms a character into a non-capturing group, // for example transform /\342\202\254*/ to /(?:\342\202\254)*/ and use binary encoding on both input and pattern. // For now, we just detect if there are any non-ascii character escapes. If so we use a binary encoding accomodating case 3), // but breaking cases 1 and 2. Otherwise we encode using k-coding to make case 1 match. if (HasEscapedNonAsciiBytes(_pattern)) { encoding = RubyEncoding.Binary; kc = 0; } strInput = ForceEncoding(input, encoding.Encoding, start); } else if (input.Encoding.IsKCoding) { strInput = input.ToString(BinaryEncoding.Instance); } else { _pattern.RequireCompatibleEncoding(input); input.PrepareForCharacterRead(); strInput = input.ConvertToString(); } return(TransformPattern(encoding, kc)); }
internal static string /*!*/ MakeMessage(ref MutableString message, string /*!*/ baseMessage) { Assert.NotNull(baseMessage); string result = MakeMessage(message != null ? message.ConvertToString() : null, baseMessage); message = MutableString.Create(result); return(result); }
public static string /*!*/ MakeMessage(ref MutableString message, string /*!*/ baseMessage) { Assert.NotNull(baseMessage); string result = MakeMessage(message != null ? message.ConvertToString() : null, baseMessage); message = MutableString.Create(result, message != null ? message.Encoding : RubyEncoding.UTF8); return(result); }
public static RubyIO /*!*/ Reopen(RubyIO /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ path, int mode) { Stream newStream = RubyFile.OpenFileStream(self.Context, path.ConvertToString(), (IOMode)mode); self.Context.SetStream(self.GetFileDescriptor(), newStream); self.SetStream(newStream); self.Mode = (IOMode)mode; return(self); }
public static MutableString /*!*/ Basename(RubyClass /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ path, [DefaultProtocol, NotNull, Optional] MutableString extensionFilter) { if (path.IsEmpty) { return(path); } MutableString trimmedPath = TrimTrailingSlashes(path); // Special cases of drive letters C:\\ or C:/ if (trimmedPath.Length == 2) { if (Char.IsLetter(trimmedPath.GetChar(0)) && trimmedPath.GetChar(1) == ':') { var result = (path.Length > 2 ? MutableString.Create(path.GetChar(2).ToString()) : MutableString.CreateMutable()); return(result.TaintBy(path)); } } string trimmedPathAsString = trimmedPath.ConvertToString(); if (trimmedPathAsString == "/") { return(trimmedPath); } string filename = Path.GetFileName(trimmedPath.ConvertToString()); // Handle UNC host names correctly string root = Path.GetPathRoot(trimmedPath.ConvertToString()); if (MutableString.IsNullOrEmpty(extensionFilter)) { return(MutableString.Create(trimmedPathAsString == root ? root : filename)); } string fileExtension = Path.GetExtension(filename); string basename = Path.GetFileNameWithoutExtension(filename); string strResult = WildcardExtensionMatch(fileExtension, extensionFilter.ConvertToString()) ? basename : filename; return(Glob.CanonicalizePath(MutableString.Create(strResult)).TaintBy(path)); }
private static RubyIO OpenFileForRead(RubyContext /*!*/ context, MutableString /*!*/ path) { string strPath = path.ConvertToString(); if (!File.Exists(strPath)) { throw new Errno.NoEntryError(String.Format("No such file or directory - {0}", strPath)); } return(new RubyIO(context, File.OpenRead(strPath), "r")); }
public static int MakeDirectory(object self, [NotNull] MutableString /*!*/ dirname, [Optional] object permissions) { string strDir = dirname.ConvertToString(); try { Directory.CreateDirectory(strDir); } catch (Exception ex) { throw ToRubyException(ex, strDir, DirectoryOperation.Create); } return(0); }
public static int RemoveDirectory(object self, [NotNull] MutableString /*!*/ dirname) { string strDir = dirname.ConvertToString(); try { Directory.Delete(strDir); } catch (Exception ex) { throw ToRubyException(ex, strDir, DirectoryOperation.Delete); } return(0); }
public static int Delete(RubyClass /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ path) { string strPath = path.ConvertToString(); if (!FileExists(self.Context, strPath)) { throw new Errno.NoEntryError(String.Format("No such file or directory - {0}", strPath)); } File.Delete(strPath); return(1); }
public static RubyIO /*!*/ CreateIO(RubyClass /*!*/ self, [DefaultProtocol] int fileDescriptor, [DefaultProtocol, NotNull, Optional] MutableString modeString) { // TODO: a new RubyIO should be created here RubyIO result = self.Context.GetDescriptor(fileDescriptor); if (modeString != null) { result.ResetIOMode(modeString.ConvertToString()); } return(result); }
public static MutableString /*!*/ DirName(RubyClass /*!*/ self, MutableString /*!*/ path) { string directoryName = path.ConvertToString(); if (IsValidPath(path.ConvertToString())) { directoryName = Path.GetDirectoryName(path.ConvertToString()); string fileName = Path.GetFileName(path.ConvertToString()); if (!String.IsNullOrEmpty(fileName)) { directoryName = StripPathCharacters(path.ConvertToString().Replace(fileName, "")); } } else { if (directoryName.Length > 1) { directoryName = "//"; } } return(Glob.CanonicalizePath(MutableString.Create(String.IsNullOrEmpty(directoryName) ? "." : directoryName))); }
public static object NewStruct(BlockParam block, RubyClass /*!*/ self, [DefaultProtocol] MutableString className, [DefaultProtocol, NotNullItems] params string /*!*/[] /*!*/ attributeNames) { if (className == null) { return(Create(block, self, null, attributeNames)); } string strName = className.ConvertToString(); self.Context.CheckConstantName(strName); return(Create(block, self, strName, attributeNames)); }
public static object NullableSize(RubyModule /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ path) { FileSystemInfo fsi; if (RubyFileOps.RubyStatOps.TryCreate(self.Context, path.ConvertToString(), out fsi)) { return(RubyFileOps.RubyStatOps.NullableSize(fsi)); } else { return(null); } }
public static MutableString /*!*/ GetExtension(RubyClass /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ path) { string pathStr = path.ConvertToString(); string extension = Path.GetExtension(pathStr); string filename = Path.GetFileName(pathStr); if (extension == filename) { // File.extname(".foo") should be "", but Path.GetExtension(".foo") returns ".foo" extension = String.Empty; } return(MutableString.Create(extension, path.Encoding).TaintBy(path)); }
public RubyDir([NotNull] MutableString /*!*/ dirname) { string strName = dirname.ConvertToString(); try { _rawEntries = Directory.GetFileSystemEntries(strName); } catch (Exception ex) { throw ToRubyException(ex, strName, DirectoryOperation.Open); } _dirName = MutableString.Create(NormalizePathSeparators(strName)); _closed = false; _pos = -2; }
public static int Rename(RubyContext /*!*/ context, RubyClass /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ oldPath, [DefaultProtocol, NotNull] MutableString /*!*/ newPath) { string strOldPath = oldPath.ConvertToString(); if (!FileExists(context, strOldPath) && !DirectoryExists(context, strOldPath)) { throw new Errno.NoEntryError(String.Format("No such file or directory - {0}", oldPath)); } // TODO: Change to raise a SystemCallError instead of a native CLR error File.Move(strOldPath, newPath.ToString()); return(0); }
public static MutableString Index(RubyContext /*!*/ context, object /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ value) { string strValue = value.ConvertToString(); PlatformAdaptationLayer pal = context.DomainManager.Platform; foreach (DictionaryEntry entry in pal.GetEnvironmentVariables()) { if (strValue.Equals(entry.Value)) { return(FrozenString(context, entry.Key)); } } return(null); }
public static int UpdateTimes(RubyClass /*!*/ self, DateTime accessTime, DateTime modifiedTime, [NotNull] MutableString /*!*/ path) { string strPath = path.ConvertToString(); if (!FileExists(self.Context, strPath)) { throw new Errno.NoEntryError(String.Format("No such file or directory - {0}", strPath)); } FileInfo info = new FileInfo(strPath); info.LastAccessTime = accessTime; info.LastWriteTime = modifiedTime; return(1); }
public static object NewStruct(BlockParam block, RubyClass /*!*/ self, [DefaultProtocol, Optional] MutableString className, [NotNull] params object[] /*!*/ attributeNames) { string[] symbols = Protocols.CastToSymbols(self.Context, attributeNames); if (className == null) { return(Create(block, self, null, symbols)); } string strName = className.ConvertToString(); RubyUtils.CheckConstantName(strName); return(Create(block, self, strName, symbols)); }
public static bool IsZeroLength(RubyClass /*!*/ self, [DefaultProtocol, NotNull] MutableString /*!*/ path) { string strPath = path.ConvertToString(); // NUL/nul is a special-cased filename on Windows if (strPath.ToLower() == "nul") { return(RubyStatOps.IsZeroLength(RubyStatOps.Create(self.Context, strPath))); } if (DirectoryExists(self.Context, strPath) || !FileExists(self.Context, strPath)) { return(false); } return(RubyStatOps.IsZeroLength(RubyStatOps.Create(self.Context, strPath))); }