예제 #1
0
        public NPOIFSMiniStore(NPOIFSFileSystem filesystem, RootProperty root,
                               List <BATBlock> sbats, HeaderBlock header)
        {
            this._filesystem  = filesystem;
            this._sbat_blocks = sbats;
            this._header      = header;
            this._root        = root;

            this._mini_stream = new NPOIFSStream(filesystem, root.StartBlock);
        }
예제 #2
0
        /**
         * Constructor for an existing Document
         */
        public NPOIFSDocument(DocumentProperty property, NPOIFSFileSystem filesystem)
        {
            this._property   = property;
            this._filesystem = filesystem;

            if (property.Size < POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE)
            {
                _stream     = new NPOIFSStream(_filesystem.GetMiniStore(), property.StartBlock);
                _block_size = _filesystem.GetMiniStore().GetBlockStoreBlockSize();
            }
            else
            {
                _stream     = new NPOIFSStream(_filesystem, property.StartBlock);
                _block_size = _filesystem.GetBlockStoreBlockSize();
            }
        }
예제 #3
0
        /**
         * Constructor for a new Document
         *
         * @param name the name of the POIFSDocument
         * @param stream the InputStream we read data from
         */
        public NPOIFSDocument(String name, NPOIFSFileSystem filesystem, Stream stream)
        {
            this._filesystem = filesystem;

            // Buffer the contents into memory. This is a bit icky...
            // TODO Replace with a buffer up to the mini stream size, then streaming write
            byte[] contents;
            if (stream is MemoryStream)
            {
                MemoryStream bais = (MemoryStream)stream;
                contents = new byte[bais.Length];
                bais.Read(contents, 0, contents.Length);
            }
            else
            {
                MemoryStream baos = new MemoryStream();
                IOUtils.Copy(stream, baos);
                contents = baos.ToArray();
            }

            // Do we need to store as a mini stream or a full one?
            if (contents.Length <= POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE)
            {
                _stream     = new NPOIFSStream(filesystem.GetMiniStore());
                _block_size = _filesystem.GetMiniStore().GetBlockStoreBlockSize();
            }
            else
            {
                _stream     = new NPOIFSStream(filesystem);
                _block_size = _filesystem.GetBlockStoreBlockSize();
            }

            // Store it
            _stream.UpdateContents(contents);

            // And build the property for it
            this._property       = new DocumentProperty(name, contents.Length);
            _property.StartBlock = _stream.GetStartBlock();
        }
예제 #4
0
        /**
         * Updates the contents of the stream to the new
         *  Set of bytes.
         * Note - if this is property based, you'll still
         *  need to update the size in the property yourself
         */
        public void UpdateContents(byte[] contents)
        {
            // How many blocks are we going to need?
            int blockSize = blockStore.GetBlockStoreBlockSize();
            int blocks    = (int)Math.Ceiling(((double)contents.Length) / blockSize);

            // Make sure we don't encounter a loop whilst overwriting
            //  the existing blocks
            ChainLoopDetector loopDetector = blockStore.GetChainLoopDetector();

            // Start writing
            int prevBlock = POIFSConstants.END_OF_CHAIN;
            int nextBlock = startBlock;

            for (int i = 0; i < blocks; i++)
            {
                int thisBlock = nextBlock;

                // Allocate a block if needed, otherwise figure
                //  out what the next block will be
                if (thisBlock == POIFSConstants.END_OF_CHAIN)
                {
                    thisBlock = blockStore.GetFreeBlock();
                    loopDetector.Claim(thisBlock);

                    // We're on the end of the chain
                    nextBlock = POIFSConstants.END_OF_CHAIN;

                    // Mark the previous block as carrying on to us if needed
                    if (prevBlock != POIFSConstants.END_OF_CHAIN)
                    {
                        blockStore.SetNextBlock(prevBlock, thisBlock);
                    }
                    blockStore.SetNextBlock(thisBlock, POIFSConstants.END_OF_CHAIN);

                    // If we've just written the first block on a
                    //  new stream, save the start block offset
                    if (this.startBlock == POIFSConstants.END_OF_CHAIN)
                    {
                        this.startBlock = thisBlock;
                    }
                }
                else
                {
                    loopDetector.Claim(thisBlock);
                    nextBlock = blockStore.GetNextBlock(thisBlock);
                }

                // Write it
                //byte[] buffer = blockStore.CreateBlockIfNeeded(thisBlock);
                ByteBuffer buffer  = blockStore.CreateBlockIfNeeded(thisBlock);
                int        startAt = i * blockSize;
                int        endAt   = Math.Min(contents.Length - startAt, blockSize);
                buffer.Write(contents, startAt, endAt);
                //for (int index = startAt, j = 0; index < endAt; index++, j++)
                //    buffer[j] = contents[index];

                // Update pointers
                prevBlock = thisBlock;
            }
            int lastBlock = prevBlock;

            // If we're overwriting, free any remaining blocks
            NPOIFSStream toFree = new NPOIFSStream(blockStore, nextBlock);

            toFree.free(loopDetector);

            // Mark the end of the stream
            blockStore.SetNextBlock(lastBlock, POIFSConstants.END_OF_CHAIN);
        }