示例#1
0
        public void Send(byte[] buffer, byte commandCode)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("command");
            }

            if (m_IsDisconnected)
            {
                return;
            }
            try
            {
                m_SendingQueue.Lock();
                if ((commandCode < 0x50 && commandCode > 0x6F) || m_SendingQueue.Count < 25)
                {
                    m_SendingQueue.Add(buffer, DateTime.Now);
                }
            }
            finally
            {
                m_SendingQueue.Unlock();
            }
            m_SendingResetEvent.Set();
        }
示例#2
0
        public Command23(CommandBuilder command)
        {
            if (command == null)
            {
                throw new ArgumentNullException("command");
            }

            m_Command        = command;
            m_CommandID      = m_Command.ReadBytes(48);
            m_SenderPeerID   = m_Command.ReadBytes(48);
            m_ReceiverPeerID = m_Command.ReadBytes(48);
            m_SearchID       = m_Command.ReadBytes(48);
            m_SearchResults  = new RList <SearchResult>();
            ushort searchResultsCount = m_Command.ReadUInt16();

            for (int n = 0; n < searchResultsCount; n++)
            {
                byte[] fileHash = m_Command.ReadBytes(64);
                uint   fileSize = m_Command.ReadUInt32();
                string fileName = m_Command.ReadString();
                RIndexedHashtable <string, string> metaData = new RIndexedHashtable <string, string>();
                ushort metaDataCount = m_Command.ReadUInt16();
                for (int m = 0; m < metaDataCount; m++)
                {
                    metaData.Add(m_Command.ReadString(), m_Command.ReadString());
                }
                m_SearchResults.Add(new SearchResult(fileHash, fileSize, fileName, metaData, m_Command.ReadString(), m_Command.ReadByte()));
            }
        }
示例#3
0
        public Command54(CommandBuilder command)
        {
            if (command == null)
            {
                throw new ArgumentNullException("command");
            }

            m_Command        = command;
            m_CommandID      = m_Command.ReadBytes(48);
            m_SenderPeerID   = m_Command.ReadBytes(48);
            m_ReceiverPeerID = m_Command.ReadBytes(48);
            m_SourceSearchID = m_Command.ReadBytes(48);
            m_FileSize       = m_Command.ReadUInt32();
            m_FileName       = m_Command.ReadString();
            m_MetaData       = new RIndexedHashtable <string, string>();
            ushort metaDataCount = m_Command.ReadUInt16();

            for (int n = 0; n < metaDataCount; n++)
            {
                m_MetaData.Add(m_Command.ReadString(), m_Command.ReadString());
            }
            m_Comment    = m_Command.ReadString();
            m_Rating     = m_Command.ReadByte();
            m_SectorsMap = m_Command.ReadBytes(m_Command.ReadUInt16());
        }
示例#4
0
 public void Add(SharedFile sharedFile)
 {
     try
     {
         Lock();
         m_FileHash.Add(sharedFile.FileHashString, sharedFile);
         m_OnceHashedFileHash.Add(sharedFile.OnceHashedFileHashString, sharedFile.FileHashString);
         m_TwiceHashedFileHash.Add(sharedFile.TwiceHashedFileHashString, sharedFile.FileHashString);
         m_ThriceHashedFileHash.Add(sharedFile.ThriceHashedFileHashString, sharedFile.FileHashString);
     }
     finally
     {
         Unlock();
     }
 }
 public void Add(Download download)
 {
     try
     {
         Lock();
         m_DownloadID.Add(download.DownloadIDString, download);
         m_FileHash.Add(download.FileHashString, download.DownloadIDString);
         m_OnceHashedFileHash.Add(download.OnceHashedFileHashString, download.DownloadIDString);
         m_TwiceHashedFileHash.Add(download.TwiceHashedFileHashString, download.DownloadIDString);
         m_ThriceHashedFileHash.Add(download.ThriceHashedFileHashString, download.DownloadIDString);
     }
     finally
     {
         Unlock();
     }
 }
示例#6
0
        public Command53(CommandBuilder command)
        {
            if (command == null)
                throw new ArgumentNullException("command");

            m_Command = command;
            m_CommandID = m_Command.ReadBytes(48);
            m_SenderPeerID = m_Command.ReadBytes(48);
            m_ReceiverPeerID = m_Command.ReadBytes(48);
            m_SourceSearchID = m_Command.ReadBytes(48);
            m_FileSize = m_Command.ReadUInt32();
            m_FileName = m_Command.ReadString();
            m_MetaData = new RIndexedHashtable<string, string>();
            ushort metaDataCount = m_Command.ReadUInt16();
            for (int n = 0; n < metaDataCount; n++)
                m_MetaData.Add(m_Command.ReadString(), m_Command.ReadString());
            m_Comment = m_Command.ReadString();
            m_Rating = m_Command.ReadByte();
        }
示例#7
0
        public Command23(CommandBuilder command)
        {
            if (command == null)
                throw new ArgumentNullException("command");

            m_Command = command;
            m_CommandID = m_Command.ReadBytes(48);
            m_SenderPeerID = m_Command.ReadBytes(48);
            m_ReceiverPeerID = m_Command.ReadBytes(48);
            m_SearchID = m_Command.ReadBytes(48);
            m_SearchResults = new RList<SearchResult>();
            ushort searchResultsCount = m_Command.ReadUInt16();
            for (int n = 0; n < searchResultsCount; n++)
            {
                byte[] fileHash = m_Command.ReadBytes(64);
                uint fileSize = m_Command.ReadUInt32();
                string fileName = m_Command.ReadString();
                RIndexedHashtable<string, string> metaData = new RIndexedHashtable<string, string>();
                ushort metaDataCount = m_Command.ReadUInt16();
                for (int m = 0; m < metaDataCount; m++)
                    metaData.Add(m_Command.ReadString(), m_Command.ReadString());
                m_SearchResults.Add(new SearchResult(fileHash, fileSize, fileName, metaData, m_Command.ReadString(), m_Command.ReadByte()));
            }
        }
示例#8
0
        public void Process()
        {
            //2009-01-25 Nochbaer
            bool activateSearchDB = bool.Parse(m_Settings["ActivateSearchDB"]);
            if (!m_SearchedInDatabase && activateSearchDB && m_SearchType != SearchType.OnlyNetwork)
            {
                Core.AddSearchDBSearch(m_SearchIDString, m_SearchPattern);
                m_SearchedInDatabase = true;

                if (m_SearchType == SearchType.OnlyDatabase)
                {
                    m_SearchCommandsToSent = 0;
                }
            }
            else if (m_SearchedInDatabase && !m_GotSearchDBResults)
            {
                try
                {
                    m_Results.Lock();

                    RIndexedHashtable<string, SearchDBManager.OldSearchResult> searchdbResults = Core.GetSearchDBResults(m_SearchIDString);

                    if (searchdbResults != null)
                    {
                        int maxSearchDBResults = int.Parse(m_Settings["MaxSearchDBResults"]);
                        m_TotalSearchDBResults = searchdbResults.Count;

                        int resultCounter = 0;
                        foreach (SearchDBManager.OldSearchResult result in searchdbResults.Values)
                        {
                            if (m_FileTypeFilter.Contains(result.FileName))
                            {
                                if (!m_Results.ContainsKey(result.FileHashString))
                                {
                                    //2009-01-31 Nochbaer
                                    if (resultCounter >= maxSearchDBResults)
                                    {
                                        m_TooManySearchDBResults = true;
                                        break;
                                    }

                                    RIndexedHashtable<string, string> metaData = new RIndexedHashtable<string, string>();
                                    metaData.Add("Album", result.Album);
                                    metaData.Add("Artist", result.Artist);
                                    metaData.Add("Title", result.Title);
                                    m_Results.Add(result.FileHashString, new Result(m_Results, result.FileHash, result.FileSize, Core.GenerateIDOrHash(), result.FileName, metaData, string.Empty, result.Rating, true, result.Date));

                                    resultCounter++;
                                }
                            }
                        }

                        //Compare the results after filetypefilter
                        if (m_Results.Count >= 25)
                        {
                            m_SearchCommandsToSent = 0;
                        }

                        m_GotSearchDBResults = true;
                    }
                }
                finally
                {
                    m_Results.Unlock();
                }
            }
            else if (!activateSearchDB || m_SearchType == SearchType.OnlyNetwork)
            {
                m_SearchedInDatabase = true;
                m_GotSearchDBResults = true;
            }

            if (m_SearchedInDatabase && m_GotSearchDBResults && m_SearchCommandsToSent > 0 && DateTime.Now.Subtract(m_LastSent).TotalSeconds >= Constants.Command20Interval)
            {
                Core.SendCommand20(m_SearchFloodingHash, m_SearchPeerID, m_SearchID, m_SearchPattern);
                m_LastSent = DateTime.Now;
                m_SearchCommandsToSent--;
            }
        }
