Beispiel #1
0
        /// <summary>
        /// Finish building the file. Don't use this builder after that!
        /// </summary>
        /// <returns></returns>
        public LoggedFile Close()
        {
            var ret = new LoggedFile(info.ID, log);

            info = new FileLog.LoggedFileInfo();
            log  = null;
            return(ret);
        }
Beispiel #2
0
 /// <summary>
 /// Creates new file inside the passed FileLog
 /// </summary>
 /// <param name="log"></param>
 /// <exception cref="ArgumentNullException">log</exception>
 public LoggedFileBuilder(FileLog log)
 {
     if (log == null)
     {
         throw new ArgumentNullException("log");
     }
     this.log = log;
     info     = log.CreateFile();
 }
Beispiel #3
0
 /// <summary>
 /// Get file lentgh
 /// </summary>
 /// <param name="hint">file hint as returned from GetFileHint</param>
 /// <returns>file length</returns>
 public long GetFileLength(FileLog.LoggedFileInfo hint)
 {
     lock (streamLock)
     {
         var initialPos = stream.Position;
         stream.Position = hint.Hint;
         var ret = binReader.ReadInt64();
         stream.Position = initialPos;
         return(ret);
     }
 }
Beispiel #4
0
 /// <summary>
 /// Read file data to buffer
 /// </summary>
 /// <param name="hint">file hint as returned from GetFileHint</param>
 /// <param name="buffer">output buffer</param>
 /// <param name="start">file offset to start reading at</param>
 /// <param name="length">how many data to read</param>
 /// <param name="offset">start offset in the output buffer</param>
 /// <exception cref="ArgumentNullException">Buffer is null</exception>
 /// <exception cref="BufferNotLargeEnoughException"></exception>
 /// <exception cref="IndexOutOfRangeException">Data outside the file requested.</exception>
 /// <exception cref="LoggedFileCorruptedException">The logged file is somehow corrupted - eg. invalid pointers, missing data, ...</exception>
 public void ReadFileDataToBuffer(FileLog.LoggedFileInfo hint, byte[] buffer, long start, int length, int offset)
 {
     if (buffer == null)
     {
         throw new ArgumentNullException("buffer");
     }
     if (buffer.Length - offset < length)
     {
         throw new BufferNotLargeEnoughException();
     }
     lock (streamLock)
     {
         var initialPos = stream.Position;
         stream.Position = hint.Hint;
         long size = binReader.ReadInt64();
         if (size < start + length)
         {
             throw new IndexOutOfRangeException("Data outside the file requested.");
         }
         long blockOffset  = start % FileLog.BlockSize;
         long fbt2Offset   = (start / (FileLog.BlockSize)) % (FileLog.FilesPerBlock + 1);
         long fbtOffset    = start / (FileLog.BlockSize * (FileLog.FilesPerBlock + 1)) + 1;
         long currentFbt   = stream.Position;
         long currentFbt2  = -1;
         var  streamLength = stream.Length;
         while (length > 0)
         {
             while (fbtOffset <= FileLog.FilesPerBlock)
             {
                 while (fbt2Offset <= FileLog.FilesPerBlock)
                 {
                     if (currentFbt2 < 0)
                     {
                         stream.Position = currentFbt + fbtOffset * sizeof(long);
                         currentFbt2     = binReader.ReadInt64();
                         if (currentFbt2 <= 0 || currentFbt2 > streamLength - FileLog.BlockSize)
                         {
                             throw new LoggedFileCorruptedException(string.Format("Expected valid pointer to FBT2 at {0}! File hint: {1}.", stream.Position - sizeof(long), hint));
                         }
                     }
                     stream.Position = currentFbt2 + fbt2Offset * sizeof(long);
                     long dataBlock = binReader.ReadInt64();
                     if (dataBlock <= 0 || dataBlock > streamLength - FileLog.BlockSize)
                     {
                         throw new LoggedFileCorruptedException(string.Format("Expected valid pointer to data block at {0}! File hint: {1}.", stream.Position - sizeof(long), hint));
                     }
                     stream.Position = dataBlock + blockOffset;
                     int toRead = Math.Min(length, (int)(FileLog.BlockSize - blockOffset));
                     int read   = 0;
                     // although all data should be available the implementation may not return them all at once
                     while (toRead > 0 && (read = stream.Read(buffer, offset, toRead)) != 0)
                     {
                         toRead      -= read;
                         offset      += read;
                         length      -= read;
                         blockOffset += read;
                     }
                     if (toRead > 0)
                     {
                         throw new LoggedFileCorruptedException(string.Format("Expected to read {0} more bytes from data block starting at {1}. File hint: {2}.", toRead, dataBlock, hint));
                     }
                     if (length == 0)
                     {
                         stream.Position = initialPos;
                         return;
                     }
                     blockOffset = 0;
                     fbt2Offset++;
                 }
                 fbt2Offset = 0;
                 fbtOffset++;
                 currentFbt2 = -1;
             }
             stream.Position = currentFbt;
             currentFbt      = binReader.ReadInt64();
             if (currentFbt <= 0 || currentFbt > streamLength - FileLog.BlockSize)
             {
                 throw new LoggedFileCorruptedException(string.Format("Expected valid pointer to next FBT at {0}! File hint: {1}.", stream.Position - sizeof(long), hint));
             }
             stream.Position = currentFbt;
             fbtOffset      -= FileLog.FilesPerBlock;
             currentFbt2     = -1;
         }
     }
 }