bool ParseString(string srcString, SwitchForm[] switchForms)
        {
            int len = srcString.Length;

            if (len == 0)
            {
                return(false);
            }
            int pos = 0;

            if (!IsItSwitchChar(srcString[pos]))
            {
                return(false);
            }
            while (pos < len)
            {
                if (IsItSwitchChar(srcString[pos]))
                {
                    pos++;
                }
                const int kNoLen             = -1;
                int       matchedSwitchIndex = 0;
                int       maxLen             = kNoLen;
                for (int switchIndex = 0; switchIndex < _switches.Length; switchIndex++)
                {
                    int switchLen = switchForms[switchIndex].IDString.Length;
                    if (switchLen <= maxLen || pos + switchLen > len)
                    {
                        continue;
                    }
                    if (String.Compare(switchForms[switchIndex].IDString, 0,
                                       srcString, pos, switchLen, true) == 0)
                    {
                        matchedSwitchIndex = switchIndex;
                        maxLen             = switchLen;
                    }
                }
                if (maxLen == kNoLen)
                {
                    throw new Exception("maxLen == kNoLen");
                }
                SwitchResult matchedSwitch = _switches[matchedSwitchIndex];
                SwitchForm   switchForm    = switchForms[matchedSwitchIndex];
                if ((!switchForm.Multi) && matchedSwitch.ThereIs)
                {
                    throw new Exception("switch must be single");
                }
                matchedSwitch.ThereIs = true;
                pos += maxLen;
                int        tailSize = len - pos;
                SwitchType type     = switchForm.Type;
                switch (type)
                {
                case SwitchType.PostMinus:
                {
                    if (tailSize == 0)
                    {
                        matchedSwitch.WithMinus = false;
                    }
                    else
                    {
                        matchedSwitch.WithMinus = (srcString[pos] == kSwitchMinus);
                        if (matchedSwitch.WithMinus)
                        {
                            pos++;
                        }
                    }
                    break;
                }

                case SwitchType.PostChar:
                {
                    if (tailSize < switchForm.MinLen)
                    {
                        throw new Exception("switch is not full");
                    }
                    string    charSet         = switchForm.PostCharSet;
                    const int kEmptyCharValue = -1;
                    if (tailSize == 0)
                    {
                        matchedSwitch.PostCharIndex = kEmptyCharValue;
                    }
                    else
                    {
                        int index = charSet.IndexOf(srcString[pos]);
                        if (index < 0)
                        {
                            matchedSwitch.PostCharIndex = kEmptyCharValue;
                        }
                        else
                        {
                            matchedSwitch.PostCharIndex = index;
                            pos++;
                        }
                    }
                    break;
                }

                case SwitchType.LimitedPostString:
                case SwitchType.UnLimitedPostString:
                {
                    int minLen = switchForm.MinLen;
                    if (tailSize < minLen)
                    {
                        throw new Exception("switch is not full");
                    }
                    if (type == SwitchType.UnLimitedPostString)
                    {
                        matchedSwitch.PostStrings.Add(srcString.Substring(pos));
                        return(true);
                    }
                    String stringSwitch = srcString.Substring(pos, minLen);
                    pos += minLen;
                    for (int i = minLen; i < switchForm.MaxLen && pos < len; i++, pos++)
                    {
                        char c = srcString[pos];
                        if (IsItSwitchChar(c))
                        {
                            break;
                        }
                        stringSwitch += c;
                    }
                    matchedSwitch.PostStrings.Add(stringSwitch);
                    break;
                }
                }
            }
            return(true);
        }
        bool ParseString(string srcString, SwitchForm[] switchForms)
        {
            int len = srcString.Length;
            if (len == 0)
                return false;
            int pos = 0;
            if (!IsItSwitchChar(srcString[pos]))
                return false;
            while (pos < len)
            {
                if (IsItSwitchChar(srcString[pos]))
                    pos++;
                const int kNoLen = -1;
                int matchedSwitchIndex = 0;
                int maxLen = kNoLen;
                for (int switchIndex = 0; switchIndex < _switches.Length; switchIndex++)
                {
                    int switchLen = switchForms[switchIndex].IDString.Length;
                    if (switchLen <= maxLen || pos + switchLen > len)
                        continue;
                    if (String.Compare(switchForms[switchIndex].IDString, 0,
                                       srcString, pos, switchLen, true) == 0)
                    {
                        matchedSwitchIndex = switchIndex;
                        maxLen = switchLen;
                    }
                }
                if (maxLen == kNoLen)
                    throw new Exception("maxLen == kNoLen");
                SwitchResult matchedSwitch = _switches[matchedSwitchIndex];
                SwitchForm switchForm = switchForms[matchedSwitchIndex];
                if ((!switchForm.Multi) && matchedSwitch.ThereIs)
                    throw new Exception("switch must be single");
                matchedSwitch.ThereIs = true;
                pos += maxLen;
                int tailSize = len - pos;
                SwitchType type = switchForm.Type;
                switch (type)
                {
                    case SwitchType.PostMinus:
                        {
                            if (tailSize == 0)
                                matchedSwitch.WithMinus = false;
                            else
                            {
                                matchedSwitch.WithMinus = (srcString[pos] == kSwitchMinus);
                                if (matchedSwitch.WithMinus)
                                    pos++;
                            }
                            break;
                        }
                    case SwitchType.PostChar:
                        {
                            if (tailSize < switchForm.MinLen)
                                throw new Exception("switch is not full");
                            string charSet = switchForm.PostCharSet;
                            const int kEmptyCharValue = -1;
                            if (tailSize == 0)
                                matchedSwitch.PostCharIndex = kEmptyCharValue;
                            else
                            {
                                int index = charSet.IndexOf(srcString[pos]);
                                if (index < 0)
                                    matchedSwitch.PostCharIndex = kEmptyCharValue;
                                else
                                {
                                    matchedSwitch.PostCharIndex = index;
                                    pos++;
                                }
                            }
                            break;
                        }
                    case SwitchType.LimitedPostString:
                    case SwitchType.UnLimitedPostString:
                        {
                            int minLen = switchForm.MinLen;
                            if (tailSize < minLen)
                                throw new Exception("switch is not full");
                            if (type == SwitchType.UnLimitedPostString)
                            {
                                matchedSwitch.PostStrings.Add(srcString.Substring(pos));
                                return true;
                            }
                            String stringSwitch = srcString.Substring(pos, minLen);
                            pos += minLen;
                            for (int i = minLen; i < switchForm.MaxLen && pos < len; i++, pos++)
                            {
                                char c = srcString[pos];
                                if (IsItSwitchChar(c))
                                    break;
                                stringSwitch += c;
                            }
                            matchedSwitch.PostStrings.Add(stringSwitch);
                            break;
                        }
                }
            }
            return true;

        }