示例#9
0
            public void AddSource(byte[] id, string fileName, RIndexedHashtable <string, string> metaData, string comment, byte rating)
            {
                if (id == null)
                {
                    throw new ArgumentNullException("id");
                }
                if (id.Length != 48)
                {
                    throw new ArgumentException();
                }
                if (fileName == null)
                {
                    throw new ArgumentNullException("fileName");
                }
                if (metaData == null)
                {
                    throw new ArgumentNullException("metaData");
                }
                if (comment == null)
                {
                    throw new ArgumentNullException("comment");
                }
                if (rating > 3)
                {
                    throw new ArgumentOutOfRangeException("rating");
                }

                try
                {
                    m_Sources.Lock();
                    string idString = Core.ByteArrayToString(id);
                    if (!m_Sources.ContainsKey(idString))
                    {
                        m_Sources.Add(idString, new Source(m_Sources, id, fileName, metaData, comment, rating));
                    }
                    else
                    {
                        m_Sources[idString].ReportReceived(fileName, comment, rating);
                    }
                    RIndexedHashtable <string, int> fileNames1 = new RIndexedHashtable <string, int>();
                    RIndexedHashtable <byte, int>   ratings1   = new RIndexedHashtable <byte, int>();
                    foreach (Source source in m_Sources.Values)
                    {
                        if (!fileNames1.ContainsKey(source.FileName))
                        {
                            fileNames1.Add(source.FileName, 1);
                        }
                        else
                        {
                            fileNames1[source.FileName]++;
                        }
                        if (!ratings1.ContainsKey(source.Rating))
                        {
                            ratings1.Add(source.Rating, 1);
                        }
                        else
                        {
                            ratings1[source.Rating]++;
                        }
                    }
                    RList <string> fileNames2 = new RList <string>(fileNames1.Keys);
                    for (int n = 1; n <= fileNames2.Count - 1; n++)
                    {
                        for (int m = 0; m < fileNames2.Count - n; m++)
                        {
                            if (fileNames1[fileNames2[m]] < fileNames1[fileNames2[m + 1]])
                            {
                                string temp;
                                temp              = fileNames2[m];
                                fileNames2[m]     = fileNames2[m + 1];
                                fileNames2[m + 1] = temp;
                            }
                        }
                    }
                    m_FileName = fileNames2[0];
                    RList <byte> ratings2 = new RList <byte>(ratings1.Keys);
                    for (int n = 1; n <= ratings2.Count - 1; n++)
                    {
                        for (int m = 0; m < ratings2.Count - n; m++)
                        {
                            if (ratings1[ratings2[m]] < ratings1[ratings2[m + 1]])
                            {
                                byte temp;
                                temp            = ratings2[m];
                                ratings2[m]     = ratings2[m + 1];
                                ratings2[m + 1] = temp;
                            }
                        }
                    }
                    ratings2.Remove(0);
                    if (!ratings2.IsEmpty)
                    {
                        m_Rating = ratings2[0];
                    }
                    else
                    {
                        m_Rating = 0;
                    }
                    foreach (KeyValuePair <string, string> metaDataItem in metaData)
                    {
                        if (!m_MetaData.ContainsKey(metaDataItem.Key))
                        {
                            m_MetaData.Add(metaDataItem.Key, metaDataItem.Value);
                        }
                    }
                    Core.ParseMetaData(m_MetaData, out m_Album, out m_Artist, out m_Title);
                }
                finally
                {
                    m_Sources.Unlock();
                }
            }
示例#10
0
        public void AddSource(byte[] id, long fileSize, string fileName, RIndexedHashtable<string, string> metaData, string comment, byte rating, byte[] sectorsMap)
        {
            if (id == null)
                throw new ArgumentNullException("id");
            if (id.Length != 48)
                throw new ArgumentException();
            if (fileSize < 0)
                throw new ArgumentOutOfRangeException("fileSize");
            if (fileName == null)
                throw new ArgumentNullException("fileName");
            if (metaData == null)
                throw new ArgumentNullException("metaData");
            if (comment == null)
                throw new ArgumentNullException("comment");
            if (rating > 3)
                throw new ArgumentOutOfRangeException("rating");

            if (m_IsHashing)
                return;
            try
            {
                // 2007-06-14 T.Norad
                // set current time as last seen in this download
                m_LastSeen = DateTime.Now;
                m_Sources.Lock();
                string idString = Core.ByteArrayToString(id);
                if (!m_Sources.ContainsKey(idString))
                    m_Sources.Add(idString, new Source(m_Sources, id, fileName, metaData, comment, rating, sectorsMap));
                else
                    m_Sources[idString].Report5354Received(fileName, metaData, comment, rating, sectorsMap);
                RIndexedHashtable<string, int> fileNames1 = new RIndexedHashtable<string, int>();
                RIndexedHashtable<byte, int> ratings1 = new RIndexedHashtable<byte, int>();
                foreach (Source source in m_Sources.Values)
                {
                    if (!source.HasInformation)
                        continue;
                    if (!fileNames1.ContainsKey(source.FileName))
                        fileNames1.Add(source.FileName, 1);
                    else
                        fileNames1[source.FileName]++;
                    if (!ratings1.ContainsKey(source.Rating))
                        ratings1.Add(source.Rating, 1);
                    else
                        ratings1[source.Rating]++;
                }
                RList<string> fileNames2 = new RList<string>(fileNames1.Keys);
                for (int n = 1; n <= fileNames2.Count - 1; n++)
                    for (int m = 0; m < fileNames2.Count - n; m++)
                    {
                        if (fileNames1[fileNames2[m]] < fileNames1[fileNames2[m + 1]])
                        {
                            string temp;
                            temp = fileNames2[m];
                            fileNames2[m] = fileNames2[m + 1];
                            fileNames2[m + 1] = temp;
                        }
                    }
                fileNames2.Remove(string.Empty);
                if (!fileNames2.IsEmpty)
                {
                    m_FileName = fileNames2[0];
                }
                else
                {
                    m_FileName = m_FileHashString;
                }
                RList<byte> ratings2 = new RList<byte>(ratings1.Keys);
                for (int n = 1; n <= ratings2.Count - 1; n++)
                    for (int m = 0; m < ratings2.Count - n; m++)
                    {
                        if (ratings1[ratings2[m]] < ratings1[ratings2[m + 1]])
                        {
                            byte temp;
                            temp = ratings2[m];
                            ratings2[m] = ratings2[m + 1];
                            ratings2[m + 1] = temp;
                        }
                    }
                ratings2.Remove(0);
                if (!ratings2.IsEmpty)
                    m_Rating = ratings2[0];
                else
                    m_Rating = 0;
                foreach (KeyValuePair<string, string> metaDataItem in metaData)
                    if (!m_MetaData.ContainsKey(metaDataItem.Key))
                        m_MetaData.Add(metaDataItem.Key, metaDataItem.Value);
                Core.ParseMetaData(m_MetaData, out m_Album, out m_Artist, out m_Title);
                if (!m_HasInformation)
                {
                    m_FileSize = fileSize;
                    m_FileSizeString = Core.LengthToString(m_FileSize);
                    m_Sectors = m_FileSize / 32768;
                    m_SectorsMap = new byte[(m_Sectors / 8) + 1];
                    for (long n = m_Sectors + 1; n < m_SectorsMap.Length * 8; n++)
                        m_SectorsMap[n / 8] |= (byte)(1 << ((int)n % 8));
                    FillWithZeros();
                    m_HasInformation = true;
                }
            }
            finally
            {
                m_Sources.Unlock();
            }
        }
