/// <summary>
        /// Gets the path for a Transform from the root, e.g. '/root/parent/mytransform'
        /// </summary>
        public static string GetPath(Transform t)
        {
            if (t == null)
            {
                return(null);
            }

            string        path = null;
            StringBuilder b    = null;

            try {
                b = StringBuilderPool.Get();

                b = GetPathFrom(t, null, b);

                if (b[0] != '/')
                {
                    b.Insert(0, "/");
                }

                path = b.ToString();
            }
            finally {
                if (b != null)
                {
                    StringBuilderPool.Return(b);
                }
            }

            return(path);
        }
        private static string Describe(ErrorResponseMessage errorMessage)
        {
            if (errorMessage.ErrorCount == 0)
            {
                return("Server returned an error with no description.");
            }

            var sb = StringBuilderPool.Get();

            try
            {
                for (var i = 0;
                     i < errorMessage.ErrorCount - 1;
                     ++i, sb.Append(", "))
                {
                    var error = errorMessage.Errors[i];

                    sb.Append(error.Value);
                }

                return(sb.ToString());
            }
            finally
            {
                StringBuilderPool.Free(ref sb);
            }
        }
예제 #3
0
        private bool AddWordCapitalized(string word, FlagSet flags, MorphSet morphs, CapitalizationType capType)
        {
            // add inner capitalized forms to handle the following allcap forms:
            // Mixed caps: OpenOffice.org -> OPENOFFICE.ORG
            // Allcaps with suffixes: CIA's -> CIA'S

            if (
                (
                    capType == CapitalizationType.Huh ||
                    capType == CapitalizationType.HuhInit ||
                    (capType == CapitalizationType.All && flags.HasItems)
                )
                &&
                !flags.Contains(Affix.ForbiddenWord)
                )
            {
                flags = Builder.Dedup(FlagSet.Union(flags, SpecialFlags.OnlyUpcaseFlag));

                var textInfo       = Affix.Culture.TextInfo;
                var initCapBuilder = StringBuilderPool.Get(word);
                if (initCapBuilder.Length > 0)
                {
                    initCapBuilder[0] = textInfo.ToUpper(initCapBuilder[0]);

                    for (var i = 1; i < initCapBuilder.Length; i++)
                    {
                        initCapBuilder[i] = textInfo.ToLower(initCapBuilder[i]);
                    }
                }

                return(AddWord(StringBuilderPool.GetStringAndReturn(initCapBuilder), flags, morphs, true));
            }

            return(false);
        }
예제 #4
0
        public static string HashPath(string path)
        {
            var md5 = new MD5CryptoServiceProvider();
            var ret = md5.ComputeHash(Encoding.UTF8.GetBytes(path));

            var builder = StringBuilderPool.Get();

            foreach (var b in ret)
            {
                builder.Append(b.ToString("x2"));
            }
            var str = builder.ToString();

            StringBuilderPool.Return(builder);

            builder = StringBuilderPool.Get();
            builder.Append(str.Substring(0, 2));
            builder.Append("/");
            builder.Append(str.Substring(2, 2));
            builder.Append("/");
            builder.Append(str);
            var hashed = builder.ToString();

            StringBuilderPool.Return(builder);

            return(hashed);
        }
        public bool TryConvert(string text, out string converted)
        {
            var convertedBuilder = StringBuilderPool.Get(text.Length);

            var appliedConversion = false;

            for (var i = 0; i < text.Length; i++)
            {
                var replacementEntry = FindLargestMatchingConversion(text.Subslice(i));
                var replacementText  = replacementEntry == null
                    ? string.Empty
                    : replacementEntry.ExtractReplacementText(text.Length - i, i == 0);

                if (replacementText.Length == 0)
                {
                    convertedBuilder.Append(text[i]);
                }
                else
                {
                    convertedBuilder.Append(replacementText);
                    i += replacementEntry.Pattern.Length - 1;
                    appliedConversion = true;
                }
            }

            converted = StringBuilderPool.GetStringAndReturn(convertedBuilder);

            return(appliedConversion);
        }
