Exemple #1
0
        private void AddEntryToDictionary(
            EdataDictionaryPathEntry entry,
            ContentPathSplitInfo entryPathSplitInfo,
            EdataDictionaryRootEntry dictionaryRoot)
        {
            if (entryPathSplitInfo.SplitIndex == 0)
            {
                dictionaryRoot.AddFollowingEntry(entry);
                //entry.PrecedingEntry = dictionaryRoot;
            }
            else
            {
                var precedingPath = entryPathSplitInfo.GetPathToSplitIndex();
                EdataDictionaryPathEntry precedingPathEntry =
                    dictionaryRoot.SelectEntryByPath(precedingPath);

                var pp = precedingPathEntry as EdataDictionaryDirEntry;
                if (precedingPathEntry != null)
                {
                    pp.AddFollowingEntry(entry);
                    //entry.PrecedingEntry = pp;
                }
                else
                {
                    throw new Exception(String.Format(
                                            "Cannot find a following precedding entry: {0}",
                                            precedingPath));
                }
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dictionaryRoot"></param>
        /// <param name="contentFilesSectionOffset"></param>
        /// <returns></returns>
        protected virtual IEnumerable <EdataContentFile> TranslateDictionaryEntriesToContentFiles(
            Stream source,
            uint contentFilesSectionOffset,
            EdataDictionaryRootEntry dictionaryRoot)
        {
            var contentFiles = new List <EdataContentFile>();

            var fileEntries = dictionaryRoot.SelectEntriesOfType <EdataDictionaryFileEntry>();

            foreach (var entry in fileEntries)
            {
                var newCotnetFile = new EdataContentFile();
                newCotnetFile.Offset      = entry.FileOffset;
                newCotnetFile.TotalOffset = entry.FileOffset + contentFilesSectionOffset;
                newCotnetFile.Length      = entry.FileLength;
                newCotnetFile.Checksum    = entry.FileChecksum;
                newCotnetFile.Path        = entry.FullPath;

                //To można by stąd wydzielić
                ResolveContentFileType(source, newCotnetFile, contentFilesSectionOffset);

                contentFiles.Add(newCotnetFile);
            }

            return(contentFiles);
        }
Exemple #3
0
        /// <summary>
        /// Creates a hierarchy of the dictionary content entries based on the provided collection of content files.
        /// </summary>
        /// <param name="contentFiles"></param>
        /// <returns></returns>
        /// <remarks>This metohd requires that there are no two content files with the same paths.</remarks>
        protected virtual EdataDictionaryRootEntry CreateDictionaryEntries(
            IEnumerable <EdataContentFile> contentFiles)
        {
            List <ContentPathSplitInfo> pathsToSplit = contentFiles
                                                       .OrderBy(file => file.Path, new EdataDictStringComparer())
                                                       .Select(file => new ContentPathSplitInfo()
            {
                Path = file.Path
            })
                                                       .ToList();

            var dictionaryRoot = new EdataDictionaryRootEntry();

            //Wide match can't be picked over a long match.
            while (pathsToSplit.Count > 0)
            {
                List <ContentPathSplitInfo> pathsToCompare = TakePathsToCompare(pathsToSplit);
                if (pathsToCompare.Count == 1)
                {
                    var newEntry = new EdataDictionaryFileEntry(pathsToCompare[0].GetPathFromSplitIndex());
                    AddEntryToDictionary(newEntry, pathsToCompare[0], dictionaryRoot);

                    pathsToSplit.Remove(pathsToCompare[0]);
                }
                else if (pathsToCompare.Count > 1)
                {
                    int matchIndex = 0;

                    while (true) //Zastanowić sie co z warunkiem kończoaczym, czy to break moze nie zaistnieć.
                    {
                        bool allPathsMatched = CheckIfAllPathsMatchAtIndex(pathsToCompare, matchIndex);;
                        if (allPathsMatched)
                        {
                            matchIndex++;
                        }
                        else
                        {
                            var newEntry = new EdataDictionaryDirEntry(pathsToCompare[0].GetPathFromSplitIndex(length: matchIndex));
                            AddEntryToDictionary(newEntry, pathsToCompare[0], dictionaryRoot);

                            //czy tu powinno być += czy tylko przypisanie?
                            pathsToCompare.ForEach(x => x.SplitIndex += matchIndex);

                            break;
                        }
                    }
                }
            }

            return(dictionaryRoot);
        }
Exemple #4
0
 /// <summary>
 /// Assigns a dictionary data of the content files to the corresponding dictionary entries.
 /// </summary>
 /// <param name="contentFiles"></param>
 /// <param name="dictionaryRoot"></param>
 protected virtual void AssignContentFilesInfoToDictEntries(
     IEnumerable <EdataContentFile> contentFiles,
     EdataDictionaryRootEntry dictionaryRoot)
 {
     foreach (var file in contentFiles)
     {
         var matchingEntry = dictionaryRoot.SelectEntryByPath(file.Path);
         EdataDictionaryFileEntry fileEntry = matchingEntry as EdataDictionaryFileEntry;
         if (fileEntry != null)
         {
             fileEntry.FileOffset   = file.Offset;
             fileEntry.FileLength   = file.Length;
             fileEntry.FileChecksum = file.Checksum;
         }
     }
 }
Exemple #5
0
        protected virtual uint ComputeDictionaryLength(EdataDictionaryRootEntry dictionaryRoot)
        {
            uint dictHeaderSize = 10;
            uint totalSize      = dictHeaderSize;

            var entriesQueue = new Queue <EdataDictionaryPathEntry>();

            entriesQueue.Enqueue(dictionaryRoot);

            while (entriesQueue.Count > 0)
            {
                var entry = entriesQueue.Dequeue();

                totalSize += (uint)entry.Length;

                foreach (var subEntry in entry.FollowingEntries)
                {
                    entriesQueue.Enqueue(subEntry);
                }
            }

            return(totalSize);
        }
Exemple #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="target"></param>
        /// <param name="dictionaryRoot"></param>
        /// <param name="dictOffset"></param>
        /// <returns></returns>
        protected virtual DictionaryWriteInfo WriteDictionary(
            Stream target,
            EdataDictionaryRootEntry dictionaryRoot,
            uint dictOffset)
        {
            var info = new DictionaryWriteInfo();

            target.Seek(dictOffset, SeekOrigin.Begin);

            //Need to use depth-traversal
            var entriesStack = new Stack <EdataDictionaryPathEntry>();

            entriesStack.Push(dictionaryRoot);

            while (entriesStack.Count > 0)
            {
                var entry = entriesStack.Pop();

                var entryBuffer = entry.ToBytes();
                target.Write(entryBuffer, 0, entryBuffer.Length);
                info.Length += (uint)entryBuffer.Length;

                foreach (var subEntry in entry.FollowingEntries.Reverse())
                {
                    entriesStack.Push(subEntry);
                }
            }

            var dictBuff = new byte[info.Length];

            target.Seek(dictOffset, SeekOrigin.Begin);
            target.Read(dictBuff, 0, dictBuff.Length);

            info.Checksum = MD5.Create().ComputeHash(dictBuff);

            return(info);
        }
        /// <summary>
        /// Reads Edata version 2 dictionary entries
        /// </summary>
        /// <param name="source"></param>
        /// <param name="header"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        protected virtual EdataDictionaryRootEntry ReadDcitionaryEntries(
            Stream source,
            uint dictOffset,
            uint dictLength)
        {
            EdataDictionaryRootEntry dictRoot   = new EdataDictionaryRootEntry();
            EdataDictionaryDirEntry  workingDir = null;

            source.Seek(dictOffset + dictRoot.Length, SeekOrigin.Begin);

            long dictEnd = dictOffset + dictLength;

            while (source.Position < dictEnd)
            {
                var buffer = new byte[4];
                source.Read(buffer, 0, 4);
                int entrysFirstFour = BitConverter.ToInt32(buffer, 0);

                source.Read(buffer, 0, 4);
                int entrysSecondFour = BitConverter.ToInt32(buffer, 0);

                bool isFileEntry = (entrysFirstFour == 0);
                if (isFileEntry)
                {
                    int entryLength = entrysSecondFour;

                    //source.Read(buffer, 0, 4);
                    //int relevanceLength = BitConverter.ToInt32(buffer, 0);

                    buffer = new byte[8];
                    source.Read(buffer, 0, buffer.Length);
                    long offset = BitConverter.ToInt64(buffer, 0);

                    source.Read(buffer, 0, buffer.Length);
                    long length = BitConverter.ToInt64(buffer, 0);

                    var checksum = new byte[16];
                    source.Read(checksum, 0, checksum.Length);

                    String pathPart = MiscUtilities.ReadString(source);
                    if (pathPart.Length % 2 == 0)
                    {
                        source.Seek(1, SeekOrigin.Current);
                    }

                    var newFile = new EdataDictionaryFileEntry(pathPart, entryLength, offset, length, checksum);
                    if (workingDir != null)
                    {
                        workingDir.AddFollowingEntry(newFile);

                        //Usuwamy tylko jeśli pojawia się wpis pliku oznaczony jako kończący ścieżkę.
                        if (newFile.IsEndingEntry())
                        {
                            EdataDictionaryDirEntry previousEntry = null;
                            do
                            {
                                previousEntry = workingDir;
                                workingDir    = workingDir.PrecedingEntry as EdataDictionaryDirEntry;
                            }while (workingDir != null && previousEntry.IsEndingEntry());
                        }
                    }
                    else
                    {
                        dictRoot.AddFollowingEntry(newFile);
                    }
                }
                else //isDirEntry
                {
                    int entryLength     = entrysFirstFour;
                    int relevanceLength = entrysSecondFour;

                    //source.Read(buffer, 0, 4);
                    //int relevanceLength = BitConverter.ToInt32(buffer, 0);

                    String pathPart = MiscUtilities.ReadString(source);
                    if (pathPart.Length % 2 == 0)
                    {
                        source.Seek(1, SeekOrigin.Current);
                    }

                    var newDir = new EdataDictionaryDirEntry(pathPart, entryLength, relevanceLength);
                    if (workingDir != null)
                    {
                        workingDir.AddFollowingEntry(newDir);
                    }
                    else
                    {
                        dictRoot.AddFollowingEntry(newDir);
                    }
                    workingDir = newDir;
                }
            }

            return(dictRoot);
        }