Esempio n. 1
0
        public static List <LogInfo> TXTAddLineOp(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>(8);

            CodeInfo_TXTAddLineOp infoOp = cmd.Info.Cast <CodeInfo_TXTAddLineOp>();

            CodeInfo_TXTAddLine firstInfo = infoOp.Infos[0];
            string         fileName       = StringEscaper.Preprocess(s, firstInfo.FileName);
            string         modeStr        = StringEscaper.Preprocess(s, firstInfo.Mode);
            TXTAddLineMode mode;

            if (modeStr.Equals("Append", StringComparison.OrdinalIgnoreCase))
            {
                mode = TXTAddLineMode.Append;
            }
            else if (modeStr.Equals("Prepend", StringComparison.OrdinalIgnoreCase))
            {
                mode = TXTAddLineMode.Prepend;
            }
            else
            {
                throw new ExecuteException($"Mode [{modeStr}] must be one of [Append, Prepend]");
            }

            if (!StringEscaper.PathSecurityCheck(fileName, out string errorMsg))
            {
                return(LogInfo.LogErrorMessage(logs, errorMsg));
            }

            // Detect encoding of text. If text does not exists, create blank file (ANSI)
            Encoding encoding;

            if (File.Exists(fileName))
            {
                encoding = EncodingHelper.SmartDetectEncoding(fileName, infoOp.Infos.Select(x => x.Line));
            }
            else
            {
                encoding = EncodingHelper.DefaultAnsi;
            }

            string linesToWrite;

            if (mode == TXTAddLineMode.Prepend)
            {
                string tempPath = FileHelper.GetTempFile();
                using (StreamReader r = new StreamReader(fileName, encoding, false))
                    using (StreamWriter w = new StreamWriter(tempPath, false, encoding))
                    {
                        StringBuilder b = new StringBuilder();
                        List <CodeInfo_TXTAddLine> infos = infoOp.Infos;
                        infos.Reverse();
                        foreach (CodeInfo_TXTAddLine subInfo in infos)
                        {
                            b.AppendLine(StringEscaper.Preprocess(s, subInfo.Line));
                        }
                        linesToWrite = b.ToString();

                        w.Write(linesToWrite);
                        w.Write(r.ReadToEnd());
                    }
                FileHelper.FileReplaceEx(tempPath, fileName);

                logs.Add(new LogInfo(LogState.Success, $"Lines prepended to [{fileName}] : \r\n{linesToWrite}", cmd));
            }
            else if (mode == TXTAddLineMode.Append)
            {
                StringBuilder b = new StringBuilder();
                foreach (CodeInfo_TXTAddLine subInfo in infoOp.Infos)
                {
                    b.AppendLine(StringEscaper.Preprocess(s, subInfo.Line));
                }

                linesToWrite = b.ToString();

                bool newLineExist = true;
                if (File.Exists(fileName))
                {
                    using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        long   bomLen   = EncodingHelper.TextBomLength(fs);
                        byte[] lastChar = new byte[2];
                        if (2 + bomLen <= fs.Length)
                        {
                            fs.Position = fs.Length - 2;
                            fs.Read(lastChar, 0, 2);
                            if (lastChar[0] != '\r' || lastChar[1] != '\n')
                            {
                                newLineExist = false;
                            }
                        }
                    }
                }

                if (newLineExist)
                {
                    File.AppendAllText(fileName, linesToWrite, encoding);
                }
                else
                {
                    File.AppendAllText(fileName, "\r\n" + linesToWrite, encoding);
                }

                logs.Add(new LogInfo(LogState.Success, $"Lines appended to [{fileName}] : \r\n{linesToWrite}", cmd));
            }
            else
            {
                throw new InvalidOperationException("Internal Logic Error at TXTAddLine");
            }

            return(logs);
        }