예제 #6
0
        public static bool AddReplacementEntry(this Dictionary <string, MultiReplacementEntry> list, string pattern1, string pattern2)
        {
            if (string.IsNullOrEmpty(pattern1) || pattern2 == null)
            {
                return(false);
            }

            var pattern1Builder = StringBuilderPool.Get(pattern1);
            ReplacementValueType type;
            var trailingUnderscore = pattern1Builder.EndsWith('_');

            if (pattern1Builder.StartsWith('_'))
            {
                if (trailingUnderscore)
                {
                    type = ReplacementValueType.Isol;
                    pattern1Builder.Remove(pattern1Builder.Length - 1, 1);
                }
                else
                {
                    type = ReplacementValueType.Ini;
                }

                pattern1Builder.Remove(0, 1);
            }
            else
            {
                if (trailingUnderscore)
                {
                    type = ReplacementValueType.Fin;
                    pattern1Builder.Remove(pattern1Builder.Length - 1, 1);
                }
                else
                {
                    type = ReplacementValueType.Med;
                }
            }

            pattern1Builder.Replace('_', ' ');

            pattern1 = StringBuilderPool.GetStringAndReturn(pattern1Builder);
            pattern2 = pattern2.Replace('_', ' ');

            // find existing entry
            MultiReplacementEntry entry;

            if (list.TryGetValue(pattern1, out entry))
            {
                entry = entry.With(type, pattern2);
            }
            else
            {
                // make a new entry if none exists
                entry = new MultiReplacementEntry(pattern1, type, pattern2);
            }

            list[pattern1] = entry;

            return(true);
        }
        public string ReadLine()
        {
            if (!hasCheckedForPreamble)
            {
                ReadPreamble();
            }

            var builder = StringBuilderPool.Get();

            char[] readChars = null;
            while ((readChars = ReadNextChars()) != null)
            {
                if (ProcessCharsForLine(readChars, builder))
                {
                    break;
                }
            }

            if (readChars == null && builder.Length == 0)
            {
                return(null);
            }

            return(ProcessLine(StringBuilderPool.GetStringAndReturn(builder)));
        }
        public async Task <string> ReadLineAsync()
        {
            if (!hasCheckedForPreamble)
            {
                await ReadPreambleAsync().ConfigureAwait(false);
            }

            var builder = StringBuilderPool.Get();

            char[] readChars = null;
            while ((readChars = await ReadNextCharsAsync().ConfigureAwait(false)) != null)
            {
                if (ProcessCharsForLine(readChars, builder))
                {
                    break;
                }
            }

            if (readChars == null && builder.Length == 0)
            {
                return(null);
            }

            return(ProcessLine(StringBuilderPool.GetStringAndReturn(builder)));
        }
예제 #9
0
파일: Common.cs 프로젝트: GeBo1/GeBoPlugins
        internal static StringBuilder RequestStringBuilder()
        {
#if GEBO_COMMON_FULL
            return(StringBuilderPool.Get());
#else
            return(new StringBuilder());
#endif
        }
