Beispiel #1
0
        public void TrimEndSubstring(string input, char trimChar, string expected)
        {
            var substring = new Substring(input);

            substring = Substring.TrimEnd(substring, trimChar);

            Assert.Equal(expected, substring.ToString());
        }
Beispiel #2
0
        public void SubstringConstructor()
        {
            AString astr = new AString();
            AString res  = new AString();

            constructorTest("a", res, false); UT_EQ("a", res);
            constructorTest(" a", res, false); UT_EQ(" a", res);
            constructorTest("a ", res, false); UT_EQ("a ", res);
            constructorTest("a b", res, false); UT_EQ("a b", res);
            constructorTest(" a b", res, false); UT_EQ(" a b", res);
            constructorTest("a b ", res, false); UT_EQ("a b ", res);

            constructorTest("a", res, true); UT_EQ("a", res);
            constructorTest(" a", res, true); UT_EQ("a", res);
            constructorTest("a ", res, true); UT_EQ("a", res);
            constructorTest("a b", res, true); UT_EQ("a b", res);
            constructorTest(" a b", res, true); UT_EQ("a b", res);
            constructorTest("a b ", res, true); UT_EQ("a b", res);

            // changing whitespaces
            {
                {
                    astr.Clear()._("xy xz abc xy");
                    Substring subs = new Substring();
                    subs.Set(astr).Trim("xy ".ToCharArray());
                    subs.CopyTo(res);
                    UT_EQ("z abc", res);
                }

                {
                    Substring subs = new Substring("xy xz abc xy");
                    subs.TrimStart("xy ".ToCharArray());
                    subs.TrimEnd("xy ".ToCharArray());
                    subs.CopyTo(res);
                    UT_EQ("z abc", res);
                }
            }

            // test other constructors
            {
                astr.Clear()._(" astring ");
                UT_TRUE((new Substring()).IsEmpty());
                UT_TRUE((new Substring()).IsNull());
                UT_EQ("astring", (new Substring(astr)).Trim().ToString());
                UT_EQ("str", (new Substring(astr, 2, 3)).ToString());
                UT_EQ("", (new Substring(astr, 20, 3)).ToString());
                UT_TRUE((new Substring(astr, 20, 3)).IsEmpty());
                UT_FALSE((new Substring(astr, 20, 3)).IsNull());


                Substring s2 = new Substring(astr); s2.Trim();
                UT_EQ("astring", new Substring(s2.ToString()).ToString());
                UT_EQ("str", (new Substring((new Substring(astr, 2, 3)))).ToString());
            }
        }
        bool  Get(Object category, Object name, AString target)
        {
            // assemble option name as CATEGORY_NAME
            target.Clear()._(category);
            if (target.IsNotEmpty())
            {
                target._('_');
            }
            target._(name);


            int       optionLength = target.Length();
            Substring actVar       = new Substring();

            for (int i = 0; i < args.Length; i++)
            {
                // remove whitespaces (if somebody would work with quotation marks...)
                actVar.Set(args[i]).Trim();

                // request '-' and allow a second '-'
                if (!actVar.Consume('-'))
                {
                    continue;
                }
                actVar.Consume('-');

                if (target.CompareTo(args[i], Case.Ignore, actVar.Start, optionLength, 0, optionLength) == 0)
                {
                    //again, lets trim before searching the = sign (really almost unnecessary)
                    actVar.Start += optionLength;
                    if (actVar.Consume('=', Whitespaces.Trim))
                    {
                        actVar.TrimStart();
                        actVar.TrimEnd();
                        target.Clear();
                        target._NC(args[i], actVar.Start, actVar.Length());
                        return(true);
                    }
                }
            }

            return(false);
        }
        /** ****************************************************************************************
         * Returns the next token, which is afterwards also available through field #Actual.
         * If no further token  was available, the returned
         * \ref cs::aworx::lib::strings::Substring "Substring" will be 'nulled'
         * (see \ref cs::aworx::lib::strings::Substring::IsNull "Substring.IsNull").
         * To prevent this, the availability of a next token should be
         * checked using method #HasNext().
         *
         * For clarification, see the explanation and sample code in this classes documentation.
         *
         *  @param trimming  Determines if the token is trimmed in respect to the white space
         *                   characters defined in field #Whitespaces.
         *                   Defaults to \c Whitespaces.Trim.
         *  @param newDelim  The delimiter separates the tokens. Defaults to 0, which keeps the
         *                   current delimiter intact.
         *                   However, it a new delimiter can be provided for every next token.
         * @return true if a next token was available, false if not.
         ******************************************************************************************/
        public Substring    Next(Whitespaces trimming = enums.Whitespaces.Trim, char newDelim = '\0')
        {
            if (Rest.IsNull())
            {
                Actual.SetNull();
                return(Actual);
            }

            // change of delim?
            if (newDelim != '\0')
            {
                delim = newDelim;
            }

            // set buf, start and find end
            Actual.Buf   = Rest.Buf;
            Actual.Start = Rest.Start;

            int nextDelimiter = Rest.IndexOf(delim);

            if (nextDelimiter >= 0)
            {
                Rest.Start += nextDelimiter + 1;
                Actual.End  = Rest.Start - 2;
            }
            else
            {
                Actual.End = Rest.End;
                Rest.SetNull();
            }


            // trim
            if (trimming == enums.Whitespaces.Trim)
            {
                Actual.TrimStart(Whitespaces);
                Actual.TrimEnd(Whitespaces);
            }

            return(Actual);
        }
        // #############################################################################################
        // file IO
        // #############################################################################################

        /** ****************************************************************************************
         *  Clears all configuration data and reads the file. It might happen that lines are
         *  ignored or otherwise marked as faulty. All numbers of such lines get collected in
         *  field LinesWithReadErrors.
         *  @return Returns the #Status of the operation.
         ******************************************************************************************/
        public IniFile.Status  ReadFile()
        {
            Clear();
            LastStatus = Status.OK;

            // read all variables
            StreamReader file;

            try
            {
                file = new StreamReader(FileName.ToString());
            }
            catch (Exception)
            {
                return(LastStatus = Status.ERROR_OPENING_FILE);
            }

            String    lineS;
            AString   name       = new AString();
            AString   value      = new AString();
            AString   comments   = new AString();
            Section   actSection = Sections[0];
            Substring line       = new Substring();
            Tokenizer tn         = new Tokenizer();

            int  lineNo         = 0;
            bool fileHeaderRead = false;

            LinesWithReadErrors.Clear();

            while ((lineS = file.ReadLine()) != null)
            {
                lineNo = 0;
                //  place in AString
                line.Set(lineS).Trim();

                // empty line?
                if (line.IsEmpty())
                {
                    // already collecting a comment?
                    if (comments.IsNotEmpty())
                    {
                        // first empty line in file found?
                        if (!fileHeaderRead)
                        {
                            //store comments belonging to file
                            fileHeaderRead = true;
                            FileComments   = comments;
                            comments       = new AString();
                            continue;
                        }

                        comments.NewLine();
                    }
                    continue;
                }

                // comments line: find comment character '#', ';' or //
                if (startsWithCommentSymbol(line))
                {
                    //gather in comments string
                    if (comments.IsNotEmpty())
                    {
                        comments.NewLine();
                    }
                    line.CopyTo(comments, true);
                    continue;
                }

                // section line
                if (line.Consume('['))
                {
                    fileHeaderRead = true;

                    // we do not care if there is no closing bracket. But if there is one, we remove it.
                    if (!line.ConsumeFromEnd(']'))
                    {
                        LinesWithReadErrors.Add(lineNo);
                    }

                    // search the section in our section list (if section existed already, new comments
                    // are dropped)
                    actSection = SearchOrCreateSection(line, comments);
                    comments.Clear();

                    continue;
                }

                // variable line? If not, we just drop the line!
                tn.Set(line, '=');
                tn.Next();
                if (!tn.HasNext())
                {
                    LinesWithReadErrors.Add(lineNo);
                    continue;
                }

                tn.Actual.CopyTo(name);
                if (tn.GetRest().IsEmpty())
                {
                    LinesWithReadErrors.Add(lineNo);
                    continue;
                }

                value.Clear();
                Substring valueRead = tn.Actual;

                // read continues as long as lines end with '\' (must not be '\\')
                char delim = '\0';
                while (valueRead.CharAtEnd() == '\\' &&
                       valueRead.CharAtEnd(1) != '\\')
                {
                    // search end before '\'. The first of all broken lines determines the delimiter
                    valueRead.End--;
                    valueRead.TrimEnd();

                    if (delim == 0)
                    {
                        delim = valueRead.CharAtEnd();
                        if (delim == '\"' || char.IsLetterOrDigit(delim))
                        {
                            delim = '\0';
                        }
                    }

                    removeEscapeSequences(valueRead, value);
                    if ((lineS = file.ReadLine()) == null)
                    {
                        // last line of the file ended with '\' !
                        valueRead.Clear();
                        break;
                    }

                    valueRead.Set(lineS).Trim();
                }
                removeEscapeSequences(valueRead, value);

                actSection.Insert(name, value, comments).Delim = delim;
                comments.Clear();
            }
            file.Close();

            return(LastStatus);
        }