Exemple #1
0
        /// <summary>
        /// Decompresses data. Uses <see cref="BrotliDecoder"/>.
        /// </summary>
        /// <returns>Decompressed data.</returns>
        /// <param name="compressed">Compressed data.</param>
        /// <exception cref="ArgumentException">Invalid data.</exception>
        /// <exception cref="OutOfMemoryException"></exception>
        public static unsafe byte[] BrotliDecompress(ReadOnlySpan <byte> compressed)
        {
            int n = checked (compressed.Length * 4 + 8000);

            for (int i = 0; i < 3; i++)
            {
                if (n < 512_000)
                {
                    n *= 2;
                }
            }
            //print.it(compressed.Length, n, n/compressed.Length); //usually ~ 80 KB
            for (; ; n = checked (n * 2))
            {
                byte *b = null;
                try {
                    b = MemoryUtil.Alloc(n);
                    if (BrotliDecoder.TryDecompress(compressed, new(b, n), out int nw))
                    {
                        return(new Span <byte>(b, nw).ToArray());
                    }
                    if (nw == 0)
                    {
                        throw new ArgumentException("cannot decompress this data");
                    }
                    //print.it(n);
                }
                finally { MemoryUtil.Free(b); }
            }
        }
Exemple #2
0
        string                 _exe; //for errors only

        /// <summary>
        /// Prepares parameters for API <msdn>CreateProcess</msdn> and similar.
        /// </summary>
        /// <param name="exe">
        /// Full path of program file. If not full path, uses <see cref="folders.ThisApp"/>. Uses <see cref="pathname.normalize"/>.
        /// If <i>rawExe</i> true, does not use <b>Normalize</b>/<b>ThisApp</b>.
        /// </param>
        /// <param name="args">null or command line arguments.</param>
        /// <param name="curDir">
        /// Initial current directory of the new process.
        /// - If null, uses <c>Directory.GetCurrentDirectory()</c>.
        /// - Else if <i>rawCurDir</i>==true, uses raw <i>curDir</i> value.
        /// - Else if "", calls <c>pathname.getDirectory(exe)</c>.
        /// - Else calls <see cref="pathname.expand"/>.
        /// </param>
        /// <param name="envVar">null or environment variables to pass to the new process together with variables of this process. Format: "var1=value1\0var2=value2\0". If ends with "\0\0", will pass only these variables.</param>
        /// <param name="rawExe">Don't normalize <i>exe</i>.</param>
        /// <param name="rawCurDir">Don't normalize <i>curDir</i>.</param>
        public ProcessStarter_(string exe, string args = null, string curDir = null, string envVar = null, bool rawExe = false, bool rawCurDir = false) : this()
        {
            if (!rawExe)
            {
                exe = pathname.normalize(exe, folders.ThisApp, PNFlags.DontExpandDosPath | PNFlags.DontPrefixLongPath);
            }
            _exe = exe;
            cl   = (args == null ? ("\"" + exe + "\"" + "\0") : ("\"" + exe + "\" " + args + "\0")).ToCharArray();
            if (curDir == null)
            {
                this.curDir = Directory.GetCurrentDirectory();                             //if null passed to CreateProcessWithTokenW, the new process does not inherit current directory of this process
            }
            else
            {
                this.curDir = rawCurDir ? curDir : (curDir.Length == 0 ? pathname.getDirectory(exe) : pathname.expand(curDir));
            }

            si.cb      = Api.SizeOf <Api.STARTUPINFO>();
            si.dwFlags = Api.STARTF_FORCEOFFFEEDBACK;

            flags = Api.CREATE_UNICODE_ENVIRONMENT;

            if (envVar != null && !envVar.Ends("\0\0"))
            {
                var es = Api.GetEnvironmentStrings();
                int len1; for (var k = es; ; k++)
                {
                    if (k[0] == 0 && k[1] == 0)
                    {
                        len1 = (int)(k - es) + 2; break;
                    }
                }
                int len2 = envVar.Length;
                var t    = new string('\0', len1 + len2);
                fixed(char *p = t)
                {
                    MemoryUtil.Copy(es, p, --len1 * 2);
                    for (int i = 0; i < envVar.Length; i++)
                    {
                        p[len1 + i] = envVar[i];
                    }
                }

                this.envVar = t;
                Api.FreeEnvironmentStrings(es);
            }
            else
            {
                this.envVar = null;
            }
        }
Exemple #3
0
        /// <summary>
        /// Compresses data. Uses <see cref="BrotliEncoder"/>.
        /// </summary>
        /// <param name="data">Data. See also: <see cref="MemoryMarshal.AsBytes"/>, <see cref="CollectionsMarshal.AsSpan"/>.</param>
        /// <param name="level">Compression level, 0 (no compression) to 11 (maximal compression). Default 6. Bigger levels don't make much smaller but can make much slower.</param>
        /// <exception cref="ArgumentOutOfRangeException">Invalid <i>level</i>.</exception>
        /// <exception cref="OutOfMemoryException"></exception>
        public static unsafe byte[] BrotliCompress(ReadOnlySpan <byte> data, int level = 6)
        {
            int n = BrotliEncoder.GetMaxCompressedLength(data.Length);
            var b = MemoryUtil.Alloc(n);

            try {
                if (!BrotliEncoder.TryCompress(data, new(b, n), out n, level, 22))
                {
                    throw new AuException();
                }
                return(new Span <byte>(b, n).ToArray());
            }
            finally { MemoryUtil.Free(b); }
        }