예제 #10
0
파일: Batch.cs 프로젝트: cjwang/SQLHelper
        /// <summary>
        /// Setups the parameters.
        /// </summary>
        /// <param name="Count">The count.</param>
        /// <param name="FinalParameters">The final parameters.</param>
        /// <param name="Finalizable">if set to <c>true</c> [finalizable].</param>
        /// <param name="FinalSQLCommand">The final SQL command.</param>
        private int SetupParameters(int Count, List <IParameter> FinalParameters, ref bool Finalizable, ref string FinalSQLCommand)
        {
            var ParameterTotal = 0;
            var Builder        = StringBuilderPool?.Get() ?? new StringBuilder();

            Builder.Append(FinalSQLCommand);
            for (var y = 0; y < Headers.Count; ++y)
            {
                var Command = Headers[y];
                if (ParameterTotal + Command.Parameters.Length >= 2000)
                {
                    break;
                }
                ParameterTotal += Command.Parameters.Length;
                Finalizable    |= Command.Finalizable;
                if (Command.CommandType == CommandType.Text)
                {
                    var TempCommandText = Command.SQLCommand ?? string.Empty;
                    Builder.Append(Command.SQLCommand ?? string.Empty).Append(Environment.NewLine);

                    for (int i = 0, CommandParametersLength = Command.Parameters.Length; i < CommandParametersLength; i++)
                    {
                        var TempParameter = Command.Parameters[i];
                        FinalParameters.Add(TempParameter.CreateCopy(string.Empty));
                    }
                }
                else
                {
                    Builder.Append(Command.SQLCommand).Append(Environment.NewLine);
                    for (int i = 0, CommandParametersLength = Command.Parameters.Length; i < CommandParametersLength; i++)
                    {
                        var TempParameter = Command.Parameters[i];
                        FinalParameters.Add(TempParameter.CreateCopy(string.Empty));
                    }
                }
            }
            for (var y = Count; y < Commands.Count; ++y)
            {
                var Command = Commands[y];
                if (ParameterTotal + Command.Parameters.Length >= 2000)
                {
                    break;
                }
                ParameterTotal += Command.Parameters.Length;
                Finalizable    |= Command.Finalizable;
                if (Command.CommandType == CommandType.Text)
                {
                    var TempCommandText = Command.SQLCommand ?? string.Empty;
                    var Suffix          = "Command" + Count.ToString(CultureInfo.InvariantCulture);
                    Builder.Append(string.IsNullOrEmpty(Command.SQLCommand) ?
                                   string.Empty :
                                   ParameterRegex.Replace(Command.SQLCommand, x =>
                    {
                        var Param = Array.Find(Command.Parameters, z => z.ID == x.Groups["ParamName"].Value);
                        return(!(Param is null) ? x.Value + Suffix : x.Value);
                    })).Append(Environment.NewLine);
예제 #11
0
        private bool TryParseReplacements(string parameterText, List <SingleReplacement> entries)
        {
            var parameters = parameterText.SliceOnTabOrSpace();

            if (parameters.Length == 0)
            {
                Builder.LogWarning("Failed to parse replacements from: " + parameterText);
                return(false);
            }

            var patternBuilder = StringBuilderPool.Get(parameters[0]);
            var outString      = parameters.Length > 1 ? parameters[1].ToString() : string.Empty;

            ReplacementValueType type;
            var hasTrailingDollar = patternBuilder.EndsWith('$');

            if (patternBuilder.StartsWith('^'))
            {
                if (hasTrailingDollar)
                {
                    type = ReplacementValueType.Isol;
                    patternBuilder.Remove(patternBuilder.Length - 1, 1);
                }
                else
                {
                    type = ReplacementValueType.Ini;
                }

                patternBuilder.Remove(0, 1);
            }
            else
            {
                if (hasTrailingDollar)
                {
                    type = ReplacementValueType.Fin;
                    patternBuilder.Remove(patternBuilder.Length - 1, 1);
                }
                else
                {
                    type = ReplacementValueType.Med;
                }
            }

            patternBuilder.Replace('_', ' ');

            entries.Add(new SingleReplacement(
                            Builder.Dedup(StringBuilderPool.GetStringAndReturn(patternBuilder)),
                            Builder.Dedup(outString.Replace('_', ' ')),
                            type));

            return(true);
        }
예제 #12
0
        /// <summary>
        /// Build CSS class string from boolean properties of objects in arguments, from strings in arguments.
        /// </summary>
        public static string CssClass(params object[] args)
        {
            var builder = StringBuilderPool.Get();

            try
            {
                var _1st = true;
                foreach (var arg in args)
                {
                    if (arg is string s)
                    {
                        if (!_1st)
                        {
                            builder.Append(' ');
                        }
                        _1st = false;
                        builder.Append(s);
                    }
                    else if (arg is Enum e)
                    {
                        if (!_1st)
                        {
                            builder.Append(' ');
                        }
                        _1st = false;
                        builder.Append(GetHyphenatedName(e.ToString()));
                    }
                    else
                    {
                        foreach (var(name, getter) in GetPropEntriesFromCache(arg))
                        {
                            if ((bool)getter.Invoke(arg, null))
                            {
                                if (!_1st)
                                {
                                    builder.Append(' ');
                                }
                                _1st = false;
                                builder.Append(name);
                            }
                        }
                    }
                }

                return(builder.ToString());
            }
            finally
            {
                StringBuilderPool.Return(builder);
            }
        }
예제 #13
0
        private void NextLine(bool noWait = false)
        {
            StringBuilder stringBuilder = StringBuilderPool.Get();

            stringBuilder.Append(((ReactiveProperty <string>) this._name).get_Value());
            stringBuilder.Append(": ");
            stringBuilder.Append(this._textBuffer[this._currentLine]);
            ((ReactiveProperty <string>) this._message).set_Value(stringBuilder.ToString());
            ++this._currentLine;
            this.FontSpeed = Manager.Config.GameData.FontSpeed;
            if (noWait && !this._typefaceAnimator.isNoWait)
            {
                this.FontSpeed = 100;
            }
            this._typefaceAnimator.Play();
        }
예제 #14
0
            protected override void LoadAssetAtPathInternal(string path, Type type)
            {
                var resPath = PathUtility.RelativeProjectPathToRelativeResourcesPath(path);

                var sb = StringBuilderPool.Get();

                sb.Append(Path.GetDirectoryName(resPath));
                sb.Append("/");
                sb.Append(Path.GetFileNameWithoutExtension(resPath));

                _request = Resources.LoadAsync(sb.ToString(), type);
                if (_request == null)
                {
                    throw new BundleAssetLoadFailedException(
                              string.Format("Cannot load asset {0} from resources: ", sb));
                }

                StringBuilderPool.Return(sb);
            }
            /// <summary>
            /// Recursive search for right ss - sharp s permutations
            /// </summary>
            private WordEntry SpellSharps(ref string @base, int nPos, int n, int repNum, ref SpellCheckResultType info, out string root)
            {
                var pos = @base.IndexOfOrdinal("ss", nPos);

                if (pos >= 0 && n < MaxSharps)
                {
                    var baseBuilder = StringBuilderPool.Get(@base, @base.Length);
                    baseBuilder[pos] = 'ß';
                    baseBuilder.Remove(pos + 1, 1);
                    @base = baseBuilder.ToString();

                    var h = SpellSharps(ref @base, pos + 1, n + 1, repNum + 1, ref info, out root);
                    if (h != null)
                    {
                        return(h);
                    }

                    baseBuilder.Clear();
                    baseBuilder.Append(@base);
                    baseBuilder[pos] = 's';
                    baseBuilder.Insert(pos + 1, 's');
                    @base = StringBuilderPool.GetStringAndReturn(baseBuilder);

                    h = SpellSharps(ref @base, pos + 2, n + 1, repNum, ref info, out root);
                    if (h != null)
                    {
                        return(h);
                    }
                }
                else if (repNum > 0)
                {
                    return(CheckWord(@base, ref info, out root));
                }

                root = null;
                return(null);
            }
예제 #16
0
        protected override void LoadAssetInternal()
        {
            Logs.Logger.LogInfo("Start synchronously loading asset: {0}", _path);

#if UNITY_EDITOR
            if (_context.Options.UseAssetDatabaseInsteadOfResources)
            {
                _asset = AssetDatabase.LoadAssetAtPath(_path, _type);
                if (!_asset)
                {
                    throw new BundleAssetLoadFailedException("Could not load asset from AssetDatabase: " + _path);
                }
            }
            else
#endif
            {
                var resPath = PathUtility.RelativeProjectPathToRelativeResourcesPath(_path);

                var sb = StringBuilderPool.Get();
                sb.Append(Path.GetDirectoryName(resPath));
                sb.Append("/");
                sb.Append(Path.GetFileNameWithoutExtension(resPath));

                _asset = Resources.Load(sb.ToString(), _type);
                if (!_asset)
                {
                    throw new BundleAssetLoadFailedException("Could not load asset from resources: " + _path);
                }

                StringBuilderPool.Return(sb);
            }

            IsDone = true;

            Logs.Logger.LogInfo("End synchronously loading asset: {0}", _path);
        }
        public void AddMessage(int _actorID, string _message)
        {
            if (_message.IsNullOrEmpty() && _message == null)
            {
                _message = string.Empty;
            }
            OneColor oneColor = this.PersonColor(_actorID);
            string   self     = this.PersonName(_actorID) ?? string.Empty;

            if (self.IsNullOrEmpty() && _message.IsNullOrEmpty())
            {
                Debug.LogWarning((object)"AddNotify: キャラ名もメッセージも空っぽだったので追加せず");
            }
            else if (self.IsNullOrEmpty())
            {
                this.AddLog(_message);
            }
            else
            {
                if ((string)oneColor != (string)null)
                {
                    StringBuilder toRelease = StringBuilderPool.Get();
                    toRelease.AppendFormat("<color={0}>{1}</color>{2}", (object)oneColor, (object)self, (object)_message);
                    _message = toRelease.ToString();
                    StringBuilderPool.Release(toRelease);
                }
                else
                {
                    StringBuilder toRelease = StringBuilderPool.Get();
                    toRelease.AppendFormat("{0}{1}", (object)self, (object)_message);
                    _message = toRelease.ToString();
                    StringBuilderPool.Release(toRelease);
                }
                this.AddLog(_message);
            }
        }
        public static unsafe IReadOnlyList <string> Perform(
            IReadOnlyList <PostgresPropertySetting> settings,
            PostgresCommand command)
        {
            var parameters = command.Parameters;
            var sql        = command.CommandText;

            if (sql == null)
            {
                return(EmptyList <string> .Value);
            }

            DemandStandardSettings(settings);

            var queries  = new List <string>();
            var sb       = StringBuilderPool.Get(sql.Length);
            var lastChar = '\0';

            fixed(char *sqlPtr = sql)
            for (var i = 0; i < sql.Length; ++i)
            {
                var chr     = sqlPtr[i];
                var nextChr = i == sql.Length - 1 ? '\0' : sqlPtr[i + 1];

                switch (chr)
                {
                // Handle strings made with quotes, 'foo' and E'foo'
                case '\'':
                    var escapedQuotes = lastChar == 'E';

                    sb.Append(chr);
                    lastChar = '\0';

                    for (++i; i < sql.Length; ++i)
                    {
                        chr = sqlPtr[i];
                        sb.Append(chr);

                        // Quotes (chr == '\'') can be inside a string
                        // in several ways:
                        // * If they're doubled up.
                        // * If we're inside an escape string escaped
                        //   with a backslash.
                        if (chr == '\'' && lastChar != '\'' &&
                            !(escapedQuotes && lastChar == '\\'))
                        {
                            goto next;
                        }

                        lastChar = chr;
                    }

                    continue;

                // Handle dollar strings, $$foo$$ and $bar$foo$bar$
                case '$':
                    var k = i + 1;

                    // Syntax is "$abc$" or "$$", if "named" then "a"
                    // must be a letter. bc+ can be letter or digit.
                    // But "$5" is also valid syntax for parameter
                    // access, so we must respect those.

                    if (k >= sql.Length)
                    {
                        goto default;
                    }

                    var chrK = sqlPtr[k];

                    if (chrK == '$')
                    {
                        var indexOf = sql.IndexOf("$$", k,
                                                  StringComparison.Ordinal);

                        // Really... it's invalid syntax.
                        if (indexOf == -1)
                        {
                            goto default;
                        }

                        // 2 is length of "$$"
                        sb.Append(sql, i, indexOf - i + 2);

                        i = indexOf + 1;
                        goto next;
                    }

                    if (!char.IsLetter(chrK))
                    {
                        goto default;
                    }

                    sb.Append('$');
                    sb.Append(chrK);

                    for (++k; k < sql.Length; ++k)
                    {
                        chrK = sqlPtr[k];
                        sb.Append(chrK);
                        if (chrK == '$')
                        {
                            break;
                        }
                        if (!char.IsLetterOrDigit(chrK))
                        {
                            goto default;
                        }
                    }

                    // +1 to account for final $.
                    ++k;

                    var namedStringStart = i;
                    var matchIndex       = namedStringStart;
                    var matchedCount     = 0;
                    var matchLength      = k - namedStringStart;

                    for (i = k; i < sql.Length; ++i)
                    {
                        for (var m = i; m < sql.Length; ++m, ++matchIndex)
                        {
                            chr = sqlPtr[m];

                            sb.Append(chr);
                            lastChar = chr;

                            if (chr != sqlPtr[matchIndex])
                            {
                                i            = m;
                                matchedCount = 0;
                                matchIndex   = namedStringStart;
                                break;
                            }

                            if (++matchedCount == matchLength)
                            {
                                i = m;
                                // Match success.
                                goto next;
                            }
                        }
                    }

                    // If we enumerate the entire string and do not
                    // find a match, it's technically invalid syntax
                    // but that's the user's problem. They're better
                    // off getting the actual error from postgres.

                    continue;

                // Handle @@NotNamedParameter
                case '@' when nextChr == '@':
                    // Append and fast forward past next one.
                    sb.Append(chr);
                    ++i;
                    lastChar = '\0';
                    continue;

                // Handle @NamedParameter
                case '@':
                    var start = i + 1;

                    var offset = 0;
                    for (i = start; i < sql.Length; ++i)
                    {
                        if (!char.IsLetterOrDigit(sqlPtr[i]))
                        {
                            --i;
                            offset = 1;
                            break;
                        }
                    }

                    var name       = sql.Substring(start, i - start + offset);
                    var paramIndex = parameters.IndexOf(name);

                    if (paramIndex == -1)
                    {
                        throw new ArgumentOutOfRangeException(
                                  "parameterName", name,
                                  "Parameter inside query was not found inside parameter list.");
                    }

                    sb.Append('$');
                    sb.Append(paramIndex + 1);
                    lastChar = '\0';
                    continue;

                // Handle -- quotes.
                case '-' when lastChar == '-':
                    sb.Append(chr);
                    lastChar = '\0';

                    for (++i; i < sql.Length; ++i)
                    {
                        chr = sqlPtr[i];

                        sb.Append(chr);
                        lastChar = chr;

                        if (chr == '\n')
                        {
                            break;
                        }
                    }
                    continue;

                // Handle /* */ quotes.
                case '*' when lastChar == '/':
                    if (i == sql.Length - 1)
                    {
                        goto default;
                    }

                    var indexOfComment = sql.IndexOf("*/", i + 1);

                    // Really... it's invalid syntax.
                    if (indexOfComment == -1)
                    {
                        goto default;
                    }

                    // 2 is length of "*/"
                    sb.Append(sql, i, indexOfComment - i + 2);

                    i = indexOfComment + 1;
                    continue;

                case ';':
                    var singleSqlCommand = sb.ToStringTrim();
                    sb.Clear();

                    if (!string.IsNullOrWhiteSpace(singleSqlCommand))
                    {
                        queries.Add(singleSqlCommand);
                    }

                    continue;

                default:
                    sb.Append(chr);
                    lastChar = chr;
                    continue;
                }

                next :;
            }

            if (sb.Length > 0)
            {
                var singleSqlCommand = sb.ToStringTrim();

                if (!string.IsNullOrWhiteSpace(singleSqlCommand))
                {
                    queries.Add(singleSqlCommand);
                }
            }

            StringBuilderPool.Free(ref sb);
            return(queries);
        }
        /// <summary>
        /// <para>Turns a TimeSpan into a human-readable text.</para>
        /// <para>Uses the specified timeSpanFormatOptions.</para>
        /// <para>For example: "31.23:59:00.555" = "31 days 23 hours 59 minutes 0 seconds 555 milliseconds"</para>
        /// </summary>
        /// <param name="FromTime"></param>
        /// <param name="options">
        /// <para>A combination of flags that determine the formatting options.</para>
        /// <para>These will be combined with the default timeSpanFormatOptions.</para>
        /// </param>
        /// <param name="timeTextInfo">An object that supplies the text to use for output</param>
        public static string ToTimeString(this TimeSpan FromTime, TimeSpanFormatOptions options,
                                          TimeTextInfo timeTextInfo)
        {
            // If there are any missing options, merge with the defaults:
            // Also, as a safeguard against missing DefaultFormatOptions, let's also merge with the AbsoluteDefaults:
            options = options.Merge(DefaultFormatOptions).Merge(AbsoluteDefaults);
            // Extract the individual options:
            var rangeMax   = options.Mask(RangeAll).AllFlags().Last();
            var rangeMin   = options.Mask(RangeAll).AllFlags().First();
            var truncate   = options.Mask(TruncateAll).AllFlags().First();
            var lessThan   = options.Mask(LessThanAll) != TimeSpanFormatOptions.LessThanOff;
            var abbreviate = options.Mask(AbbreviateAll) != TimeSpanFormatOptions.AbbreviateOff;

            var round = lessThan ? (Func <double, double>)Math.Floor : Math.Ceiling;

            switch (rangeMin)
            {
            case TimeSpanFormatOptions.RangeWeeks:
                FromTime = TimeSpan.FromDays(round(FromTime.TotalDays / 7) * 7);
                break;

            case TimeSpanFormatOptions.RangeDays:
                FromTime = TimeSpan.FromDays(round(FromTime.TotalDays));
                break;

            case TimeSpanFormatOptions.RangeHours:
                FromTime = TimeSpan.FromHours(round(FromTime.TotalHours));
                break;

            case TimeSpanFormatOptions.RangeMinutes:
                FromTime = TimeSpan.FromMinutes(round(FromTime.TotalMinutes));
                break;

            case TimeSpanFormatOptions.RangeSeconds:
                FromTime = TimeSpan.FromSeconds(round(FromTime.TotalSeconds));
                break;

            case TimeSpanFormatOptions.RangeMilliSeconds:
                FromTime = TimeSpan.FromMilliseconds(round(FromTime.TotalMilliseconds));
                break;
            }

            // Create our result:
            var textStarted = false;
            var result      = StringBuilderPool.Get();

            for (var i = rangeMax; i >= rangeMin; i = (TimeSpanFormatOptions)((int)i >> 1))
            {
                // Determine the value and title:
                int value;
                switch (i)
                {
                case TimeSpanFormatOptions.RangeWeeks:
                    value     = (int)Math.Floor(FromTime.TotalDays / 7);
                    FromTime -= TimeSpan.FromDays(value * 7);
                    break;

                case TimeSpanFormatOptions.RangeDays:
                    value     = (int)Math.Floor(FromTime.TotalDays);
                    FromTime -= TimeSpan.FromDays(value);
                    break;

                case TimeSpanFormatOptions.RangeHours:
                    value     = (int)Math.Floor(FromTime.TotalHours);
                    FromTime -= TimeSpan.FromHours(value);
                    break;

                case TimeSpanFormatOptions.RangeMinutes:
                    value     = (int)Math.Floor(FromTime.TotalMinutes);
                    FromTime -= TimeSpan.FromMinutes(value);
                    break;

                case TimeSpanFormatOptions.RangeSeconds:
                    value     = (int)Math.Floor(FromTime.TotalSeconds);
                    FromTime -= TimeSpan.FromSeconds(value);
                    break;

                case TimeSpanFormatOptions.RangeMilliSeconds:
                    value     = (int)Math.Floor(FromTime.TotalMilliseconds);
                    FromTime -= TimeSpan.FromMilliseconds(value);
                    break;

                default:
                    // This code is unreachable, but it prevents compile-errors.
                    throw new ArgumentException("TimeSpanUtility");
                }


                //Determine whether to display this value
                var displayThisValue = false;
                var breakFor         =
                    false; // I wish C# supported "break for;" (like how VB supports "Exit For" from within a "Select Case" statement)
                switch (truncate)
                {
                case TimeSpanFormatOptions.TruncateShortest:
                    if (textStarted)
                    {
                        breakFor = true;
                        break;
                    }

                    if (value > 0)
                    {
                        displayThisValue = true;
                    }
                    break;

                case TimeSpanFormatOptions.TruncateAuto:
                    if (value > 0)
                    {
                        displayThisValue = true;
                    }
                    break;

                case TimeSpanFormatOptions.TruncateFill:
                    if (textStarted || value > 0)
                    {
                        displayThisValue = true;
                    }
                    break;

                case TimeSpanFormatOptions.TruncateFull:
                    displayThisValue = true;
                    break;
                }

                if (breakFor)
                {
                    break;
                }

                //we need to display SOMETHING (even if it's zero)
                if (i == rangeMin && textStarted == false)
                {
                    displayThisValue = true;
                    if (lessThan && value < 1)
                    {
                        // Output the "less than 1 unit" text:
                        var unitTitle = timeTextInfo.GetUnitText(rangeMin, 1, abbreviate);
                        result.Append(timeTextInfo.GetLessThanText(unitTitle));
                        displayThisValue = false;
                    }
                }

                // Output the value:
                if (displayThisValue)
                {
                    if (textStarted)
                    {
                        result.Append(" ");
                    }
                    var unitTitle = timeTextInfo.GetUnitText(i, value, abbreviate);
                    result.Append(unitTitle);
                    textStarted = true;
                }
            }

            var ret = result.ToString();

            StringBuilderPool.Release(result);
            return(ret);
        }
예제 #20
0
        public static Guid GetCharaGuid(this SaveData.CharaData charaData,
                                        int guidVersion = PluginDataInfo.CurrentCharaGuidVersion)
        {
            if (guidVersion > PluginDataInfo.MaxCharaGuidVersion)
            {
                throw new ArgumentOutOfRangeException(nameof(guidVersion), $"Unknown guidVersion ({guidVersion})");
            }

            if (guidVersion < PluginDataInfo.MinimumSupportedCharaGuidVersion || charaData == null ||
                !charaData.charFileInitialized)
            {
                return(Guid.Empty);
            }

            var guidKeyBuilder = StringBuilderPool.Get();
            var intFmt         = "{0:04}";

            try
            {
                switch (guidVersion)
                {
                case 5:
                    guidKeyBuilder
                    .AppendFormat(intFmt,
                                  charaData is SaveData.Heroine heroine5
                                    ? heroine5.FixCharaIDOrPersonality
                                    : charaData.personality)
                    .Append('/')
                    .AppendFormat(intFmt, charaData.schoolClass)
                    .Append('/')
                    .AppendFormat(intFmt, charaData.schoolClassIndex)
                    .Append('/')
                    .Append(charaData.Name);
                    break;

                case 6:
                    guidKeyBuilder
                    .AppendFormat(intFmt,
                                  charaData is SaveData.Heroine heroine6
                                    ? heroine6.FixCharaIDOrPersonality
                                    : charaData.personality)
                    .Append('/')
                    .AppendFormat(intFmt, charaData.schoolClass)
                    .Append('/')
                    .AppendFormat(intFmt, charaData.schoolClassIndex)
                    .Append('/')
                    .Append(charaData.firstname)
                    .Append('/')
                    .Append(charaData.lastname)
                    .Append('/')
                    .Append(charaData.parameter.sex);
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(guidVersion),
                                                          $"Unsupported guidVersion ({guidVersion})");
                }

                if (guidKeyBuilder.Length == 0)
                {
                    return(Guid.Empty);
                }
                var guidKey = guidKeyBuilder.ToString();
                var result  = GuidCache.Get(guidKey);
                Logger?.DebugLogDebug(
                    $"{nameof(GetCharaGuid)} (version={guidVersion}): guidKey={guidKey}, result={result}");
                return(result);
            }
            finally
            {
                StringBuilderPool.Release(guidKeyBuilder);
            }
        }
예제 #21
0
        private bool TryParseAffixIntoList <TEntry>(string parameterText, ref List <AffixEntryGroup.Builder <TEntry> > groups)
            where TEntry : AffixEntry, new()
        {
            if (groups == null)
            {
                groups = new List <AffixEntryGroup.Builder <TEntry> >();
            }

            var lineMatch = AffixLineRegex.Match(parameterText);

            if (!lineMatch.Success)
            {
                Builder.LogWarning("Failed to parse affix line: " + parameterText);
                return(false);
            }

            var lineMatchGroups = lineMatch.Groups;

            FlagValue characterFlag;

            if (!TryParseFlag(lineMatchGroups[1].Value, out characterFlag))
            {
                Builder.LogWarning($"Failed to parse affix flag for {lineMatchGroups[1].Value} from: {parameterText}");
                return(false);
            }

            var affixGroup = groups.FindLast(g => g.AFlag == characterFlag);
            var contClass  = FlagSet.Empty;

            if (lineMatchGroups[2].Success && lineMatchGroups[3].Success)
            {
                if (affixGroup != null)
                {
                    Builder.LogWarning($"Duplicate affix group definition for {affixGroup.AFlag} from: {parameterText}");
                    return(false);
                }

                var options = AffixEntryOptions.None;
                if (lineMatchGroups[2].Value.StartsWith('Y'))
                {
                    options |= AffixEntryOptions.CrossProduct;
                }
                if (Builder.IsAliasM)
                {
                    options |= AffixEntryOptions.AliasM;
                }
                if (Builder.IsAliasF)
                {
                    options |= AffixEntryOptions.AliasF;
                }

                int expectedEntryCount;
                IntEx.TryParseInvariant(lineMatchGroups[3].Value, out expectedEntryCount);

                affixGroup = new AffixEntryGroup.Builder <TEntry>
                {
                    AFlag   = characterFlag,
                    Options = options,
                    Entries = new List <TEntry>(expectedEntryCount)
                };

                groups.Add(affixGroup);

                return(true);
            }
            else if (lineMatchGroups[4].Success && lineMatchGroups[5].Success && lineMatchGroups[6].Success)
            {
                // piece 3 - is string to strip or 0 for null
                var strip = lineMatchGroups[4].Value;
                if (strip == "0")
                {
                    strip = string.Empty;
                }
                else if (EnumEx.HasFlag(Builder.Options, AffixConfigOptions.ComplexPrefixes))
                {
                    strip = strip.Reverse();
                }

                // piece 4 - is affix string or 0 for null
                var           affixInput      = lineMatchGroups[5].Value;
                var           affixSlashIndex = affixInput.IndexOf('/');
                StringBuilder affixText;
                if (affixSlashIndex >= 0)
                {
                    var slashPartOffset = affixSlashIndex + 1;
                    var slashPartLength = affixInput.Length - slashPartOffset;
                    affixText = StringBuilderPool.Get(affixInput, 0, affixSlashIndex);

                    if (Builder.IsAliasF)
                    {
                        int aliasNumber;
                        if (IntEx.TryParseInvariant(affixInput.Subslice(slashPartOffset, slashPartLength), out aliasNumber) && aliasNumber > 0 && aliasNumber <= Builder.AliasF.Count)
                        {
                            contClass = Builder.AliasF[aliasNumber - 1];
                        }
                        else
                        {
                            Builder.LogWarning($"Failed to parse contclasses from : {parameterText}");
                            return(false);
                        }
                    }
                    else
                    {
                        contClass = ParseFlags(affixInput.Subslice(slashPartOffset, slashPartLength));
                    }
                }
                else
                {
                    affixText = StringBuilderPool.Get(affixInput);
                }

                if (Builder.IgnoredChars != null && Builder.IgnoredChars.HasItems)
                {
                    affixText.RemoveChars(Builder.IgnoredChars);
                }

                if (EnumEx.HasFlag(Builder.Options, AffixConfigOptions.ComplexPrefixes))
                {
                    affixText.Reverse();
                }

                if (affixText.Length == 1 && affixText[0] == '0')
                {
                    affixText.Clear();
                }

                // piece 5 - is the conditions descriptions
                var conditionText = lineMatchGroups[6].Value;
                if (EnumEx.HasFlag(Builder.Options, AffixConfigOptions.ComplexPrefixes))
                {
                    conditionText = ReverseCondition(conditionText);
                }

                var conditions = CharacterCondition.Parse(conditionText);

                if (!string.IsNullOrEmpty(strip) && !conditions.AllowsAnySingleCharacter)
                {
                    bool isRedundant;
                    if (typeof(TEntry) == typeof(PrefixEntry))
                    {
                        isRedundant = RedundantConditionPrefix(strip, conditions);
                    }
                    else if (typeof(TEntry) == typeof(SuffixEntry))
                    {
                        isRedundant = RedundantConditionSuffix(strip, conditions);
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }

                    if (isRedundant)
                    {
                        conditions = CharacterConditionGroup.AllowAnySingleCharacter;
                    }
                }

                // piece 6
                MorphSet morph;
                if (lineMatchGroups[7].Success)
                {
                    var morphAffixText = lineMatchGroups[7].Value;
                    if (Builder.IsAliasM)
                    {
                        int morphNumber;
                        if (IntEx.TryParseInvariant(morphAffixText, out morphNumber) && morphNumber > 0 && morphNumber <= Builder.AliasM.Count)
                        {
                            morph = Builder.AliasM[morphNumber - 1];
                        }
                        else
                        {
                            Builder.LogWarning($"Failed to parse morph {morphAffixText} from: {parameterText}");
                            return(false);
                        }
                    }
                    else
                    {
                        if (EnumEx.HasFlag(Builder.Options, AffixConfigOptions.ComplexPrefixes))
                        {
                            morphAffixText = morphAffixText.Reverse();
                        }

                        morph = Builder.Dedup(MorphSet.TakeArray(Builder.DedupInPlace(morphAffixText.SplitOnTabOrSpace())));
                    }
                }
                else
                {
                    morph = MorphSet.Empty;
                }

                if (affixGroup == null)
                {
                    affixGroup = new AffixEntryGroup.Builder <TEntry>
                    {
                        AFlag   = characterFlag,
                        Options = AffixEntryOptions.None,
                        Entries = new List <TEntry>()
                    };
                }

                if (!Builder.HasContClass && contClass.HasItems)
                {
                    Builder.HasContClass = true;
                }

                affixGroup.Entries.Add(AffixEntry.Create <TEntry>(
                                           Builder.Dedup(strip),
                                           Builder.Dedup(StringBuilderPool.GetStringAndReturn(affixText)),
                                           Builder.Dedup(conditions),
                                           morph,
                                           contClass));

                return(true);
            }
            else
            {
                Builder.LogWarning("Affix line not fully parsed: " + parameterText);
                return(false);
            }
        }
예제 #22
0
        private static string ReverseCondition(string conditionText)
        {
            if (string.IsNullOrEmpty(conditionText))
            {
                return(conditionText);
            }

            var chars = StringBuilderPool.Get(conditionText);

            chars.Reverse();
            var neg       = false;
            var lastIndex = chars.Length - 1;

            for (int k = lastIndex; k >= 0; k--)
            {
                switch (chars[k])
                {
                case '[':
                    if (neg)
                    {
                        if (k < lastIndex)
                        {
                            chars[k + 1] = '[';
                        }
                    }
                    else
                    {
                        chars[k] = ']';
                    }

                    break;

                case ']':
                    chars[k] = '[';
                    if (neg && k < lastIndex)
                    {
                        chars[k + 1] = '^';
                    }

                    neg = false;

                    break;

                case '^':
                    if (k < lastIndex)
                    {
                        if (chars[k + 1] == ']')
                        {
                            neg = true;
                        }
                        else
                        {
                            chars[k + 1] = chars[k];
                        }
                    }

                    break;

                default:
                    if (neg && k < lastIndex)
                    {
                        chars[k + 1] = chars[k];
                    }
                    break;
                }
            }

            return(StringBuilderPool.GetStringAndReturn(chars));
        }