Esempio n. 2
0
        public static List <LogInfo> TXTAddLineOp(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

            Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_TXTAddLineOp));
            CodeInfo_TXTAddLineOp infoOp = cmd.Info as CodeInfo_TXTAddLineOp;

            string         fileName = StringEscaper.Preprocess(s, infoOp.InfoList[0].FileName);
            string         modeStr  = StringEscaper.Preprocess(s, infoOp.InfoList[0].Mode);
            TXTAddLineMode mode;

            if (modeStr.Equals("Append", StringComparison.OrdinalIgnoreCase))
            {
                mode = TXTAddLineMode.Append;
            }
            else if (modeStr.Equals("Prepend", StringComparison.OrdinalIgnoreCase))
            {
                mode = TXTAddLineMode.Prepend;
            }
            else
            {
                throw new ExecuteException($"Mode [{modeStr}] must be one of [Append, Prepend]");
            }

            if (StringEscaper.PathSecurityCheck(fileName, out string errorMsg) == false)
            {
                logs.Add(new LogInfo(LogState.Error, errorMsg));
                return(logs);
            }

            // Detect encoding of text
            // If text does not exists, create blank file
            Encoding encoding = Encoding.Default;

            if (File.Exists(fileName))
            {
                encoding = FileHelper.DetectTextEncoding(fileName);
            }

            string linesToWrite;

            if (mode == TXTAddLineMode.Prepend)
            {
                string tempPath = Path.GetTempFileName();
                using (StreamReader reader = new StreamReader(fileName, encoding))
                    using (StreamWriter writer = new StreamWriter(tempPath, false, encoding))
                    {
                        StringBuilder b = new StringBuilder();
                        for (int i = infoOp.InfoList.Count - 1; 0 <= i; i--)
                        {
                            b.AppendLine(StringEscaper.Preprocess(s, infoOp.InfoList[i].Line));
                        }
                        linesToWrite = b.ToString();

                        writer.Write(linesToWrite);
                        writer.Write(reader.ReadToEnd());
                    }
                FileHelper.FileReplaceEx(tempPath, fileName);

                logs.Add(new LogInfo(LogState.Success, $"Lines prepened to [{fileName}] : \r\n{linesToWrite}", cmd));
            }
            else if (mode == TXTAddLineMode.Append)
            {
                StringBuilder b = new StringBuilder();
                for (int i = 0; i < infoOp.InfoList.Count; i++)
                {
                    b.AppendLine(StringEscaper.Preprocess(s, infoOp.InfoList[i].Line));
                }
                linesToWrite = b.ToString();

                bool newLineExist = true;
                if (File.Exists(fileName))
                {
                    using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        long   bomLen   = FileHelper.TextBOMLength(fs);
                        byte[] lastChar = new byte[2];
                        if (2 + bomLen <= fs.Length)
                        {
                            fs.Position = fs.Length - 2;
                            fs.Read(lastChar, 0, 2);
                            if (lastChar[0] != '\r' || lastChar[1] != '\n')
                            {
                                newLineExist = false;
                            }
                        }
                    }
                }

                if (newLineExist)
                {
                    File.AppendAllText(fileName, linesToWrite, encoding);
                }
                else
                {
                    File.AppendAllText(fileName, "\r\n" + linesToWrite, encoding);
                }

                logs.Add(new LogInfo(LogState.Success, $"Lines appended to [{fileName}] : \r\n{linesToWrite}", cmd));
            }

            return(logs);
        }
Esempio n. 3
0
        private static CodeCommand PackCommand(CodeType type, List <CodeCommand> cmds)
        {
            Debug.Assert(0 < cmds.Count);

            CodeType packType;
            CodeInfo packInfo;

            switch (type)
            {
            case CodeType.TXTAddLine:
                packType = CodeType.TXTAddLineOp;
                packInfo = new CodeInfo_TXTAddLineOp(cmds);
                break;

            case CodeType.TXTReplace:
                packType = CodeType.TXTReplaceOp;
                packInfo = new CodeInfo_TXTReplaceOp(cmds);
                break;

            case CodeType.TXTDelLine:
                packType = CodeType.TXTDelLineOp;
                packInfo = new CodeInfo_TXTDelLineOp(cmds);
                break;

            case CodeType.IniRead:
                packType = CodeType.IniReadOp;
                packInfo = new CodeInfo_IniReadOp(cmds);
                break;

            case CodeType.IniWrite:
                packType = CodeType.IniWriteOp;
                packInfo = new CodeInfo_IniWriteOp(cmds);
                break;

            case CodeType.IniDelete:
                packType = CodeType.IniDeleteOp;
                packInfo = new CodeInfo_IniDeleteOp(cmds);
                break;

            case CodeType.IniReadSection:
                packType = CodeType.IniReadSectionOp;
                packInfo = new CodeInfo_IniReadSectionOp(cmds);
                break;

            case CodeType.IniAddSection:
                packType = CodeType.IniAddSectionOp;
                packInfo = new CodeInfo_IniAddSectionOp(cmds);
                break;

            case CodeType.IniDeleteSection:
                packType = CodeType.IniDeleteSectionOp;
                packInfo = new CodeInfo_IniDeleteSectionOp(cmds);
                break;

            case CodeType.IniWriteTextLine:
                packType = CodeType.IniWriteTextLineOp;
                packInfo = new CodeInfo_IniWriteTextLineOp(cmds);
                break;

            case CodeType.Visible:
                packType = CodeType.VisibleOp;
                packInfo = new CodeInfo_VisibleOp(cmds);
                break;

            case CodeType.ReadInterface:
                packType = CodeType.ReadInterfaceOp;
                packInfo = new CodeInfo_ReadInterfaceOp(cmds);
                break;

            case CodeType.WriteInterface:
                packType = CodeType.WriteInterfaceOp;
                packInfo = new CodeInfo_WriteInterfaceOp(cmds);
                break;

            case CodeType.WimExtract:
                packType = CodeType.WimExtractOp;
                packInfo = new CodeInfo_WimExtractOp(cmds);
                break;

            case CodeType.WimPathAdd:     // Use WimPathAdd as representative of WimPath*
                packType = CodeType.WimPathOp;
                packInfo = new CodeInfo_WimPathOp(cmds);
                break;

            default:
                throw new InternalException("Internal Logic Error at CodeOptimizer.InternalOptimize");
            }

            return(new CodeCommand(MergeRawCodes(cmds), cmds[0].Section, packType, packInfo, cmds[0].LineIdx));
        }