103928aee4356845252ac6b662d5c72c29903813eJake Slack//
203928aee4356845252ac6b662d5c72c29903813eJake Slack//  ========================================================================
303928aee4356845252ac6b662d5c72c29903813eJake Slack//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
403928aee4356845252ac6b662d5c72c29903813eJake Slack//  ------------------------------------------------------------------------
503928aee4356845252ac6b662d5c72c29903813eJake Slack//  All rights reserved. This program and the accompanying materials
603928aee4356845252ac6b662d5c72c29903813eJake Slack//  are made available under the terms of the Eclipse Public License v1.0
703928aee4356845252ac6b662d5c72c29903813eJake Slack//  and Apache License v2.0 which accompanies this distribution.
803928aee4356845252ac6b662d5c72c29903813eJake Slack//
903928aee4356845252ac6b662d5c72c29903813eJake Slack//      The Eclipse Public License is available at
1003928aee4356845252ac6b662d5c72c29903813eJake Slack//      http://www.eclipse.org/legal/epl-v10.html
1103928aee4356845252ac6b662d5c72c29903813eJake Slack//
1203928aee4356845252ac6b662d5c72c29903813eJake Slack//      The Apache License v2.0 is available at
1303928aee4356845252ac6b662d5c72c29903813eJake Slack//      http://www.opensource.org/licenses/apache2.0.php
1403928aee4356845252ac6b662d5c72c29903813eJake Slack//
1503928aee4356845252ac6b662d5c72c29903813eJake Slack//  You may elect to redistribute this code under either of these licenses.
1603928aee4356845252ac6b662d5c72c29903813eJake Slack//  ========================================================================
1703928aee4356845252ac6b662d5c72c29903813eJake Slack//
1803928aee4356845252ac6b662d5c72c29903813eJake Slack
1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.io.nio;
2003928aee4356845252ac6b662d5c72c29903813eJake Slack
2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.File;
2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.FileNotFoundException;
2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException;
2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.RandomAccessFile;
2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.nio.channels.FileChannel;
2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.nio.channels.WritableByteChannel;
2703928aee4356845252ac6b662d5c72c29903813eJake Slack
2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.AbstractBuffer;
2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.Buffer;
3003928aee4356845252ac6b662d5c72c29903813eJake Slack
3103928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class RandomAccessFileBuffer extends AbstractBuffer implements Buffer
3203928aee4356845252ac6b662d5c72c29903813eJake Slack{
3303928aee4356845252ac6b662d5c72c29903813eJake Slack    final RandomAccessFile _file;
3403928aee4356845252ac6b662d5c72c29903813eJake Slack    final FileChannel _channel;
3503928aee4356845252ac6b662d5c72c29903813eJake Slack    final int _capacity;
3603928aee4356845252ac6b662d5c72c29903813eJake Slack
3703928aee4356845252ac6b662d5c72c29903813eJake Slack    public RandomAccessFileBuffer(File file)
3803928aee4356845252ac6b662d5c72c29903813eJake Slack        throws FileNotFoundException
3903928aee4356845252ac6b662d5c72c29903813eJake Slack    {
4003928aee4356845252ac6b662d5c72c29903813eJake Slack        super(READWRITE,true);
4103928aee4356845252ac6b662d5c72c29903813eJake Slack        assert file.length()<=Integer.MAX_VALUE;
4203928aee4356845252ac6b662d5c72c29903813eJake Slack        _file = new RandomAccessFile(file,"rw");
4303928aee4356845252ac6b662d5c72c29903813eJake Slack        _channel=_file.getChannel();
4403928aee4356845252ac6b662d5c72c29903813eJake Slack        _capacity=Integer.MAX_VALUE;
4503928aee4356845252ac6b662d5c72c29903813eJake Slack        setGetIndex(0);
4603928aee4356845252ac6b662d5c72c29903813eJake Slack        setPutIndex((int)file.length());
4703928aee4356845252ac6b662d5c72c29903813eJake Slack    }
4803928aee4356845252ac6b662d5c72c29903813eJake Slack
4903928aee4356845252ac6b662d5c72c29903813eJake Slack    public RandomAccessFileBuffer(File file,int capacity)
5003928aee4356845252ac6b662d5c72c29903813eJake Slack        throws FileNotFoundException
5103928aee4356845252ac6b662d5c72c29903813eJake Slack    {
5203928aee4356845252ac6b662d5c72c29903813eJake Slack        super(READWRITE,true);
5303928aee4356845252ac6b662d5c72c29903813eJake Slack        assert capacity>=file.length();
5403928aee4356845252ac6b662d5c72c29903813eJake Slack        assert file.length()<=Integer.MAX_VALUE;
5503928aee4356845252ac6b662d5c72c29903813eJake Slack        _capacity=capacity;
5603928aee4356845252ac6b662d5c72c29903813eJake Slack        _file = new RandomAccessFile(file,"rw");
5703928aee4356845252ac6b662d5c72c29903813eJake Slack        _channel=_file.getChannel();
5803928aee4356845252ac6b662d5c72c29903813eJake Slack        setGetIndex(0);
5903928aee4356845252ac6b662d5c72c29903813eJake Slack        setPutIndex((int)file.length());
6003928aee4356845252ac6b662d5c72c29903813eJake Slack    }
6103928aee4356845252ac6b662d5c72c29903813eJake Slack
6203928aee4356845252ac6b662d5c72c29903813eJake Slack    public RandomAccessFileBuffer(File file,int capacity,int access)
6303928aee4356845252ac6b662d5c72c29903813eJake Slack        throws FileNotFoundException
6403928aee4356845252ac6b662d5c72c29903813eJake Slack    {
6503928aee4356845252ac6b662d5c72c29903813eJake Slack        super(access,true);
6603928aee4356845252ac6b662d5c72c29903813eJake Slack        assert capacity>=file.length();
6703928aee4356845252ac6b662d5c72c29903813eJake Slack        assert file.length()<=Integer.MAX_VALUE;
6803928aee4356845252ac6b662d5c72c29903813eJake Slack        _capacity=capacity;
6903928aee4356845252ac6b662d5c72c29903813eJake Slack        _file = new RandomAccessFile(file,access==READWRITE?"rw":"r");
7003928aee4356845252ac6b662d5c72c29903813eJake Slack        _channel=_file.getChannel();
7103928aee4356845252ac6b662d5c72c29903813eJake Slack        setGetIndex(0);
7203928aee4356845252ac6b662d5c72c29903813eJake Slack        setPutIndex((int)file.length());
7303928aee4356845252ac6b662d5c72c29903813eJake Slack    }
7403928aee4356845252ac6b662d5c72c29903813eJake Slack
7503928aee4356845252ac6b662d5c72c29903813eJake Slack    public byte[] array()
7603928aee4356845252ac6b662d5c72c29903813eJake Slack    {
7703928aee4356845252ac6b662d5c72c29903813eJake Slack        return null;
7803928aee4356845252ac6b662d5c72c29903813eJake Slack    }
7903928aee4356845252ac6b662d5c72c29903813eJake Slack
8003928aee4356845252ac6b662d5c72c29903813eJake Slack    public int capacity()
8103928aee4356845252ac6b662d5c72c29903813eJake Slack    {
8203928aee4356845252ac6b662d5c72c29903813eJake Slack        return _capacity;
8303928aee4356845252ac6b662d5c72c29903813eJake Slack    }
8403928aee4356845252ac6b662d5c72c29903813eJake Slack
8503928aee4356845252ac6b662d5c72c29903813eJake Slack    @Override
8603928aee4356845252ac6b662d5c72c29903813eJake Slack    public void clear()
8703928aee4356845252ac6b662d5c72c29903813eJake Slack    {
8803928aee4356845252ac6b662d5c72c29903813eJake Slack        try
8903928aee4356845252ac6b662d5c72c29903813eJake Slack        {
9003928aee4356845252ac6b662d5c72c29903813eJake Slack            synchronized (_file)
9103928aee4356845252ac6b662d5c72c29903813eJake Slack            {
9203928aee4356845252ac6b662d5c72c29903813eJake Slack                super.clear();
9303928aee4356845252ac6b662d5c72c29903813eJake Slack                _file.setLength(0);
9403928aee4356845252ac6b662d5c72c29903813eJake Slack            }
9503928aee4356845252ac6b662d5c72c29903813eJake Slack        }
9603928aee4356845252ac6b662d5c72c29903813eJake Slack        catch(Exception e)
9703928aee4356845252ac6b662d5c72c29903813eJake Slack        {
9803928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new RuntimeException(e);
9903928aee4356845252ac6b662d5c72c29903813eJake Slack        }
10003928aee4356845252ac6b662d5c72c29903813eJake Slack    }
10103928aee4356845252ac6b662d5c72c29903813eJake Slack
10203928aee4356845252ac6b662d5c72c29903813eJake Slack
10303928aee4356845252ac6b662d5c72c29903813eJake Slack    @Override
10403928aee4356845252ac6b662d5c72c29903813eJake Slack    public byte peek()
10503928aee4356845252ac6b662d5c72c29903813eJake Slack    {
10603928aee4356845252ac6b662d5c72c29903813eJake Slack        synchronized (_file)
10703928aee4356845252ac6b662d5c72c29903813eJake Slack        {
10803928aee4356845252ac6b662d5c72c29903813eJake Slack            try
10903928aee4356845252ac6b662d5c72c29903813eJake Slack            {
11003928aee4356845252ac6b662d5c72c29903813eJake Slack                if (_get!=_file.getFilePointer())
11103928aee4356845252ac6b662d5c72c29903813eJake Slack                    _file.seek(_get);
11203928aee4356845252ac6b662d5c72c29903813eJake Slack                return _file.readByte();
11303928aee4356845252ac6b662d5c72c29903813eJake Slack            }
11403928aee4356845252ac6b662d5c72c29903813eJake Slack            catch(Exception e)
11503928aee4356845252ac6b662d5c72c29903813eJake Slack            {
11603928aee4356845252ac6b662d5c72c29903813eJake Slack                throw new RuntimeException(e);
11703928aee4356845252ac6b662d5c72c29903813eJake Slack            }
11803928aee4356845252ac6b662d5c72c29903813eJake Slack        }
11903928aee4356845252ac6b662d5c72c29903813eJake Slack    }
12003928aee4356845252ac6b662d5c72c29903813eJake Slack
12103928aee4356845252ac6b662d5c72c29903813eJake Slack    public byte peek(int index)
12203928aee4356845252ac6b662d5c72c29903813eJake Slack    {
12303928aee4356845252ac6b662d5c72c29903813eJake Slack        synchronized (_file)
12403928aee4356845252ac6b662d5c72c29903813eJake Slack        {
12503928aee4356845252ac6b662d5c72c29903813eJake Slack            try
12603928aee4356845252ac6b662d5c72c29903813eJake Slack            {
12703928aee4356845252ac6b662d5c72c29903813eJake Slack                _file.seek(index);
12803928aee4356845252ac6b662d5c72c29903813eJake Slack                return _file.readByte();
12903928aee4356845252ac6b662d5c72c29903813eJake Slack            }
13003928aee4356845252ac6b662d5c72c29903813eJake Slack            catch(Exception e)
13103928aee4356845252ac6b662d5c72c29903813eJake Slack            {
13203928aee4356845252ac6b662d5c72c29903813eJake Slack                throw new RuntimeException(e);
13303928aee4356845252ac6b662d5c72c29903813eJake Slack            }
13403928aee4356845252ac6b662d5c72c29903813eJake Slack        }
13503928aee4356845252ac6b662d5c72c29903813eJake Slack    }
13603928aee4356845252ac6b662d5c72c29903813eJake Slack
13703928aee4356845252ac6b662d5c72c29903813eJake Slack    public int peek(int index, byte[] b, int offset, int length)
13803928aee4356845252ac6b662d5c72c29903813eJake Slack    {
13903928aee4356845252ac6b662d5c72c29903813eJake Slack        synchronized (_file)
14003928aee4356845252ac6b662d5c72c29903813eJake Slack        {
14103928aee4356845252ac6b662d5c72c29903813eJake Slack            try
14203928aee4356845252ac6b662d5c72c29903813eJake Slack            {
14303928aee4356845252ac6b662d5c72c29903813eJake Slack                _file.seek(index);
14403928aee4356845252ac6b662d5c72c29903813eJake Slack                return _file.read(b,offset,length);
14503928aee4356845252ac6b662d5c72c29903813eJake Slack            }
14603928aee4356845252ac6b662d5c72c29903813eJake Slack            catch(Exception e)
14703928aee4356845252ac6b662d5c72c29903813eJake Slack            {
14803928aee4356845252ac6b662d5c72c29903813eJake Slack                throw new RuntimeException(e);
14903928aee4356845252ac6b662d5c72c29903813eJake Slack            }
15003928aee4356845252ac6b662d5c72c29903813eJake Slack        }
15103928aee4356845252ac6b662d5c72c29903813eJake Slack    }
15203928aee4356845252ac6b662d5c72c29903813eJake Slack
15303928aee4356845252ac6b662d5c72c29903813eJake Slack    public void poke(int index, byte b)
15403928aee4356845252ac6b662d5c72c29903813eJake Slack    {
15503928aee4356845252ac6b662d5c72c29903813eJake Slack        synchronized (_file)
15603928aee4356845252ac6b662d5c72c29903813eJake Slack        {
15703928aee4356845252ac6b662d5c72c29903813eJake Slack            try
15803928aee4356845252ac6b662d5c72c29903813eJake Slack            {
15903928aee4356845252ac6b662d5c72c29903813eJake Slack                _file.seek(index);
16003928aee4356845252ac6b662d5c72c29903813eJake Slack                _file.writeByte(b);
16103928aee4356845252ac6b662d5c72c29903813eJake Slack            }
16203928aee4356845252ac6b662d5c72c29903813eJake Slack            catch(Exception e)
16303928aee4356845252ac6b662d5c72c29903813eJake Slack            {
16403928aee4356845252ac6b662d5c72c29903813eJake Slack                throw new RuntimeException(e);
16503928aee4356845252ac6b662d5c72c29903813eJake Slack            }
16603928aee4356845252ac6b662d5c72c29903813eJake Slack        }
16703928aee4356845252ac6b662d5c72c29903813eJake Slack    }
16803928aee4356845252ac6b662d5c72c29903813eJake Slack
16903928aee4356845252ac6b662d5c72c29903813eJake Slack    @Override
17003928aee4356845252ac6b662d5c72c29903813eJake Slack    public int poke(int index, byte[] b, int offset, int length)
17103928aee4356845252ac6b662d5c72c29903813eJake Slack    {
17203928aee4356845252ac6b662d5c72c29903813eJake Slack        synchronized (_file)
17303928aee4356845252ac6b662d5c72c29903813eJake Slack        {
17403928aee4356845252ac6b662d5c72c29903813eJake Slack            try
17503928aee4356845252ac6b662d5c72c29903813eJake Slack            {
17603928aee4356845252ac6b662d5c72c29903813eJake Slack                _file.seek(index);
17703928aee4356845252ac6b662d5c72c29903813eJake Slack                _file.write(b,offset,length);
17803928aee4356845252ac6b662d5c72c29903813eJake Slack                return length;
17903928aee4356845252ac6b662d5c72c29903813eJake Slack            }
18003928aee4356845252ac6b662d5c72c29903813eJake Slack            catch(Exception e)
18103928aee4356845252ac6b662d5c72c29903813eJake Slack            {
18203928aee4356845252ac6b662d5c72c29903813eJake Slack                throw new RuntimeException(e);
18303928aee4356845252ac6b662d5c72c29903813eJake Slack            }
18403928aee4356845252ac6b662d5c72c29903813eJake Slack        }
18503928aee4356845252ac6b662d5c72c29903813eJake Slack    }
18603928aee4356845252ac6b662d5c72c29903813eJake Slack
18703928aee4356845252ac6b662d5c72c29903813eJake Slack    public int writeTo(WritableByteChannel channel,int index, int length)
18803928aee4356845252ac6b662d5c72c29903813eJake Slack        throws IOException
18903928aee4356845252ac6b662d5c72c29903813eJake Slack    {
19003928aee4356845252ac6b662d5c72c29903813eJake Slack        synchronized (_file)
19103928aee4356845252ac6b662d5c72c29903813eJake Slack        {
19203928aee4356845252ac6b662d5c72c29903813eJake Slack            return (int)_channel.transferTo(index,length,channel);
19303928aee4356845252ac6b662d5c72c29903813eJake Slack        }
19403928aee4356845252ac6b662d5c72c29903813eJake Slack    }
19503928aee4356845252ac6b662d5c72c29903813eJake Slack
19603928aee4356845252ac6b662d5c72c29903813eJake Slack}
197