示例#11
0
 /// <summary>
 /// Neue ResumeDownloads()
 /// 10.06.2009 Lars
 /// 03.07.2009 Lars (Neue Downloadwarteschlange)
 /// 04.07.2009 Lars (Einfacheres und besseres Handling)
 /// </summary>
 private static void ResumeDownloads()
 {
     try
     {
         // Alle gesicherten Downloads einlesen
         RIndexedHashtable<string, XmlNode> downloadsXml = new RIndexedHashtable<string, XmlNode>();
         if (File.Exists(m_DownloadsFilePath))
         {
             XmlDocument downloadsXmlDocument = new XmlDocument();
             downloadsXmlDocument.Load(m_DownloadsFilePath);
             foreach (XmlNode downloadNode in downloadsXmlDocument.SelectSingleNode("downloads"))
                 try
                 {
                     downloadsXml.Add(downloadNode.Attributes["hash"].InnerText, downloadNode);
                 }
                 catch (Exception ex)
                 {
                     m_Logger.Log(ex, "A download cannot be resumed due to non existent information about it!");
                     continue;
                 }
         }
         // Alle vorhandenen Dateien durchgehen
         RList<Download> temporary = new RList<Download>(downloadsXml.Count);
         foreach (string filePath in Directory.GetFiles(Settings.Instance["TemporaryDirectory"]))
         {
             string fileName = new FileInfo(filePath).Name;
             try
             {
                 if (!Regex.IsMatch(fileName, "^[0-9A-F]{128,128}$", RegexOptions.IgnoreCase))
                 {
                     m_Logger.Log("The file \"{0}\" is no valid temporary download!", fileName);
                 }
                 XmlNode node;
                 if (!downloadsXml.TryGetValue(fileName, out node))
                 {
                     m_Logger.Log("The download of \"{0}\" cannot be resumed due to non existent information about it!", fileName);
                     continue;
                 }
                 bool hasInformation = true;
                 if ((node as XmlElement).HasAttribute("hasinformation") && (node as XmlElement).GetAttribute("hasinformation") == "none")
                     hasInformation = false;
                 string lastSeenString = null;
                 DateTime? lastSeen = null;
                 string lastReceptionString = null;
                 DateTime? lastReception = null;
                 String subfolder = string.Empty;
                 if (node.SelectSingleNode("lastseen") != null)
                 {
                     lastSeenString = node.SelectSingleNode("lastseen").InnerText;
                     if (lastSeenString != null && lastSeenString.Length > 0)
                         lastSeen = DateTime.Parse(lastSeenString);
                 }
                 if (node.SelectSingleNode("lastreception") != null)
                 {
                     lastReceptionString = node.SelectSingleNode("lastreception").InnerText;
                     if (lastReceptionString != null && lastReceptionString.Length > 0)
                         lastReception = DateTime.Parse(lastReceptionString);
                 }
                 if (node.SelectSingleNode("subfolder") != null)
                     subfolder = node.SelectSingleNode("subfolder").InnerText;
                 Download download = new Download(Core.FileHashStringToFileHash(fileName), node.SelectSingleNode("filename").InnerText, long.Parse(node.SelectSingleNode("filesize").InnerText), hasInformation, lastSeen, lastReception, hasInformation ? Convert.FromBase64String(node.SelectSingleNode("sectorsmap").InnerText) : null);
                 download.SetSubFolderAndTime(subfolder, null);
                 temporary.Add(download);
             }
             catch (Exception ex)
             {
                 m_Logger.Log(ex, "An exception was thrown while resuming the download of \"{0}\"!", fileName);
             }
         }
         // Wiederaufzunehmende Download sortieren
         for (int n = 1; n <= temporary.Count - 1; n++)
             for (int m = 0; m < temporary.Count - n; m++)
             {
                 Download a = temporary[m];
                 Download b = temporary[m + 1];
                 if (downloadsXml.IndexOfKey(a.FileHashString) > downloadsXml.IndexOfKey(b.FileHashString))
                 {
                     temporary[m] = b;
                     temporary[m + 1] = a;
                 }
             }
         // Downloads wiederaufnehmen
         try
         {
             m_DownloadsAndQueue.Lock();
             foreach (Download download in temporary)
                 m_DownloadsAndQueue.Add(download);
         }
         finally
         {
             m_DownloadsAndQueue.Unlock();
         }
     }
     catch (Exception ex)
     {
         m_Logger.Log(ex, "An exception was thrown while resuming downloads!");
     }
     finally
     {
         // Erst jetzt kann die downloads.xml wieder geschreiben werden...
         DownloadsXmlWriter.SetIsReady();
     }
 }
示例#12
0
            public void AddSource(byte[] id, string fileName, RIndexedHashtable<string, string> metaData, string comment, byte rating)
            {
                if (id == null)
                    throw new ArgumentNullException("id");
                if (id.Length != 48)
                    throw new ArgumentException();
                if (fileName == null)
                    throw new ArgumentNullException("fileName");
                if (metaData == null)
                    throw new ArgumentNullException("metaData");
                if (comment == null)
                    throw new ArgumentNullException("comment");
                if (rating > 3)
                    throw new ArgumentOutOfRangeException("rating");

                try
                {
                    m_Sources.Lock();
                    string idString = Core.ByteArrayToString(id);
                    if (!m_Sources.ContainsKey(idString))
                        m_Sources.Add(idString, new Source(m_Sources, id, fileName, metaData, comment, rating));
                    else
                        m_Sources[idString].ReportReceived(fileName, comment, rating);
                    RIndexedHashtable<string, int> fileNames1 = new RIndexedHashtable<string, int>();
                    RIndexedHashtable<byte, int> ratings1 = new RIndexedHashtable<byte, int>();
                    foreach (Source source in m_Sources.Values)
                    {
                        if (!fileNames1.ContainsKey(source.FileName))
                            fileNames1.Add(source.FileName, 1);
                        else
                            fileNames1[source.FileName]++;
                        if (!ratings1.ContainsKey(source.Rating))
                            ratings1.Add(source.Rating, 1);
                        else
                            ratings1[source.Rating]++;
                    }
                    RList<string> fileNames2 = new RList<string>(fileNames1.Keys);
                    for (int n = 1; n <= fileNames2.Count - 1; n++)
                        for (int m = 0; m < fileNames2.Count - n; m++)
                        {
                            if (fileNames1[fileNames2[m]] < fileNames1[fileNames2[m + 1]])
                            {
                                string temp;
                                temp = fileNames2[m];
                                fileNames2[m] = fileNames2[m + 1];
                                fileNames2[m + 1] = temp;
                            }
                        }
                    m_FileName = fileNames2[0];
                    RList<byte> ratings2 = new RList<byte>(ratings1.Keys);
                    for (int n = 1; n <= ratings2.Count - 1; n++)
                        for (int m = 0; m < ratings2.Count - n; m++)
                        {
                            if (ratings1[ratings2[m]] < ratings1[ratings2[m + 1]])
                            {
                                byte temp;
                                temp = ratings2[m];
                                ratings2[m] = ratings2[m + 1];
                                ratings2[m + 1] = temp;
                            }
                        }
                    ratings2.Remove(0);
                    if (!ratings2.IsEmpty)
                        m_Rating = ratings2[0];
                    else
                        m_Rating = 0;
                    foreach (KeyValuePair<string, string> metaDataItem in metaData)
                        if (!m_MetaData.ContainsKey(metaDataItem.Key))
                            m_MetaData.Add(metaDataItem.Key, metaDataItem.Value);
                    Core.ParseMetaData(m_MetaData, out m_Album, out m_Artist, out m_Title);
                }
                finally
                {
                    m_Sources.Unlock();
                }
            }
