public IFileChunkReference ReadFileChunkReference(StpFormat stpFormat, CbFormat cbFormat, string context)
        {
            if (stpFormat == StpFormat.Uncompressed8Bytes && cbFormat == CbFormat.Uncompressed4Bytes)
            {
                var fileChunkReference64x32 = new FileChunkReference64x32();
                ReadFileChunkReference64x32(ref fileChunkReference64x32, context);

                return(fileChunkReference64x32);
            }

            if (stpFormat == StpFormat.Uncompressed4Bytes && cbFormat == CbFormat.Uncompressed4Bytes)
            {
                var fileChunkReference32 = new FileChunkReference32();
                ReadFileChunkReference32(ref fileChunkReference32, context);

                return(fileChunkReference32);
            }

            if (stpFormat == StpFormat.Compressed2Bytes && cbFormat == CbFormat.Compressed1Byte)
            {
                var fileChunkReference16x8 = new FileChunkReference16x8();
                ReadFileChunkReference16x8(ref fileChunkReference16x8, context);

                return(fileChunkReference16x8);
            }

            throw new NotImplementedException("Reference format is not supported");
        }
 public void ReadFileChunkReference64x32(ref FileChunkReference64x32 fileChunkReference64x32, string context)
 {
     if (!Unsafe.ReadStruct(binaryReader, ref fileChunkReference64x32))
     {
         throw new FileFormatException("Cannot read ReadFileChunkReference32. Context: " + context);
     }
 }
        public void ReadTransactionLog(Dictionary <uint, uint> transactionsData, IFileChunkReference fileChunkReference,
                                       uint cTransactionsInLog)
        {
            oneNoteFileReader.Move(fileChunkReference.Offset, "TransactionLog");

            uint cbRead = 0;
            var  cbTransactionLogFragmentSize = fileChunkReference.DataSize;
            var  cbMax = cbTransactionLogFragmentSize - FileChunkReference64x32.SizeInBytes;

            for (var i = 0; i < cTransactionsInLog; i++)
            {
                if (cbRead == cbMax)
                {
                    const string operationContext = "TransactionLog.nextFragment";

                    var nextFragment = new FileChunkReference64x32();

                    oneNoteFileReader.ReadFileChunkReference64x32(ref nextFragment, operationContext);
                    oneNoteFileReader.Move(nextFragment.Offset, operationContext);

                    cbRead = 0;
                    cbMax  = nextFragment.cb - FileChunkReference64x32.SizeInBytes;
                }
                else if (cbRead > cbMax)
                {
                    throw new FileFormatException("Transaction log is broken");
                }

                ReadTransaction(transactionsData, ref cbRead);
            }
        }
        public ICollection <FNDBase> ReadFileNodeList(IFileChunkReference fileChunkReference, Dictionary <uint, uint> transactionsData, params uint[] fileNodeIds)
        {
            ICollection <FNDBase> result = new List <FNDBase>();

            var nextFragment = new FileChunkReference64x32();

            while (true)
            {
                ReadFileNodeListFragment(fileChunkReference, result, ref nextFragment, transactionsData, fileNodeIds);

                if (FileChunkReference64x32.Nil.Equals(nextFragment))
                {
                    break;
                }

                fileChunkReference = nextFragment;
            }

            return(result);
        }
        public void ReadFileNodeListFragment(IFileChunkReference fileChunkReference, ICollection <FNDBase> result, ref FileChunkReference64x32 nextFragment, Dictionary <uint, uint> transactionsData, params uint[] fileNodeIds)
        {
            oneNoteFileReader.Move(fileChunkReference.Offset, "FileNodeListFragment");

            var jumpSizeToNextFragmentReference = GetJumpSizeToNextFragmentReference(fileChunkReference.DataSize);

            var fileNodeListHeader = new FileNodeListHeader();

            oneNoteFileReader.ReadFileNodeListHeader(ref fileNodeListHeader);
            jumpSizeToNextFragmentReference -= FileNodeListHeader.SizeInBytes;

            var fileNodeListId = fileNodeListHeader.FileNodeListID;
            var nodesCount     = transactionsData[fileNodeListId];
            var fileNodeHeader = new FileNodeHeader();

            while (true)
            {
                if (nodesCount == 0)
                {
                    break;
                }

                oneNoteFileReader.ReadFileNodeHeader(ref fileNodeHeader);
                jumpSizeToNextFragmentReference -= FileNodeHeader.SizeInBytes;

                var fileNodeId = fileNodeHeader.FileNodeID;
                if (fileNodeId == FileNodeIDs.ChunkTerminatorFND)
                {
                    break;
                }

                var sizeOfData = fileNodeHeader.Size - FileNodeHeader.SizeInBytes;
                var skip       = true;

                if (fileNodeIds.Length == 0 || Array.IndexOf(fileNodeIds, fileNodeId) >= 0)
                {
                    var readFileNodeData = ReadFileNodeData(fileNodeHeader);
                    if (readFileNodeData == null)
                    {
                        readFileNodeData = new NotImplementedFND(fileNodeHeader);
                    }
                    else
                    {
                        skip = false;
                    }

                    result.Add(readFileNodeData);
                    jumpSizeToNextFragmentReference -= sizeOfData;
                }

                if (skip && sizeOfData != 0)
                {
                    oneNoteFileReader.Skip(sizeOfData);
                    jumpSizeToNextFragmentReference -= sizeOfData;
                }

                nodesCount--;

                const uint minJumpSize = 4;
                if (jumpSizeToNextFragmentReference < minJumpSize)
                {
                    break;
                }
            }

            if (jumpSizeToNextFragmentReference != 0)
            {
                oneNoteFileReader.Skip(jumpSizeToNextFragmentReference);
            }

            oneNoteFileReader.ReadFileChunkReference64x32(ref nextFragment, "FileNodeListFragment.nextFragment");
            oneNoteFileReader.ExpectFileNodeListFooter();

            transactionsData[fileNodeListId] = nodesCount;
        }