Esempio n. 1
0
        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()));
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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));
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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));
        }
Esempio n. 6
0
 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));
     }
 }
Esempio n. 7
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;

            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);
            }
        }
Esempio n. 8
0
 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);
     }
 }
Esempio n. 9
0
        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));
                }
            }
        }
Esempio n. 10
0
 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));
     }
 }
Esempio n. 11
0
        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));
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
        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);
        }
Esempio n. 15
0
        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));
        }
Esempio n. 16
0
        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"));
        }
Esempio n. 17
0
        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);
        }
Esempio n. 18
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);
        }
Esempio n. 19
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);
        }
Esempio n. 20
0
        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);
        }
Esempio n. 21
0
        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)));
        }
Esempio n. 22
0
        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));
        }
Esempio n. 23
0
        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);
            }
        }
Esempio n. 24
0
        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));
        }
Esempio n. 25
0
        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;
        }
Esempio n. 26
0
        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);
        }
Esempio n. 27
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);
        }
Esempio n. 28
0
        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);
        }
Esempio n. 29
0
        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));
        }
Esempio n. 30
0
        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)));
        }