예제 #1
0
        private static List <string> GetFMSupportedLanguagesFromInstDir(string fmInstPath, bool earlyOutOnEnglish)
        {
            // Get initial list of base FM dirs the normal way: we don't want to count these as lang dirs even if
            // they're named such (matching FMSel behavior)
            var searchList = FastIO.GetDirsTopOnly(fmInstPath, "*", ignoreReparsePoints: true);

            if (searchList.Count == 0)
            {
                return(new List <string>());
            }

            #region Move key dirs to end of list (priority)

            // Searching folders is horrendously slow, so prioritize folders most likely to contain lang dirs so
            // if we find English, we end up earlying-out much faster

            for (int i = 0; i < 3; i++)
            {
                string keyDir = i switch { 0 => "/books", 1 => "/intrface", _ => "/strings" };

                for (int j = 0; j < searchList.Count; j++)
                {
                    if (j < searchList.Count - 1 &&
                        searchList[j].PathEndsWithI(keyDir))
                    {
                        string item = searchList[j];
                        searchList.RemoveAt(j);
                        searchList.Add(item);
                        break;
                    }
                }
            }

            #endregion

            var langsFoundList = new HashSetI(Supported.Length);

            while (searchList.Count > 0)
            {
                string bdPath = searchList[searchList.Count - 1];
                searchList.RemoveAt(searchList.Count - 1);
                bool englishFound = FastIO.SearchDirForLanguages(SupportedHash, bdPath, searchList, langsFoundList, earlyOutOnEnglish);
                // Matching FMSel behavior: early-out on English
                if (earlyOutOnEnglish && englishFound)
                {
                    return new List <string> {
                               "English"
                    }
                }
                ;
            }

            return(SortLangsToSpec(langsFoundList));
        }
예제 #2
0
        /// <summary>
        /// Helper for finding language-named subdirectories in an installed FM directory.
        /// </summary>
        /// <param name="supportedHash"></param>
        /// <param name="path"></param>
        /// <param name="searchList"></param>
        /// <param name="retList"></param>
        /// <param name="earlyOutOnEnglish"></param>
        /// <returns><see langword="true"/> if English was found and we quit the search early</returns>
        internal static bool SearchDirForLanguages(
            HashSetI supportedHash,
            string path,
            List <string> searchList,
            HashSetI retList,
            bool earlyOutOnEnglish)
        {
            path = NormalizeAndCheckPath(path, pathIsKnownValid: true);

            using var findHandle = FindFirstFileExW(@"\\?\" + path + "\\*",
                                                    FINDEX_INFO_LEVELS.FindExInfoBasic, out WIN32_FIND_DATAW findData,
                                                    FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero, FIND_FIRST_EX_LARGE_FETCH);

            if (findHandle.IsInvalid)
            {
                int err = Marshal.GetLastWin32Error();
                if (err is ERROR_FILE_NOT_FOUND or ERROR_NO_MORE_FILES)
                {
                    return(false);
                }
                ThrowException("*", err, path);
            }
            do
            {
                if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY &&
                    // Just ignore reparse points and sidestep any problems
                    (findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != FILE_ATTRIBUTE_REPARSE_POINT &&
                    findData.cFileName != "." && findData.cFileName != "..")
                {
                    if (supportedHash.Contains(findData.cFileName))
                    {
                        // Add lang dir to found langs list, but not to search list - don't search within lang
                        // dirs (matching FMSel behavior)
                        retList.Add(findData.cFileName);
                        // Matching FMSel behavior: early-out on English
                        if (earlyOutOnEnglish && findData.cFileName.EqualsI("english"))
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        searchList.Add(Path.Combine(path, findData.cFileName));
                    }
                }
            } while (FindNextFileW(findHandle, out findData));

            return(false);
        }
예제 #3
0
        internal static List <string> SortLangsToSpec(HashSetI langsHash)
        {
            var ret = new List <string>(Supported.Length);

            // Return a list of all found languages, sorted in the same order as FMSupportedLanguages
            // (matching FMSel behavior)
            if (langsHash.Count > 0)
            {
                for (int i = 0; i < Supported.Length; i++)
                {
                    string sl = Supported[i];
                    if (langsHash.Contains(sl))
                    {
                        ret.Add(sl);
                    }
                }
            }

            return(ret);
        }
예제 #4
0
 public FMTagsCollection(int capacity)
 {
     _list    = new List <string>(capacity);
     _hashSet = new HashSetI(capacity);
 }
예제 #5
0
 public FMTagsCollection()
 {
     _list    = new List <string>();
     _hashSet = new HashSetI();
 }
예제 #6
0
 static FMLanguages()
 {
     SupportedHash = Supported.ToHashSetI();
 }