Example #1
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();
        }
Example #2
0
        /**
         * Load the block, extending the underlying stream if needed
         */
        public override ByteBuffer CreateBlockIfNeeded(int offset)
        {
            // Try to Get it without extending the stream
            try
            {
                return(GetBlockAt(offset));
            }
            catch (IndexOutOfRangeException)
            {
                // Need to extend the stream
                // TODO Replace this with proper append support
                // For now, do the extending by hand...

                // Ask for another block
                int newBigBlock = _filesystem.GetFreeBlock();
                _filesystem.CreateBlockIfNeeded(newBigBlock);

                // Tack it onto the end of our chain
                ChainLoopDetector loopDetector = _filesystem.GetChainLoopDetector();
                int block = _mini_stream.GetStartBlock();
                while (true)
                {
                    loopDetector.Claim(block);
                    int next = _filesystem.GetNextBlock(block);
                    if (next == POIFSConstants.END_OF_CHAIN)
                    {
                        break;
                    }
                    block = next;
                }
                _filesystem.SetNextBlock(block, newBigBlock);
                _filesystem.SetNextBlock(newBigBlock, POIFSConstants.END_OF_CHAIN);

                // Now try again to Get it
                return(CreateBlockIfNeeded(offset));
            }
        }