<commit_before>﻿/*----------------------------------------------------------
This Source Code Form is subject to the terms of the 
Mozilla Public License, v.2.0. If a copy of the MPL 
was not distributed with this file, You can obtain one 
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ScriptEngine.Machine;
using ScriptEngine.Machine.Contexts;
using System.Diagnostics;

namespace ScriptEngine.HostedScript.Library
{
    /// <summary>
    /// Позволяет управлять процессом операционной системы. Получать текст из стандартных потоков,
    /// проверять активность, pid, завершать процесс и т.п.
    /// </summary>
    [ContextClass("Процесс", "Process")]
    public class ProcessContext : AutoContext<ProcessContext>, IDisposable
    {
        private readonly System.Diagnostics.Process _p;
        private StdTextReadStream _stdOutContext;
        private StdTextReadStream _stdErrContext;
        private StdTextWriteStream _stdInContext;

        private readonly IValue _outputEncoding;

        private ProcessContext(System.Diagnostics.Process p, IValue encoding)
        {
            _p = p;
            _outputEncoding = encoding;
        }

        public ProcessContext(System.Diagnostics.Process p):this(p, ValueFactory.Create())
        {
        }

        /// <summary>
        /// Устанавливает кодировку в которой будут считываться стандартные потоки вывода и ошибок.
        /// </summary>
        [ContextProperty("КодировкаВывода", "OutputEncoding")]
        public IValue OutputEncoding
        {
            get
            {
                return _outputEncoding;
            }
        }

        /// <summary>
        /// ПотокВыводаТекста. Стандартный поток вывода (stdout)
        ///     в методе "Завершен" смотрите пример правильной обработки цикла ожидания завершения процесса:
        /// </summary>
        [ContextProperty("ПотокВывода", "StdOut")]
        public StdTextReadStream StdOut
        {
            get
            {
                if (_stdOutContext == null)
                {
                    var stream = new ProcessOutputWrapper(_p, ProcessOutputWrapper.OutputVariant.Stdout);
                    stream.StartReading();

                    _stdOutContext = new StdTextReadStream(stream);
                }
                return _stdOutContext;
            }
        }

        /// <summary>
        /// ПотокВыводаТекста. Стандартный поток вывода ошибок (stderr)
        ///     в методе "Завершен" смотрите пример правильной обработки цикла ожидания завершения процесса:
        /// </summary>
        [ContextProperty("ПотокОшибок", "StdErr")]
        public StdTextReadStream StdErr
        {
            get
            {
                if (_stdErrContext == null)
                {
                    var stream = new ProcessOutputWrapper(_p, ProcessOutputWrapper.OutputVariant.Stderr);
                    stream.StartReading();

                    _stdErrContext = new StdTextReadStream(stream);
                }
                return _stdErrContext;
            }
        }

        /// <summary>
        /// ПотокВводаТекста. Стандартный поток ввода (stdin)
        /// </summary>
        [ContextProperty("ПотокВвода", "StdIn")]
        public StdTextWriteStream StdIn
        {
            get
            {
                if (_stdInContext == null)
                    _stdInContext = new StdTextWriteStream(_p.StandardInput);
                return _stdInContext;
            }
        }

        /// <summary>
        /// Запустить процесс на выполнение.
        ///     в методе "Завершен" смотрите пример правильной обработки цикла ожидания завершения процесса:
        /// </summary>
        [ContextMethod("Запустить", "Start")]
        public void Start()
        {
            _p.Start();
        }

        /// <summary>
        /// Флаг указывает, что процесс завершен (или нет)
        /// </summary>
        ///
        /// <example>
        /// Пример правильной обработки цикла ожидания завершения процесса:
        ///     Процесс не завершается, пока любоой из потоков (stdout, stderr) открыт для чтения.
        ///     Процесс висит и ждет, пока его освободят от текста в обоих потоках.
        ///
        /// Пока НЕ Процесс.Завершен ИЛИ Процесс.ПотокВывода.ЕстьДанные ИЛИ Процесс.ПотокОшибок.ЕстьДанные Цикл
        /// 	    Если ПериодОпросаВМиллисекундах <> 0 Тогда
        /// 	    	Приостановить(ПериодОпросаВМиллисекундах);
        /// 	    КонецЕсли;
        ///    
        /// 	    ОчереднаяСтрокаВывода = Процесс.ПотокВывода.Прочитать();
        /// 	    ОчереднаяСтрокаОшибок = Процесс.ПотокОшибок.Прочитать();
        /// 	    Если Не ПустаяСтрока(ОчереднаяСтрокаВывода) Тогда
        /// 	    	Сообщить(ОчереднаяСтрокаВывода, СтатусСообщения.Информация);
        /// 	    КонецЕсли;
        ///    
        /// 	    Если Не ПустаяСтрока(ОчереднаяСтрокаОшибок) Тогда
        /// 	    	Сообщить(ОчереднаяСтрокаОшибок, СтатусСообщения.Важное);
        /// 	    КонецЕсли;
        ///  КонецЦикла;        
        /// </example>
        [ContextProperty("Завершен","HasExited")]
        public bool HasExited
        {
            get
            {
                return _p.HasExited;
            }
        }
<commit_msg>fixed #417<commit_after>﻿/*----------------------------------------------------------
This Source Code Form is subject to the terms of the 
Mozilla Public License, v.2.0. If a copy of the MPL 
was not distributed with this file, You can obtain one 
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ScriptEngine.Machine;
using ScriptEngine.Machine.Contexts;
using System.Diagnostics;

namespace ScriptEngine.HostedScript.Library
{
    /// <summary>
    /// Позволяет управлять процессом операционной системы. Получать текст из стандартных потоков,
    /// проверять активность, pid, завершать процесс и т.п.
    /// </summary>
    [ContextClass("Процесс", "Process")]
    public class ProcessContext : AutoContext<ProcessContext>, IDisposable
    {
        private readonly System.Diagnostics.Process _p;
        private StdTextReadStream _stdOutContext;
        private StdTextReadStream _stdErrContext;
        private StdTextWriteStream _stdInContext;

        private readonly IValue _outputEncoding;

        private ProcessContext(System.Diagnostics.Process p, IValue encoding)
        {
            _p = p;
            _outputEncoding = encoding;
        }

        public ProcessContext(System.Diagnostics.Process p):this(p, ValueFactory.Create())
        {
        }

        /// <summary>
        /// Устанавливает кодировку в которой будут считываться стандартные потоки вывода и ошибок.
        /// </summary>
        [ContextProperty("КодировкаВывода", "OutputEncoding")]
        public IValue OutputEncoding
        {
            get
            {
                return _outputEncoding;
            }
        }

        /// <summary>
        /// ПотокВыводаТекста. Стандартный поток вывода (stdout)
        ///     в методе "Завершен" смотрите пример правильной обработки цикла ожидания завершения процесса:
        /// </summary>
        [ContextProperty("ПотокВывода", "StdOut")]
        public StdTextReadStream StdOut
        {
            get
            {
                if (_stdOutContext == null)
                {
                    var stream = new ProcessOutputWrapper(_p, ProcessOutputWrapper.OutputVariant.Stdout);
                    stream.StartReading();

                    _stdOutContext = new StdTextReadStream(stream);
                }
                return _stdOutContext;
            }
        }

        /// <summary>
        /// ПотокВыводаТекста. Стандартный поток вывода ошибок (stderr)
        ///     в методе "Завершен" смотрите пример правильной обработки цикла ожидания завершения процесса:
        /// </summary>
        [ContextProperty("ПотокОшибок", "StdErr")]
        public StdTextReadStream StdErr
        {
            get
            {
                if (_stdErrContext == null)
                {
                    var stream = new ProcessOutputWrapper(_p, ProcessOutputWrapper.OutputVariant.Stderr);
                    stream.StartReading();

                    _stdErrContext = new StdTextReadStream(stream);
                }
                return _stdErrContext;
            }
        }

        /// <summary>
        /// ПотокВводаТекста. Стандартный поток ввода (stdin)
        /// </summary>
        [ContextProperty("ПотокВвода", "StdIn")]
        public StdTextWriteStream StdIn
        {
            get
            {
                if (_stdInContext == null)
                    _stdInContext = new StdTextWriteStream(_p.StandardInput);
                return _stdInContext;
            }
        }

        /// <summary>
        /// Запустить процесс на выполнение.
        ///     в методе "Завершен" смотрите пример правильной обработки цикла ожидания завершения процесса:
        /// </summary>
        [ContextMethod("Запустить", "Start")]
        public void Start()
        {
            _p.Start();
        }

        /// <summary>
        /// Флаг указывает, что процесс завершен (или нет)
        /// </summary>
        ///
        /// <example>
        /// Пример правильной обработки цикла ожидания завершения процесса:
        ///     Процесс не завершается, пока любой из потоков (stdout, stderr) открыт для чтения.
        ///     Процесс висит и ждет, пока его освободят от текста в обоих потоках.
        ///
        /// Пока НЕ Процесс.Завершен ИЛИ Процесс.ПотокВывода.ЕстьДанные ИЛИ Процесс.ПотокОшибок.ЕстьДанные Цикл
        /// 	    Если ПериодОпросаВМиллисекундах &lt;&gt; 0 Тогда
        /// 	    	Приостановить(ПериодОпросаВМиллисекундах);
        /// 	    КонецЕсли;
        ///    
        /// 	    ОчереднаяСтрокаВывода = Процесс.ПотокВывода.Прочитать();
        /// 	    ОчереднаяСтрокаОшибок = Процесс.ПотокОшибок.Прочитать();
        /// 	    Если Не ПустаяСтрока(ОчереднаяСтрокаВывода) Тогда
        /// 	    	Сообщить(ОчереднаяСтрокаВывода, СтатусСообщения.Информация);
        /// 	    КонецЕсли;
        ///    
        /// 	    Если Не ПустаяСтрока(ОчереднаяСтрокаОшибок) Тогда
        /// 	    	Сообщить(ОчереднаяСтрокаОшибок, СтатусСообщения.Важное);
        /// 	    КонецЕсли;
        ///  КонецЦикла;        
        /// </example>
        [ContextProperty("Завершен","HasExited")]
        public bool HasExited
        {
            get
            {
                return _p.HasExited;
            }
        }

{'fraction_non_alphanumeric': 0.11172195303764443, 'fraction_numerical': 0.0012113306000745435, 'mean_word_length': 1.6050970873786408, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7317268', 'n_tokens_mistral': 3343, 'n_tokens_neox': 3619, 'n_words': 662}