示例#13
0
        public SearchDBManager(string fileName)
        {
            m_FilePath = fileName;

            m_CleanUpDays = int.Parse(m_Settings["SearchDBCleanUpDays"]);

            m_SearchDBThread = new Thread(delegate()
            {
                try
                {
                    Core.SetUILanguage();

                    while (!m_IsClosing && m_ErrorCounter < 10)
                    {
                        //Move buffers to normal list
                        try
                        {
                            m_SearchesToStartBuffer.Lock();
                            m_SearchesToStart.Lock();

                            foreach (SearchDBManager.SearchToStart newSearch in m_SearchesToStartBuffer)
                            {
                                if (!m_SearchesToStart.Contains(newSearch))
                                {
                                    m_SearchesToStart.Add(newSearch);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            m_Logger.Log(ex, "SearchDBManager: An error was thrown while reading the SearchesToStartBuffer.", new object[] { });
                        }
                        finally
                        {
                            m_SearchesToStartBuffer.Clear();

                            m_SearchesToStart.Unlock();
                            m_SearchesToStartBuffer.Unlock();
                        }

                        try
                        {
                            m_ResultsToAddBuffer.Lock();
                            m_ResultsToAdd.Lock();

                            foreach (Command23.SearchResult result in m_ResultsToAddBuffer)
                            {
                                if (!m_ResultsToAdd.Contains(result))
                                {
                                    m_ResultsToAdd.Add(result);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            m_Logger.Log(ex, "SearchDBManager: An error was thrown while reading the ResultsToAddBuffer.", new object[] { });
                        }
                        finally
                        {
                            m_ResultsToAddBuffer.Clear();

                            m_ResultsToAdd.Unlock();
                            m_ResultsToAddBuffer.Unlock();
                        }



                        //Because we are only comparing dates, it is only necessary to compare them once a day
                        bool cleanUp = false;
                        if (((TimeSpan)DateTime.Now.Subtract(m_LastCleanUp)).Days >= 1)
                        {
                            //CleanUp();
                            cleanUp = true;
                        }

                        //The current entry
                        long lastKnownValidFilePosition = 0;
                        //The entry before
                        long lastKnownValidFilePosition2 = 0;

                        ulong fileSizeOfEntries = 0;
                        long cleanedUpCounter   = 0;
                        long resultCounter      = 0;

                        FileStream fileStream   = null;
                        BinaryReader fileReader = null;
                        BinaryWriter fileWriter = null;

                        MemoryStream memoryStream = null;
                        BinaryReader memoryReader = null;
                        BinaryWriter memoryWriter = null;

                        try
                        {
                            m_ResultsToAdd.Lock();
                            m_SearchesToStart.Lock();
                            m_SearchResultsBuffer.Lock();

                            //Check if there is something to do
                            if (m_ResultsToAdd.Count > 0 || m_SearchesToStart.Count > 0 || cleanUp)
                            {
                                fileStream = new FileStream(m_FilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                                fileReader = new BinaryReader(fileStream, Encoding.Unicode);
                                fileWriter = new BinaryWriter(fileStream, Encoding.Unicode);

                                memoryStream = new MemoryStream();
                                memoryReader = new BinaryReader(memoryStream, Encoding.Unicode);
                                memoryWriter = new BinaryWriter(memoryStream, Encoding.Unicode);

                                long fileLength          = fileReader.BaseStream.Length;
                                int fileFlushCounter     = 0;
                                long fileReadPosition    = 0;
                                long fileWritePosition   = 0;
                                bool insertingData       = false;
                                bool isFirstChangedEntry = true;


                                //Add a array for the results of each search
                                foreach (SearchToStart searchToStart in m_SearchesToStart)
                                {
                                    m_SearchResultsBuffer.Add(searchToStart.SearchID, new RIndexedHashtable <string, OldSearchResult>());
                                }


                                //Go through the file
                                while (fileReadPosition < fileLength)
                                {
                                    bool isOld = false;

                                    long firstPositionOfThisEntry = fileReadPosition;

                                    lastKnownValidFilePosition2 = lastKnownValidFilePosition;
                                    lastKnownValidFilePosition  = fileReadPosition;

                                    //Read the next entry
                                    byte[] rFileHash    = fileReader.ReadBytes(64);
                                    long rFileSize      = fileReader.ReadInt64();
                                    int rFileNameCount  = fileReader.ReadInt32();
                                    string[] rFileNames = new string[rFileNameCount];
                                    for (int i = 0; i < rFileNameCount; i++)
                                    {
                                        rFileNames[i] = fileReader.ReadString();
                                    }
                                    string rAlbum  = fileReader.ReadString();
                                    string rArtist = fileReader.ReadString();
                                    string rTitle  = fileReader.ReadString();
                                    byte rRating   = fileReader.ReadByte();
                                    //Save the position of the date
                                    long datePosition = fileReader.BaseStream.Position;
                                    string rDate      = fileReader.ReadString();

                                    //Save the beginning of the next entry
                                    fileReadPosition = fileReader.BaseStream.Position;

                                    resultCounter++;

                                    //Check if this entry is a result to a search
                                    for (int i = 0; i < m_SearchesToStart.Count; i++)
                                    {
                                        string[] searchPattern = m_SearchesToStart[i].Pattern.ToLower().Split(new char[] { ' ' });;

                                        //Remove all small patterns
                                        RList <string> patterns = new RList <string>();
                                        for (int k = 0; k < searchPattern.Length; k++)
                                        {
                                            if (searchPattern[k].Length >= 3)
                                            {
                                                patterns.Add(searchPattern[k]);
                                            }
                                        }

                                        bool isResult      = false;
                                        int fileNameNumber = 0;

                                        for (int j = 0; j < patterns.Count; j++)
                                        {
                                            //Check all filenames of this entry
                                            for (int k = 0; k < rFileNames.Length; k++)
                                            {
                                                if (rFileNames[k].ToLower().Contains(patterns[j]))
                                                {
                                                    fileNameNumber = k;
                                                    isResult       = true;
                                                }
                                            }

                                            //Check the metadata of this entry
                                            if (!isResult)
                                            {
                                                if (rAlbum.ToLower().Contains(patterns[j]))
                                                {
                                                    isResult = true;
                                                }
                                                else if (rArtist.ToLower().Contains(patterns[j]))
                                                {
                                                    isResult = true;
                                                }
                                                else if (rTitle.ToLower().Contains(patterns[j]))
                                                {
                                                    isResult = true;
                                                }
                                            }

                                            //if this is no result for this part of the searchpattern,
                                            //we can stop, because there shall be only results with all
                                            //parts of the searchpattern.
                                            if (isResult == false)
                                            {
                                                break;
                                            }

                                            //Reset isResult for the next part of the searchpattern
                                            if (j != patterns.Count - 1)
                                            {
                                                isResult = false;
                                            }
                                        }

                                        if (isResult)
                                        {
                                            //Add this entry to the results of this search
                                            m_SearchResultsBuffer[m_SearchesToStart[i].SearchID].Add(Core.ByteArrayToString(rFileHash), new OldSearchResult(rFileHash, rFileSize, rFileNames[fileNameNumber], rAlbum, rArtist, rTitle, rRating, DateTime.Parse(rDate)));
                                        }
                                    }



                                    bool updateDate = false;
                                    int[] indexOfResultsToRemove = new int[0];

                                    //Check if a new result is equal to this entry
                                    for (int i = 0; i < m_ResultsToAdd.Count; i++)
                                    {
                                        //Compare the hashes
                                        if (Core.CompareByteArray(rFileHash, m_ResultsToAdd[i].FileHash))
                                        {
                                            //It exists already
                                            updateDate = true;

                                            int[] tempArray1 = new int[indexOfResultsToRemove.Length + 1];
                                            for (int j = 0; j < indexOfResultsToRemove.Length; j++)
                                            {
                                                tempArray1[j] = indexOfResultsToRemove[j];
                                            }
                                            tempArray1[indexOfResultsToRemove.Length] = i;
                                            indexOfResultsToRemove = tempArray1;

                                            //Check the filenames
                                            bool fileNameExists = false;
                                            for (int k = 0; k < rFileNames.Length; k++)
                                            {
                                                if (rFileNames[k] == m_ResultsToAdd[i].FileName)
                                                {
                                                    fileNameExists = true;
                                                    break;
                                                }
                                            }

                                            if (!fileNameExists)
                                            {
                                                //The filename is new -> add it
                                                insertingData = true;

                                                string[] tempArray = new string[rFileNameCount + 1];
                                                for (int k = 0; k < rFileNameCount; k++)
                                                {
                                                    tempArray[k] = rFileNames[k];
                                                }
                                                tempArray[rFileNameCount] = m_ResultsToAdd[i].FileName;
                                                rFileNames = tempArray;
                                                rFileNameCount++;
                                            }
                                        }
                                    }


                                    if (updateDate)
                                    {
                                        //Update the date
                                        rDate = DateTime.Now.ToString(m_DateFormatString);

                                        //Remove the new result from the list, because it exists
                                        RList <Command23.SearchResult> tempRemoveList = new RList <Command23.SearchResult>();
                                        for (int i = 0; i < m_ResultsToAdd.Count; i++)
                                        {
                                            bool addIt = false;
                                            for (int k = 0; k < indexOfResultsToRemove.Length; k++)
                                            {
                                                if (i == indexOfResultsToRemove[k])
                                                {
                                                    addIt = true;
                                                }
                                            }

                                            if (addIt)
                                            {
                                                tempRemoveList.Add(m_ResultsToAdd[i]);
                                            }
                                        }
                                        foreach (Command23.SearchResult r in tempRemoveList)
                                        {
                                            m_ResultsToAdd.Remove(r);
                                        }

                                        //Check if we can update the date directly in the file
                                        if (!insertingData)
                                        {
                                            //Write the new date to the file
                                            fileWriter.BaseStream.Position = datePosition;
                                            fileWriter.Write(rDate);
                                            fileWriter.Flush();
                                            fileReader.BaseStream.Position = fileReadPosition;
                                        }
                                    }

                                    //Check the date if we are cleaning up
                                    if (cleanUp)
                                    {
                                        if (((TimeSpan)DateTime.Now.Subtract(DateTime.Parse(rDate))).Days > m_CleanUpDays)
                                        {
                                            isOld         = true;
                                            insertingData = true;
                                            cleanedUpCounter++;
                                        }
                                        else
                                        {
                                            fileSizeOfEntries += (ulong)rFileSize;
                                        }
                                    }
                                    else
                                    {
                                        fileSizeOfEntries += (ulong)rFileSize;
                                    }

                                    //Check if we have to insert data to the file
                                    if (insertingData)
                                    {
                                        if (isFirstChangedEntry)
                                        {
                                            //Here we have to beginn writing
                                            fileWritePosition   = firstPositionOfThisEntry;
                                            isFirstChangedEntry = false;
                                        }

                                        if (!isOld)
                                        {
                                            fileFlushCounter++;

                                            //Write the entry to the buffer
                                            memoryWriter.Write(rFileHash);
                                            memoryWriter.Write(rFileSize);
                                            memoryWriter.Write(rFileNameCount);
                                            for (int i = 0; i < rFileNameCount; i++)
                                            {
                                                memoryWriter.Write(rFileNames[i]);
                                            }
                                            memoryWriter.Write(rAlbum);
                                            memoryWriter.Write(rArtist);
                                            memoryWriter.Write(rTitle);
                                            memoryWriter.Write(rRating);
                                            memoryWriter.Write(rDate);

                                            //if the buffer is big enough or we reached the end of the file, write the buffe to the file
                                            if (fileFlushCounter == 10000 || fileReadPosition >= fileLength)
                                            {
                                                fileFlushCounter = 0;

                                                memoryWriter.Flush();

                                                memoryReader.BaseStream.Position = 0;
                                                fileWriter.BaseStream.Position   = fileWritePosition;

                                                long memoryLength = memoryReader.BaseStream.Length;
                                                long spaceInFile  = fileReadPosition - fileWritePosition;

                                                //write only as much as space and data we have
                                                while (memoryReader.BaseStream.Position < spaceInFile && memoryReader.BaseStream.Position < memoryLength)
                                                {
                                                    fileWriter.Write(memoryReader.ReadByte());
                                                }
                                                fileWriter.Flush();

                                                //Reconfigure the filewriter/reader
                                                fileWritePosition = fileWriter.BaseStream.Position;
                                                fileReader.BaseStream.Position = fileReadPosition;

                                                //Write the rest of the data in the buffer to the beginning of the buffer
                                                long memoryReaderPosition = memoryReader.BaseStream.Position;
                                                long memoryWriterPosition = 0;

                                                while (memoryReaderPosition < memoryLength)
                                                {
                                                    memoryReader.BaseStream.Position = memoryReaderPosition;

                                                    byte b = memoryReader.ReadByte();

                                                    memoryReaderPosition             = memoryReader.BaseStream.Position;
                                                    memoryWriter.BaseStream.Position = memoryWriterPosition;

                                                    memoryWriter.Write(b);

                                                    memoryWriterPosition = memoryWriter.BaseStream.Position;
                                                }
                                                memoryWriter.Flush();

                                                memoryWriter.BaseStream.SetLength(memoryWriterPosition);
                                            }
                                        }
                                    }
                                }

                                if (insertingData)
                                {
                                    //write the rest of the memorystream to the file.
                                    fileWriter.BaseStream.Position = fileWritePosition;

                                    long mlength = memoryReader.BaseStream.Length;
                                    memoryReader.BaseStream.Position = 0;
                                    while (memoryReader.BaseStream.Position < mlength)
                                    {
                                        fileWriter.Write(memoryReader.ReadByte());
                                    }
                                    fileWriter.Flush();
                                }

                                if (cleanUp)
                                {
                                    m_Logger.Log(Properties.Resources_Core.CleanSearchDatabase, new object[] { cleanedUpCounter, resultCounter });
                                    resultCounter     -= cleanedUpCounter;
                                    m_LastCleanUpCount = cleanedUpCounter;
                                }

                                //Add the new results to the file
                                //The position of the filestream points already to the end
                                RIndexedHashtable <string, NewSearchResult> resultsToAdd = new RIndexedHashtable <string, NewSearchResult>();
                                foreach (Command23.SearchResult result in m_ResultsToAdd)
                                {
                                    string fileHashString = Core.ByteArrayToString(result.FileHash);

                                    if (resultsToAdd.ContainsKey(fileHashString))
                                    {
                                        resultsToAdd[fileHashString].AddFileName(result.FileName);
                                    }
                                    else
                                    {
                                        resultsToAdd.Add(fileHashString, new NewSearchResult(result));
                                    }
                                }


                                foreach (NewSearchResult newResult in resultsToAdd.Values)
                                {
                                    fileWriter.Write(newResult.FileHash);
                                    fileWriter.Write(newResult.FileSize);
                                    int fileNameCount = newResult.FileNames.Length;
                                    fileWriter.Write(fileNameCount);
                                    for (int i = 0; i < fileNameCount; i++)
                                    {
                                        fileWriter.Write(newResult.FileNames[i]);
                                    }
                                    fileWriter.Write(newResult.Album);
                                    fileWriter.Write(newResult.Artist);
                                    fileWriter.Write(newResult.Title);
                                    fileWriter.Write(newResult.Rating);
                                    fileWriter.Write(DateTime.Now.ToString(m_DateFormatString));
                                    resultCounter++;
                                    fileSizeOfEntries += (ulong)newResult.FileSize;
                                }
                                fileWriter.Flush();

                                //Clear the lists
                                m_ResultsToAdd.Clear();
                                m_SearchesToStart.Clear();

                                //Set the correct end of the file
                                if (insertingData)
                                {
                                    fileWriter.BaseStream.SetLength(fileWriter.BaseStream.Position);
                                }

                                if (cleanUp)
                                {
                                    m_LastCleanUp = DateTime.Now;
                                }

                                //Update information
                                m_ResultCount       = resultCounter;
                                m_FileSize          = fileStream.Length;
                                m_FileSizeOfEntries = fileSizeOfEntries;

                                fileReader.Close();
                                fileWriter.Close();
                                fileStream.Close();

                                memoryReader.Close();
                                memoryWriter.Close();
                                memoryStream.Close();
                            }
                        }
                        catch (Exception ex)
                        {
                            //Update information
                            m_ResultCount       = resultCounter;
                            m_FileSize          = fileStream.Length;
                            m_FileSizeOfEntries = fileSizeOfEntries;

                            m_ErrorCounter++;
                            m_Logger.Log(ex, "An exception was thrown in searchDBThread! (#{0})", new object[] { m_ErrorCounter });
                            try
                            {
                                fileStream.SetLength(lastKnownValidFilePosition2);
                                m_Logger.Log("Searchdatabase cutted to the entry bofore the last known valid entry. ({0} Bytes remaining)", new object[] { lastKnownValidFilePosition });
                                m_FileSize          = lastKnownValidFilePosition2;
                                m_ResultCount       = resultCounter - cleanedUpCounter;
                                m_FileSizeOfEntries = fileSizeOfEntries;
                            }
                            catch
                            {
                                try
                                {
                                    if (File.Exists(m_FilePath))
                                    {
                                        File.Delete(m_FilePath);
                                        m_Logger.Log("Searchdatabase deleted, because it was probably corrupt.", new object[] { });
                                        m_FileSize          = 0;
                                        m_ResultCount       = 0;
                                        m_FileSizeOfEntries = 0;
                                    }
                                }
                                catch { }
                            }
                        }
                        finally
                        {
                            m_ResultsToAdd.Unlock();
                            m_SearchesToStart.Unlock();
                            m_SearchResultsBuffer.Unlock();

                            if (fileReader != null)
                            {
                                fileReader.Close();
                            }
                            if (fileWriter != null)
                            {
                                fileWriter.Close();
                            }
                            if (fileStream != null)
                            {
                                fileStream.Close();
                            }

                            if (memoryReader != null)
                            {
                                memoryReader.Close();
                            }
                            if (memoryWriter != null)
                            {
                                memoryWriter.Close();
                            }
                            if (memoryStream != null)
                            {
                                memoryStream.Close();
                            }
                        }


                        //Move buffer to normal list
                        try
                        {
                            m_SearchResultsBuffer.Lock();
                            m_SearchResults.Lock();

                            for (int i = 0; i < m_SearchResultsBuffer.Count; i++)
                            {
                                if (!m_SearchResults.ContainsKey(((System.Collections.Generic.KeyValuePair <string, RIndexedHashtable <string, OldSearchResult> >)m_SearchResultsBuffer[i]).Key))
                                {
                                    m_SearchResults.Add(((System.Collections.Generic.KeyValuePair <string, RIndexedHashtable <string, OldSearchResult> >)m_SearchResultsBuffer[i]).Key, ((System.Collections.Generic.KeyValuePair <string, RIndexedHashtable <string, OldSearchResult> >)m_SearchResultsBuffer[i]).Value);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            m_Logger.Log(ex, "SearchDBManager: An error was thrown while reading the SearchResultsBuffer.", new object[] { });
                        }
                        finally
                        {
                            m_SearchResultsBuffer.Clear();

                            m_SearchResults.Unlock();
                            m_SearchResultsBuffer.Unlock();
                        }


                        Thread.Sleep(1000);
                    }
                }
                catch (Exception ex)
                {
                    m_Logger.Log(ex, "An exception was thrown in searchDBThread!", new object[] { });
                }

                m_Logger.Log("SearchDBManager closed.", new object[] {  });
            });
            m_SearchDBThread.Name         = "searchDBThread";
            m_SearchDBThread.IsBackground = true;
            m_SearchDBThread.Priority     = ThreadPriority.Lowest;
            m_SearchDBThread.Start();
        }
示例#14
0
        public SearchDBManager(string fileName )
        {
            m_FilePath = fileName;

            m_CleanUpDays = int.Parse(m_Settings["SearchDBCleanUpDays"]);

            m_SearchDBThread = new Thread(delegate()
            {
                try
                {
                    Core.SetUILanguage();

                    while (!m_IsClosing && m_ErrorCounter < 10)
                    {
                        //Move buffers to normal list
                        try
                        {
                            m_SearchesToStartBuffer.Lock();
                            m_SearchesToStart.Lock();

                            foreach (SearchDBManager.SearchToStart newSearch in m_SearchesToStartBuffer)
                            {
                                if (!m_SearchesToStart.Contains(newSearch))
                                {
                                    m_SearchesToStart.Add(newSearch);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            m_Logger.Log(ex, "SearchDBManager: An error was thrown while reading the SearchesToStartBuffer.", new object[] { });
                        }
                        finally
                        {
                            m_SearchesToStartBuffer.Clear();

                            m_SearchesToStart.Unlock();
                            m_SearchesToStartBuffer.Unlock();
                        }

                        try
                        {
                            m_ResultsToAddBuffer.Lock();
                            m_ResultsToAdd.Lock();

                            foreach (Command23.SearchResult result in m_ResultsToAddBuffer)
                            {
                                if (!m_ResultsToAdd.Contains(result))
                                {
                                    m_ResultsToAdd.Add(result);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            m_Logger.Log(ex, "SearchDBManager: An error was thrown while reading the ResultsToAddBuffer.", new object[] { });
                        }
                        finally
                        {
                            m_ResultsToAddBuffer.Clear();

                            m_ResultsToAdd.Unlock();
                            m_ResultsToAddBuffer.Unlock();
                        }

                        //Because we are only comparing dates, it is only necessary to compare them once a day
                        bool cleanUp = false;
                        if (((TimeSpan)DateTime.Now.Subtract(m_LastCleanUp)).Days >= 1)
                        {
                            //CleanUp();
                            cleanUp = true;
                        }

                        //The current entry
                        long lastKnownValidFilePosition = 0;
                        //The entry before
                        long lastKnownValidFilePosition2 = 0;

                        ulong fileSizeOfEntries = 0;
                        long cleanedUpCounter = 0;
                        long resultCounter = 0;

                        FileStream fileStream = null;
                        BinaryReader fileReader = null;
                        BinaryWriter fileWriter = null;

                        MemoryStream memoryStream = null;
                        BinaryReader memoryReader = null;
                        BinaryWriter memoryWriter = null;

                        try
                        {
                            m_ResultsToAdd.Lock();
                            m_SearchesToStart.Lock();
                            m_SearchResultsBuffer.Lock();

                            //Check if there is something to do
                            if (m_ResultsToAdd.Count > 0 || m_SearchesToStart.Count > 0 || cleanUp)
                            {
                                fileStream = new FileStream(m_FilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                                fileReader = new BinaryReader(fileStream, Encoding.Unicode);
                                fileWriter = new BinaryWriter(fileStream, Encoding.Unicode);

                                memoryStream = new MemoryStream();
                                memoryReader = new BinaryReader(memoryStream, Encoding.Unicode);
                                memoryWriter = new BinaryWriter(memoryStream, Encoding.Unicode);

                                long fileLength = fileReader.BaseStream.Length;
                                int fileFlushCounter = 0;
                                long fileReadPosition = 0;
                                long fileWritePosition = 0;
                                bool insertingData = false;
                                bool isFirstChangedEntry = true;

                                //Add a array for the results of each search
                                foreach (SearchToStart searchToStart in m_SearchesToStart)
                                {
                                    m_SearchResultsBuffer.Add(searchToStart.SearchID, new RIndexedHashtable<string, OldSearchResult>());
                                }

                                //Go through the file
                                while (fileReadPosition < fileLength)
                                {
                                    bool isOld = false;

                                    long firstPositionOfThisEntry = fileReadPosition;

                                    lastKnownValidFilePosition2 = lastKnownValidFilePosition;
                                    lastKnownValidFilePosition = fileReadPosition;

                                    //Read the next entry
                                    byte[] rFileHash = fileReader.ReadBytes(64);
                                    long rFileSize = fileReader.ReadInt64();
                                    int rFileNameCount = fileReader.ReadInt32();
                                    string[] rFileNames = new string[rFileNameCount];
                                    for (int i = 0; i < rFileNameCount; i++)
                                    {
                                        rFileNames[i] = fileReader.ReadString();
                                    }
                                    string rAlbum = fileReader.ReadString();
                                    string rArtist = fileReader.ReadString();
                                    string rTitle = fileReader.ReadString();
                                    byte rRating = fileReader.ReadByte();
                                    //Save the position of the date
                                    long datePosition = fileReader.BaseStream.Position;
                                    string rDate = fileReader.ReadString();

                                    //Save the beginning of the next entry
                                    fileReadPosition = fileReader.BaseStream.Position;

                                    resultCounter++;

                                    //Check if this entry is a result to a search
                                    for (int i = 0; i < m_SearchesToStart.Count; i++)
                                    {

                                        string[] searchPattern = m_SearchesToStart[i].Pattern.ToLower().Split(new char[] { ' ' }); ;

                                        //Remove all small patterns
                                        RList<string> patterns = new RList<string>();
                                        for (int k = 0; k < searchPattern.Length; k++)
                                        {
                                            if (searchPattern[k].Length >= 3)
                                            {
                                                patterns.Add(searchPattern[k]);
                                            }
                                        }

                                        bool isResult = false;
                                        int fileNameNumber = 0;

                                        for (int j = 0; j < patterns.Count; j++)
                                        {
                                            //Check all filenames of this entry
                                            for (int k = 0; k < rFileNames.Length; k++)
                                            {

                                                if (rFileNames[k].ToLower().Contains(patterns[j]))
                                                {
                                                    fileNameNumber = k;
                                                    isResult = true;
                                                }
                                            }

                                            //Check the metadata of this entry
                                            if (!isResult)
                                            {
                                                if (rAlbum.ToLower().Contains(patterns[j]))
                                                {
                                                    isResult = true;
                                                }
                                                else if (rArtist.ToLower().Contains(patterns[j]))
                                                {
                                                    isResult = true;
                                                }
                                                else if (rTitle.ToLower().Contains(patterns[j]))
                                                {
                                                    isResult = true;
                                                }
                                            }

                                            //if this is no result for this part of the searchpattern,
                                            //we can stop, because there shall be only results with all
                                            //parts of the searchpattern.
                                            if (isResult == false)
                                            {
                                                break;
                                            }

                                            //Reset isResult for the next part of the searchpattern
                                            if (j != patterns.Count - 1)
                                            {
                                                isResult = false;
                                            }
                                        }

                                        if (isResult)
                                        {
                                            //Add this entry to the results of this search
                                            m_SearchResultsBuffer[m_SearchesToStart[i].SearchID].Add(Core.ByteArrayToString(rFileHash), new OldSearchResult(rFileHash, rFileSize, rFileNames[fileNameNumber], rAlbum, rArtist, rTitle, rRating, DateTime.Parse(rDate)));
                                        }
                                    }

                                    bool updateDate = false;
                                    int[] indexOfResultsToRemove = new int[0];

                                    //Check if a new result is equal to this entry
                                    for (int i = 0; i < m_ResultsToAdd.Count; i++)
                                    {
                                        //Compare the hashes
                                        if (Core.CompareByteArray(rFileHash, m_ResultsToAdd[i].FileHash))
                                        {
                                            //It exists already
                                            updateDate = true;

                                            int[] tempArray1 = new int[indexOfResultsToRemove.Length + 1];
                                            for (int j = 0; j < indexOfResultsToRemove.Length; j++)
                                            {
                                                tempArray1[j] = indexOfResultsToRemove[j];
                                            }
                                            tempArray1[indexOfResultsToRemove.Length] = i;
                                            indexOfResultsToRemove = tempArray1;

                                            //Check the filenames
                                            bool fileNameExists = false;
                                            for (int k = 0; k < rFileNames.Length; k++)
                                            {
                                                if (rFileNames[k] == m_ResultsToAdd[i].FileName)
                                                {
                                                    fileNameExists = true;
                                                    break;
                                                }
                                            }

                                            if (!fileNameExists)
                                            {
                                                //The filename is new -> add it
                                                insertingData = true;

                                                string[] tempArray = new string[rFileNameCount + 1];
                                                for (int k = 0; k < rFileNameCount; k++)
                                                {
                                                    tempArray[k] = rFileNames[k];
                                                }
                                                tempArray[rFileNameCount] = m_ResultsToAdd[i].FileName;
                                                rFileNames = tempArray;
                                                rFileNameCount++;
                                            }
                                        }
                                    }

                                    if (updateDate)
                                    {
                                        //Update the date
                                        rDate = DateTime.Now.ToString(m_DateFormatString);

                                        //Remove the new result from the list, because it exists
                                        RList<Command23.SearchResult> tempRemoveList = new RList<Command23.SearchResult>();
                                        for (int i = 0; i < m_ResultsToAdd.Count; i++)
                                        {
                                            bool addIt = false;
                                            for (int k = 0; k < indexOfResultsToRemove.Length; k++)
                                            {
                                                if (i == indexOfResultsToRemove[k])
                                                {
                                                    addIt = true;
                                                }
                                            }

                                            if (addIt)
                                            {
                                                tempRemoveList.Add(m_ResultsToAdd[i]);
                                            }
                                        }
                                        foreach (Command23.SearchResult r in tempRemoveList)
                                        {
                                            m_ResultsToAdd.Remove(r);
                                        }

                                        //Check if we can update the date directly in the file
                                        if (!insertingData)
                                        {
                                            //Write the new date to the file
                                            fileWriter.BaseStream.Position = datePosition;
                                            fileWriter.Write(rDate);
                                            fileWriter.Flush();
                                            fileReader.BaseStream.Position = fileReadPosition;
                                        }
                                    }

                                    //Check the date if we are cleaning up
                                    if (cleanUp)
                                    {
                                        if (((TimeSpan)DateTime.Now.Subtract(DateTime.Parse(rDate))).Days > m_CleanUpDays)
                                        {
                                            isOld = true;
                                            insertingData = true;
                                            cleanedUpCounter++;
                                        }
                                        else
                                        {
                                            fileSizeOfEntries += (ulong)rFileSize;
                                        }
                                    }
                                    else
                                    {
                                        fileSizeOfEntries += (ulong)rFileSize;
                                    }

                                    //Check if we have to insert data to the file
                                    if (insertingData)
                                    {
                                        if (isFirstChangedEntry)
                                        {
                                            //Here we have to beginn writing
                                            fileWritePosition = firstPositionOfThisEntry;
                                            isFirstChangedEntry = false;
                                        }

                                        if (!isOld)
                                        {
                                            fileFlushCounter++;

                                            //Write the entry to the buffer
                                            memoryWriter.Write(rFileHash);
                                            memoryWriter.Write(rFileSize);
                                            memoryWriter.Write(rFileNameCount);
                                            for (int i = 0; i < rFileNameCount; i++)
                                            {
                                                memoryWriter.Write(rFileNames[i]);
                                            }
                                            memoryWriter.Write(rAlbum);
                                            memoryWriter.Write(rArtist);
                                            memoryWriter.Write(rTitle);
                                            memoryWriter.Write(rRating);
                                            memoryWriter.Write(rDate);

                                            //if the buffer is big enough or we reached the end of the file, write the buffe to the file
                                            if (fileFlushCounter == 10000 || fileReadPosition >= fileLength)
                                            {
                                                fileFlushCounter = 0;

                                                memoryWriter.Flush();

                                                memoryReader.BaseStream.Position = 0;
                                                fileWriter.BaseStream.Position = fileWritePosition;

                                                long memoryLength = memoryReader.BaseStream.Length;
                                                long spaceInFile = fileReadPosition - fileWritePosition;

                                                //write only as much as space and data we have
                                                while (memoryReader.BaseStream.Position < spaceInFile && memoryReader.BaseStream.Position < memoryLength)
                                                {
                                                    fileWriter.Write(memoryReader.ReadByte());
                                                }
                                                fileWriter.Flush();

                                                //Reconfigure the filewriter/reader
                                                fileWritePosition = fileWriter.BaseStream.Position;
                                                fileReader.BaseStream.Position = fileReadPosition;

                                                //Write the rest of the data in the buffer to the beginning of the buffer
                                                long memoryReaderPosition = memoryReader.BaseStream.Position;
                                                long memoryWriterPosition = 0;

                                                while (memoryReaderPosition < memoryLength)
                                                {
                                                    memoryReader.BaseStream.Position = memoryReaderPosition;

                                                    byte b = memoryReader.ReadByte();

                                                    memoryReaderPosition = memoryReader.BaseStream.Position;
                                                    memoryWriter.BaseStream.Position = memoryWriterPosition;

                                                    memoryWriter.Write(b);

                                                    memoryWriterPosition = memoryWriter.BaseStream.Position;
                                                }
                                                memoryWriter.Flush();

                                                memoryWriter.BaseStream.SetLength(memoryWriterPosition);
                                            }
                                        }
                                    }
                                }

                                if (insertingData)
                                {
                                    //write the rest of the memorystream to the file.
                                    fileWriter.BaseStream.Position = fileWritePosition;

                                    long mlength = memoryReader.BaseStream.Length;
                                    memoryReader.BaseStream.Position = 0;
                                    while (memoryReader.BaseStream.Position < mlength)
                                    {
                                        fileWriter.Write(memoryReader.ReadByte());
                                    }
                                    fileWriter.Flush();
                                }

                                if (cleanUp)
                                {
                                    m_Logger.Log(Properties.Resources_Core.CleanSearchDatabase, new object[] { cleanedUpCounter, resultCounter });
                                    resultCounter -= cleanedUpCounter;
                                    m_LastCleanUpCount = cleanedUpCounter;
                                }

                                //Add the new results to the file
                                //The position of the filestream points already to the end
                                RIndexedHashtable<string, NewSearchResult> resultsToAdd = new RIndexedHashtable<string, NewSearchResult>();
                                foreach (Command23.SearchResult result in m_ResultsToAdd)
                                {
                                    string fileHashString = Core.ByteArrayToString(result.FileHash);

                                    if (resultsToAdd.ContainsKey(fileHashString))
                                    {
                                        resultsToAdd[fileHashString].AddFileName(result.FileName);
                                    }
                                    else
                                    {
                                        resultsToAdd.Add(fileHashString, new NewSearchResult(result));
                                    }
                                }

                                foreach (NewSearchResult newResult in resultsToAdd.Values)
                                {
                                    fileWriter.Write(newResult.FileHash);
                                    fileWriter.Write(newResult.FileSize);
                                    int fileNameCount = newResult.FileNames.Length;
                                    fileWriter.Write(fileNameCount);
                                    for (int i = 0; i < fileNameCount; i++)
                                    {
                                        fileWriter.Write(newResult.FileNames[i]);
                                    }
                                    fileWriter.Write(newResult.Album);
                                    fileWriter.Write(newResult.Artist);
                                    fileWriter.Write(newResult.Title);
                                    fileWriter.Write(newResult.Rating);
                                    fileWriter.Write(DateTime.Now.ToString(m_DateFormatString));
                                    resultCounter++;
                                    fileSizeOfEntries += (ulong)newResult.FileSize;
                                }
                                fileWriter.Flush();

                                //Clear the lists
                                m_ResultsToAdd.Clear();
                                m_SearchesToStart.Clear();

                                //Set the correct end of the file
                                if (insertingData)
                                {
                                    fileWriter.BaseStream.SetLength(fileWriter.BaseStream.Position);
                                }

                                if (cleanUp)
                                {
                                    m_LastCleanUp = DateTime.Now;
                                }

                                //Update information
                                m_ResultCount = resultCounter;
                                m_FileSize = fileStream.Length;
                                m_FileSizeOfEntries = fileSizeOfEntries;

                                fileReader.Close();
                                fileWriter.Close();
                                fileStream.Close();

                                memoryReader.Close();
                                memoryWriter.Close();
                                memoryStream.Close();
                            }
                        }
                        catch (Exception ex)
                        {
                            //Update information
                            m_ResultCount = resultCounter;
                            m_FileSize = fileStream.Length;
                            m_FileSizeOfEntries = fileSizeOfEntries;

                            m_ErrorCounter++;
                            m_Logger.Log(ex, "An exception was thrown in searchDBThread! (#{0})", new object[] { m_ErrorCounter });
                            try
                            {
                                fileStream.SetLength(lastKnownValidFilePosition2);
                                m_Logger.Log("Searchdatabase cutted to the entry bofore the last known valid entry. ({0} Bytes remaining)", new object[] { lastKnownValidFilePosition});
                                m_FileSize = lastKnownValidFilePosition2;
                                m_ResultCount = resultCounter - cleanedUpCounter;
                                m_FileSizeOfEntries = fileSizeOfEntries;
                            }
                            catch
                            {
                                try
                                {
                                    if (File.Exists(m_FilePath))
                                    {
                                        File.Delete(m_FilePath);
                                        m_Logger.Log("Searchdatabase deleted, because it was probably corrupt.", new object[] { });
                                        m_FileSize = 0;
                                        m_ResultCount = 0;
                                        m_FileSizeOfEntries = 0;
                                    }
                                }
                                catch { }
                            }
                        }
                        finally
                        {
                            m_ResultsToAdd.Unlock();
                            m_SearchesToStart.Unlock();
                            m_SearchResultsBuffer.Unlock();

                            if (fileReader != null)
                            {
                                fileReader.Close();
                            }
                            if (fileWriter != null)
                            {
                                fileWriter.Close();
                            }
                            if (fileStream != null)
                            {
                                fileStream.Close();
                            }

                            if (memoryReader != null)
                            {
                                memoryReader.Close();
                            }
                            if (memoryWriter != null)
                            {
                                memoryWriter.Close();
                            }
                            if (memoryStream != null)
                            {
                                memoryStream.Close();
                            }
                        }

                        //Move buffer to normal list
                        try
                        {
                            m_SearchResultsBuffer.Lock();
                            m_SearchResults.Lock();

                            for (int i = 0; i < m_SearchResultsBuffer.Count; i++)
                            {
                                if (!m_SearchResults.ContainsKey(((System.Collections.Generic.KeyValuePair<string, RIndexedHashtable<string, OldSearchResult>>)m_SearchResultsBuffer[i]).Key))
                                {
                                    m_SearchResults.Add(((System.Collections.Generic.KeyValuePair<string, RIndexedHashtable<string, OldSearchResult>>)m_SearchResultsBuffer[i]).Key, ((System.Collections.Generic.KeyValuePair<string, RIndexedHashtable<string, OldSearchResult>>)m_SearchResultsBuffer[i]).Value);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            m_Logger.Log(ex, "SearchDBManager: An error was thrown while reading the SearchResultsBuffer.", new object[] { });
                        }
                        finally
                        {
                            m_SearchResultsBuffer.Clear();

                            m_SearchResults.Unlock();
                            m_SearchResultsBuffer.Unlock();
                        }

                        Thread.Sleep(1000);
                    }
                }
                catch (Exception ex)
                {
                    m_Logger.Log(ex, "An exception was thrown in searchDBThread!", new object[] { });
                }

                m_Logger.Log("SearchDBManager closed.", new object[] {  });
            });
            m_SearchDBThread.Name = "searchDBThread";
            m_SearchDBThread.IsBackground = true;
            m_SearchDBThread.Priority = ThreadPriority.Lowest;
            m_SearchDBThread.Start();
        }
示例#15
0
        public void Process()
        {
            //2009-01-25 Nochbaer
            bool activateSearchDB = bool.Parse(m_Settings["ActivateSearchDB"]);

            if (!m_SearchedInDatabase && activateSearchDB && m_SearchType != SearchType.OnlyNetwork)
            {
                Core.AddSearchDBSearch(m_SearchIDString, m_SearchPattern);
                m_SearchedInDatabase = true;

                if (m_SearchType == SearchType.OnlyDatabase)
                {
                    m_SearchCommandsToSent = 0;
                }
            }
            else if (m_SearchedInDatabase && !m_GotSearchDBResults)
            {
                try
                {
                    m_Results.Lock();

                    RIndexedHashtable <string, SearchDBManager.OldSearchResult> searchdbResults = Core.GetSearchDBResults(m_SearchIDString);

                    if (searchdbResults != null)
                    {
                        int maxSearchDBResults = int.Parse(m_Settings["MaxSearchDBResults"]);
                        m_TotalSearchDBResults = searchdbResults.Count;

                        int resultCounter = 0;
                        foreach (SearchDBManager.OldSearchResult result in searchdbResults.Values)
                        {
                            if (m_FileTypeFilter.Contains(result.FileName))
                            {
                                if (!m_Results.ContainsKey(result.FileHashString))
                                {
                                    //2009-01-31 Nochbaer
                                    if (resultCounter >= maxSearchDBResults)
                                    {
                                        m_TooManySearchDBResults = true;
                                        break;
                                    }

                                    RIndexedHashtable <string, string> metaData = new RIndexedHashtable <string, string>();
                                    metaData.Add("Album", result.Album);
                                    metaData.Add("Artist", result.Artist);
                                    metaData.Add("Title", result.Title);
                                    m_Results.Add(result.FileHashString, new Result(m_Results, result.FileHash, result.FileSize, Core.GenerateIDOrHash(), result.FileName, metaData, string.Empty, result.Rating, true, result.Date));

                                    resultCounter++;
                                }
                            }
                        }

                        //Compare the results after filetypefilter
                        if (m_Results.Count >= 25)
                        {
                            m_SearchCommandsToSent = 0;
                        }

                        m_GotSearchDBResults = true;
                    }
                }
                finally
                {
                    m_Results.Unlock();
                }
            }
            else if (!activateSearchDB || m_SearchType == SearchType.OnlyNetwork)
            {
                m_SearchedInDatabase = true;
                m_GotSearchDBResults = true;
            }

            if (m_SearchedInDatabase && m_GotSearchDBResults && m_SearchCommandsToSent > 0 && DateTime.Now.Subtract(m_LastSent).TotalSeconds >= Constants.Command20Interval)
            {
                Core.SendCommand20(m_SearchFloodingHash, m_SearchPeerID, m_SearchID, m_SearchPattern);
                m_LastSent = DateTime.Now;
                m_SearchCommandsToSent--;
            }
        }
示例#16
0
        public SharedFile(string filePath, byte[] fileHash, RIndexedHashtable <string, string> metaData, string comment, byte rating, DateTime?lastRequest)
        {
            if (filePath == null)
            {
                throw new ArgumentNullException("filePath");
            }
            if (fileHash == null)
            {
                throw new ArgumentNullException("fileHash");
            }
            if (fileHash.Length != 64)
            {
                throw new ArgumentException();
            }
            if (rating > 3)
            {
                throw new ArgumentOutOfRangeException("rating");
            }
            if (comment == null)
            {
                throw new ArgumentNullException("comment");
            }

            m_FilePath                   = filePath;
            m_DirectoryPath              = Path.GetDirectoryName(m_FilePath);
            m_FileName                   = Path.GetFileName(m_FilePath);
            m_FileHash                   = fileHash;
            m_FileHashString             = Core.ByteArrayToString(m_FileHash);
            m_OnceHashedFileHash         = ComputeHashes.SHA512Compute(m_FileHash);
            m_OnceHashedFileHashString   = Core.ByteArrayToString(m_OnceHashedFileHash);
            m_TwiceHashedFileHash        = ComputeHashes.SHA512Compute(m_OnceHashedFileHash);
            m_TwiceHashedFileHashString  = Core.ByteArrayToString(m_TwiceHashedFileHash);
            m_ThriceHashedFileHash       = ComputeHashes.SHA512Compute(m_TwiceHashedFileHash);
            m_ThriceHashedFileHashString = Core.ByteArrayToString(m_ThriceHashedFileHash);
            m_FileSize                   = new FileInfo(m_FilePath).Length;
            m_FileSizeString             = Core.LengthToString(m_FileSize);
            m_Sectors = m_FileSize / 32768;
            if (metaData.IsEmpty)
            {
                try
                {
                    switch (Path.GetExtension(m_FilePath))
                    {
                    case ".mp3":
                        FileStream     fileStream = new FileStream(m_FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                        ID3v1TagReader id3v1      = new ID3v1TagReader(fileStream);
                        if (id3v1.HasTag)
                        {
                            if (id3v1.HasAlbum && id3v1.Album.Trim() != string.Empty)
                            {
                                m_MetaData.Add("Album", id3v1.Album.Trim());
                            }
                            if (id3v1.HasArtist && id3v1.Artist.Trim() != string.Empty)
                            {
                                m_MetaData.Add("Artist", id3v1.Artist.Trim());
                            }
                            if (id3v1.HasTitle && id3v1.Title.Trim() != string.Empty)
                            {
                                m_MetaData.Add("Title", id3v1.Title.Trim());
                            }
                        }
                        ID3v2TagTextFrameReader id3v2 = new ID3v2TagTextFrameReader(fileStream);
                        if (id3v2.HasTag)
                        {
                            if (id3v2.Frames.ContainsKey("TALB") && id3v2.Frames["TALB"].Trim() != string.Empty)
                            {
                                m_MetaData.Add("TALB", id3v2.Frames["TALB"].Trim());
                            }
                            if (id3v2.Frames.ContainsKey("TPE1") && id3v2.Frames["TPE1"].Trim() != string.Empty)
                            {
                                m_MetaData.Add("TPE1", id3v2.Frames["TPE1"].Trim());
                            }
                            if (id3v2.Frames.ContainsKey("TIT2") && id3v2.Frames["TIT2"].Trim() != string.Empty)
                            {
                                m_MetaData.Add("TIT2", id3v2.Frames["TIT2"].Trim());
                            }
                        }
                        fileStream.Close();
                        break;

                    default:
                        FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(m_FilePath);
                        if (fileVersionInfo.CompanyName != null && fileVersionInfo.CompanyName.Trim() != string.Empty)
                        {
                            m_MetaData.Add("CompanyName", fileVersionInfo.CompanyName.Trim());
                        }
                        if (fileVersionInfo.ProductName != null && fileVersionInfo.ProductName.Trim() != string.Empty)
                        {
                            m_MetaData.Add("ProductName", fileVersionInfo.ProductName.Trim());
                        }
                        break;
                    }
                }
                catch (Exception ex)
                {
                    m_Logger.Log(ex, "An Exception was thrown while gathering meta data!");
                }
            }
            else
            {
                m_MetaData = metaData;
            }
            Core.ParseMetaData(m_MetaData, out m_Album, out m_Artist, out m_Title);
            m_Rating        = rating;
            m_Comment       = comment;
            m_LastRequest   = lastRequest;
            m_LastWriteTime = File.GetLastWriteTime(m_FilePath);
        }