Пример #1
0
        /// <summary>
        /// Attempt to load the session header from the specified entry, returning null if it can't be loaded
        /// </summary>
        /// <param name="zipEntry">The current entry</param>
        /// <returns>The session header, or null if it can't be loaded</returns>
        private static SessionHeader LoadSessionHeader(ZipArchiveEntry zipEntry)
        {
            if (!Log.SilentMode)
            {
                Log.Write(LogMessageSeverity.Verbose, LogCategory, "Opening session file from zip file to read header", "Opening zip entry '{0}'.", zipEntry.Name);
            }

            SessionHeader header = null;

            try
            {
                using (var sourceFile = zipEntry.Open())
                {
                    //we need a SEEKABLE stream, so we need to make a memory stream to be seek-able.


                    //read the file header first to find out how large the session header is (which can be any size)
                    var fileHeaderBuffer = new byte[FileHeader.HeaderSize];
                    sourceFile.Read(fileHeaderBuffer, 0, fileHeaderBuffer.Length);
                    FileHeader fileHeader = null;
                    using (var memoryStream = new MemoryStream(fileHeaderBuffer))
                    {
                        if (GLFReader.IsGLF(memoryStream, out fileHeader) == false)
                        {
                            if (!Log.SilentMode)
                            {
                                Log.Write(LogMessageSeverity.Verbose, LogCategory, "Session file does not check out as a GLF file, skipping", "Zip entry: '{0}'.", zipEntry.Name);
                            }
                            return(header);
                        }
                    }

                    var sessionHeaderBuffer = new byte[fileHeader.DataOffset];
                    //we have to copy the file header into it because we can't re-read those bytes (non-seek-able stream)
                    fileHeaderBuffer.CopyTo(sessionHeaderBuffer, 0);
                    sourceFile.Read(sessionHeaderBuffer, fileHeaderBuffer.Length, sessionHeaderBuffer.Length - fileHeaderBuffer.Length);
                    using (var memoryStream = new MemoryStream(sessionHeaderBuffer))
                    {
                        using (var sourceGlfFile = new GLFReader(memoryStream))
                        {
                            if (sourceGlfFile.IsSessionStream)
                            {
                                header = sourceGlfFile.SessionHeader;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (!Log.SilentMode)
                {
                    Log.Write(LogMessageSeverity.Warning, LogWriteMode.Queued, ex, LogCategory, "Unexpected exception while attempting to load a session header",
                              "While opening the zip file entry '{0}' an exception was thrown reading the session header. Since this routine is designed to not generate exceptions this may indicate a flaw in the logic of the routine.\r\nException: {1}\r\n",
                              zipEntry.Name, ex.Message);
                }
            }

            return(header);
        }
Пример #2
0
        /// <summary>
        /// Adds the provided session to the package
        /// </summary>
        /// <param name="sessionStream"></param>
        public void AddSession(Stream sessionStream)
        {
            using (GLFReader glfReader = new GLFReader(sessionStream)) // This will dispose the stream when it is disposed.
            {
                if (!glfReader.IsSessionStream)
                {
                    throw new GibraltarException("The data stream provided is not a valid session data stream.");
                }

                if (!Log.SilentMode)
                {
                    Log.Write(LogMessageSeverity.Verbose, LogCategory, "Stream is session file, attempting to load", null);
                }

                lock (m_Lock)
                {
                    //Add this stream to our zip archive
                    string fileName = glfReader.SessionHeader.HasFileInfo ? string.Format("{0}~{1}.{2}", glfReader.SessionHeader.Id, glfReader.SessionHeader.FileId, Log.LogExtension)
                                          : string.Format("{0}.{1}", glfReader.SessionHeader.Id, Log.LogExtension);

                    string zipFilePath = GenerateFragmentPath(glfReader.SessionHeader.FileId);

                    ZipArchiveEntry fragmentEntry;
                    if (m_Archive.Mode == ZipArchiveMode.Update)
                    {
                        fragmentEntry = m_Archive.GetEntry(zipFilePath);
                        if (fragmentEntry != null)
                        {
                            fragmentEntry.Delete(); //wipe out any existing entry
                        }
                    }

                    fragmentEntry = m_Archive.CreateEntry(FragmentsFolder + "\\" + fileName, CompressionLevel.NoCompression); //session files are already highly compressed, no reason to waste effort.

                    using (var zipStream = fragmentEntry.Open())
                    {
                        FileSystemTools.StreamContentCopy(sessionStream, zipStream, false); // Copy the stream into our package's temp directory.
                    }

                    IsDirty = true;
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Load the specified session
        /// </summary>
        /// <returns>The loaded session.  If no session can be found with the specified Id an ArgumentOutOfRangeException will be thrown.</returns>
        public Session GetSession(Guid sessionId, Guid?fileId = null)
        {
            Session requestedSession = null;

            lock (m_Lock)
            {
                SessionFileInfo <ZipArchiveEntry> sessionFileInfo;
                if (m_Sessions.TryGetValue(sessionId, out sessionFileInfo) == false)
                {
                    throw new ArgumentOutOfRangeException(nameof(sessionId), "There is no session in the package with the provided id");
                }

                //now load up all of the session fragments.
                var loadingCollection = new SessionCollection();

                foreach (var fragment in sessionFileInfo.Fragments)
                {
                    //we need a seek-able stream - so we'll extract the fragment into a temp file and go with that.
                    if (fileId != null)
                    {
                        //we need to check the file Id to see if it's what they requested
                        using (var reader = new GLFReader(FileSystemTools.GetTempFileStreamCopy(fragment.Open())))
                        {
                            if (reader.SessionHeader.FileId != fileId.Value)
                            {
                                continue;
                            }
                        }
                    }

                    requestedSession = loadingCollection.Add(FileSystemTools.GetTempFileStreamCopy(fragment.Open()), true);
                }
            }

            if (requestedSession == null)
            {
                throw new ArgumentOutOfRangeException(nameof(fileId), "There is no session file in the package with the provided file id");
            }

            return(requestedSession);
        }
Пример #4
0
        /// <summary>
        /// Retrieve the ids of the sessions files known locally for the specified session
        /// </summary>
        /// <param name="sessionId"></param>
        /// <returns></returns>
        public IList <Guid> GetSessionFileIds(Guid sessionId)
        {
            lock (m_Lock)
            {
                SessionFileInfo <ZipArchiveEntry> sessionFileInfo;
                if (m_Sessions.TryGetValue(sessionId, out sessionFileInfo) == false)
                {
                    throw new ArgumentOutOfRangeException(nameof(sessionId), "There is no session in the package with the provided id");
                }

                var fileIds = new List <Guid>();
                foreach (var fragment in sessionFileInfo.Fragments)
                {
                    //this is kinda crappy - we have to make a copy of the whole fragment to get a seekable stream to read the id.
                    using (var reader = new GLFReader(FileSystemTools.GetTempFileStreamCopy(fragment.Open())))
                    {
                        fileIds.Add(reader.SessionHeader.FileId);
                    }
                }

                return(fileIds);
            }
        }