CASCExplorer.FileScanner.ScanFile C# (CSharp) Method

ScanFile() public method

public ScanFile ( CASCFile file ) : IEnumerable
file CASCFile
return IEnumerable
        public IEnumerable<string> ScanFile(CASCFile file)
        {
            if (excludeFileTypes.Contains(Path.GetExtension(file.FullName).ToLower()))
                yield break;

            Stream fileStream = null;

            try
            {
                fileStream = CASC.OpenFile(file.Hash);
            }
            catch (Exception exc)
            {
                Logger.WriteLine("Skipped {0}, error {1}.", file.FullName, exc.Message);
                yield break;
            }

            using (fileStream)
            {
                int b;
                int state = 1;
                StringBuilder sb = new StringBuilder();

                // look for regex a+(da+)*\.a+ where a = IsAlphaNum() and d = IsFileDelim()
                // using a simple state machine
                while ((b = fileStream.ReadByte()) > -1)
                {
                    if (state == 1 && IsAlphaNum(b) || state == 2 && IsAlphaNum(b) || state == 3 && IsAlphaNum(b)) // alpha
                    {
                        state = 2;
                        sb.Append((char)b);

                        if (sb.Length > 10)
                        {
                            int nextByte = fileStream.ReadByte();

                            if (nextByte == 0)
                            {
                                string foundStr = sb.ToString();

                                foreach (var ext in extensions)
                                    yield return foundStr + ext;
                            }

                            if (nextByte > -1)
                                fileStream.Position -= 1;
                        }
                    }
                    else if (state == 2 && IsFileDelim(b)) // delimiter
                    {
                        state = 3;
                        sb.Append((char)b);
                    }
                    else if (state == 2 && b == 46) // dot
                    {
                        state = 4;
                        sb.Append((char)b);
                    }
                    else if (state == 4 && IsAlphaNum(b)) // extension
                    {
                        state = 5;
                        sb.Append((char)b);
                    }
                    else if (state == 5 && IsAlphaNum(b)) // extension
                    {
                        sb.Append((char)b);
                    }
                    else if (state == 5 && !IsFileChar(b)) // accept
                    {
                        state = 1;
                        if (sb.Length >= 10)
                            yield return sb.ToString();
                        sb.Clear();
                    }
                    else
                    {
                        state = 1;
                        sb.Clear();
                    }
                }
            }
        }

Usage Example

Esempio n. 1
0
        private void ScanFile(CASCFile file)
        {
            if (scanBackgroundWorker.CancellationPending)
            {
                throw new OperationCanceledException();
            }

            NumScanned++;

            var fileNames = scanner.ScanFile(file);

            if (fileNames.Any())
            {
                // only report progress when not skipping a file, it's faster that way
                int progress            = (int)(NumScanned / (float)NumFiles * 100);
                ScanProgressState state = new ScanProgressState();
                state.NumFilesScanned = NumScanned;
                state.NumFilesTotal   = NumFiles;
                state.CurrentFileName = file.FullName;
                scanBackgroundWorker.ReportProgress(progress, state);

                foreach (var fileName in fileNames)
                {
                    ulong hash = Hasher.ComputeHash(fileName);

                    if ((CASC.Root as WowRootHandler).IsUnknownFile(hash))
                    {
                        BeginInvoke((MethodInvoker)(() => UpdateFileNames(fileName, file.FullName)));
                    }
                }
            }
        }