Ejemplo n.º 3
0
        static int Main2(string[] args)
        {
            System.Console.WriteLine("\nLZMA# 4.49 Copyright (c) 1999-2007 Igor Pavlov  2006-07-05\n");

            if (args.Length == 0)
            {
                PrintHelp();
                return 0;
            }

            SwitchForm[] kSwitchForms = new SwitchForm[13];
            int sw = 0;
            kSwitchForms[sw++] = new SwitchForm("?", SwitchType.Simple, false);
            kSwitchForms[sw++] = new SwitchForm("H", SwitchType.Simple, false);
            kSwitchForms[sw++] = new SwitchForm("A", SwitchType.UnLimitedPostString, false, 1);
            kSwitchForms[sw++] = new SwitchForm("D", SwitchType.UnLimitedPostString, false, 1);
            kSwitchForms[sw++] = new SwitchForm("FB", SwitchType.UnLimitedPostString, false, 1);
            kSwitchForms[sw++] = new SwitchForm("LC", SwitchType.UnLimitedPostString, false, 1);
            kSwitchForms[sw++] = new SwitchForm("LP", SwitchType.UnLimitedPostString, false, 1);
            kSwitchForms[sw++] = new SwitchForm("PB", SwitchType.UnLimitedPostString, false, 1);
            kSwitchForms[sw++] = new SwitchForm("MF", SwitchType.UnLimitedPostString, false, 1);
            kSwitchForms[sw++] = new SwitchForm("EOS", SwitchType.Simple, false);
            kSwitchForms[sw++] = new SwitchForm("SI", SwitchType.Simple, false);
            kSwitchForms[sw++] = new SwitchForm("SO", SwitchType.Simple, false);
            kSwitchForms[sw++] = new SwitchForm("T", SwitchType.UnLimitedPostString, false, 1);


            Parser parser = new Parser(sw);
            try
            {
                parser.ParseStrings(kSwitchForms, args);
            }
            catch
            {
                return IncorrectCommand();
            }

            if (parser[(int)Key.Help1].ThereIs || parser[(int)Key.Help2].ThereIs)
            {
                PrintHelp();
                return 0;
            }

            System.Collections.ArrayList nonSwitchStrings = parser.NonSwitchStrings;

            int paramIndex = 0;
            if (paramIndex >= nonSwitchStrings.Count)
                return IncorrectCommand();
            string command = (string)nonSwitchStrings[paramIndex++];
            command = command.ToLower();

            bool dictionaryIsDefined = false;
            Int32 dictionary = 1 << 21;
            if (parser[(int)Key.Dictionary].ThereIs)
            {
                Int32 dicLog;
                if (!GetNumber((string)parser[(int)Key.Dictionary].PostStrings[0], out dicLog))
                    IncorrectCommand();
                dictionary = (Int32)1 << dicLog;
                dictionaryIsDefined = true;
            }
            string mf = "bt4";
            if (parser[(int)Key.MatchFinder].ThereIs)
                mf = (string)parser[(int)Key.MatchFinder].PostStrings[0];
            mf = mf.ToLower();

            if (command == "b")
            {
                const Int32 kNumDefaultItereations = 10;
                Int32 numIterations = kNumDefaultItereations;
                if (paramIndex < nonSwitchStrings.Count)
                    if (!GetNumber((string)nonSwitchStrings[paramIndex++], out numIterations))
                        numIterations = kNumDefaultItereations;
                return LzmaBench.LzmaBenchmark(numIterations, (UInt32)dictionary);
            }

            string train = "";
            if (parser[(int)Key.Train].ThereIs)
                train = (string)parser[(int)Key.Train].PostStrings[0];

            bool encodeMode = false;
            if (command == "e")
                encodeMode = true;
            else if (command == "d")
                encodeMode = false;
            else
                IncorrectCommand();

            bool stdInMode = parser[(int)Key.StdIn].ThereIs;
            bool stdOutMode = parser[(int)Key.StdOut].ThereIs;

            Stream inStream = null;
            if (stdInMode)
            {
                throw (new Exception("Not implemeted"));
            }
            else
            {
                if (paramIndex >= nonSwitchStrings.Count)
                    IncorrectCommand();
                string inputName = (string)nonSwitchStrings[paramIndex++];
                inStream = new FileStream(inputName, FileMode.Open, FileAccess.Read);
            }

            FileStream outStream = null;
            if (stdOutMode)
            {
                throw (new Exception("Not implemeted"));
            }
            else
            {
                if (paramIndex >= nonSwitchStrings.Count)
                    IncorrectCommand();
                string outputName = (string)nonSwitchStrings[paramIndex++];
                outStream = new FileStream(outputName, FileMode.Create, FileAccess.Write);
            }

            FileStream trainStream = null;
            if (train.Length != 0)
                trainStream = new FileStream(train, FileMode.Open, FileAccess.Read);

            if (encodeMode)
            {
                if (!dictionaryIsDefined)
                    dictionary = 1 << 23;

                Int32 posStateBits = 2;
                Int32 litContextBits = 3; // for normal files
                // UInt32 litContextBits = 0; // for 32-bit data
                Int32 litPosBits = 0;
                // UInt32 litPosBits = 2; // for 32-bit data
                Int32 algorithm = 2;
                Int32 numFastBytes = 128;

                bool eos = parser[(int)Key.EOS].ThereIs || stdInMode;

                if (parser[(int)Key.Mode].ThereIs)
                    if (!GetNumber((string)parser[(int)Key.Mode].PostStrings[0], out algorithm))
                        IncorrectCommand();

                if (parser[(int)Key.FastBytes].ThereIs)
                    if (!GetNumber((string)parser[(int)Key.FastBytes].PostStrings[0], out numFastBytes))
                        IncorrectCommand();
                if (parser[(int)Key.LitContext].ThereIs)
                    if (!GetNumber((string)parser[(int)Key.LitContext].PostStrings[0], out litContextBits))
                        IncorrectCommand();
                if (parser[(int)Key.LitPos].ThereIs)
                    if (!GetNumber((string)parser[(int)Key.LitPos].PostStrings[0], out litPosBits))
                        IncorrectCommand();
                if (parser[(int)Key.PosBits].ThereIs)
                    if (!GetNumber((string)parser[(int)Key.PosBits].PostStrings[0], out posStateBits))
                        IncorrectCommand();

                CoderPropID[] propIDs = 
                    {
                        CoderPropID.DictionarySize,
                        CoderPropID.PosStateBits,
                        CoderPropID.LitContextBits,
                        CoderPropID.LitPosBits,
                        CoderPropID.Algorithm,
                        CoderPropID.NumFastBytes,
                        CoderPropID.MatchFinder,
                        CoderPropID.EndMarker
                    };
                object[] properties = 
                    {
                        (Int32)(dictionary),
                        (Int32)(posStateBits),
                        (Int32)(litContextBits),
                        (Int32)(litPosBits),
                        (Int32)(algorithm),
                        (Int32)(numFastBytes),
                        mf,
                        eos
                    };

                Encoder encoder = new Encoder();
                encoder.SetCoderProperties(propIDs, properties);
                encoder.WriteCoderProperties(outStream);
                Int64 fileSize;
                if (eos || stdInMode)
                    fileSize = -1;
                else
                    fileSize = inStream.Length;
                for (int i = 0; i < 8; i++)
                    outStream.WriteByte((Byte)(fileSize >> (8 * i)));
                if (trainStream != null)
                {
                    CDoubleStream doubleStream = new CDoubleStream();
                    doubleStream.s1 = trainStream;
                    doubleStream.s2 = inStream;
                    doubleStream.fileIndex = 0;
                    inStream = doubleStream;
                    long trainFileSize = trainStream.Length;
                    doubleStream.skipSize = 0;
                    if (trainFileSize > dictionary)
                        doubleStream.skipSize = trainFileSize - dictionary;
                    trainStream.Seek(doubleStream.skipSize, SeekOrigin.Begin);
                    encoder.SetTrainSize((uint)(trainFileSize - doubleStream.skipSize));
                }
                encoder.Code(inStream, outStream, -1, -1, null);
            }
            else if (command == "d")
            {
                byte[] properties = new byte[5];
                if (inStream.Read(properties, 0, 5) != 5)
                    throw (new Exception("input .lzma is too short"));
                Decoder decoder = new Decoder();
                decoder.SetDecoderProperties(properties);
                if (trainStream != null)
                {
                    if (!decoder.Train(trainStream))
                        throw (new Exception("can't train"));
                }
                long outSize = 0;
                for (int i = 0; i < 8; i++)
                {
                    int v = inStream.ReadByte();
                    if (v < 0)
                        throw (new Exception("Can't Read 1"));
                    outSize |= ((long)(byte)v) << (8 * i);
                }
                long compressedSize = inStream.Length - inStream.Position;
                decoder.Code(inStream, outStream, compressedSize, outSize, null);
            }
            else
                throw (new Exception("Command Error"));
            return 0;
        }
 public void ParseStrings(SwitchForm[] switchForms, string[] commandStrings)
 {
     int numCommandStrings = commandStrings.Length;
     bool stopSwitch = false;
     for (int i = 0; i < numCommandStrings; i++)
     {
         string s = commandStrings[i];
         if (stopSwitch)
             NonSwitchStrings.Add(s);
         else
             if (s == kStopSwitchParsing)
                 stopSwitch = true;
             else
                 if (!ParseString(s, switchForms))
                     NonSwitchStrings.Add(s);
     }
 }