Statistics
| Revision:

svn-gvsig-desktop / branches / Mobile_Compatible_Hito_1 / libFMap_mobile_shp_driver / src-comp / org / gvsig / datasources / impljme / BufferedBigByteBufferJME.java @ 21865

History | View | Annotate | Download (4.61 KB)

1
package org.gvsig.datasources.impljme;
2

    
3
import java.io.IOException;
4
import java.nio.ByteBuffer;
5
import java.nio.ByteOrder;
6

    
7
import org.apache.log4j.Logger;
8
import org.gvsig.datasources.common.IBigByteBuffer;
9
import org.gvsig.datasources.common.IByteBuffer;
10
import org.gvsig.datasources.common.IRandomFileChannel;
11

    
12
/**
13
 * This class implements the IBigByteBuffer for JME. As the desktop version,
14
 * it keeps a small buffer in memory, by using the classes ByteBufferJME
15
 * and RandomFileChannelJME.
16
 * 
17
 * @see org.gvsig.datasources.impljme.ByteBufferJME
18
 * @see org.gvsig.datasources.impljme.RandomFileChannelJME
19
 * 
20
 * @author jldominguez
21
 *
22
 */
23
public class BufferedBigByteBufferJME implements IBigByteBuffer {
24

    
25
        private static Logger logger = Logger.getLogger(BufferedBigByteBufferJME.class);        
26
        
27
        /**
28
         * Memory buffer size
29
         */
30
        public static long DEFAULT_SIZE = 4*1024; // 8 Kbytes
31
        
32
        private ByteBufferJME theBuffer = null;
33
        
34
    private RandomFileChannelJME fc;
35
    private long minAbs, maxAbs, posAbs;
36
    private int minRel,  maxRel, posRel;
37
    private long sizeChunk, amountMem;
38
    private long fileSize;
39
    private int mode;
40
    
41
    public BufferedBigByteBufferJME(IRandomFileChannel ch, int acc_mode) {
42
            
43
        amountMem = DEFAULT_SIZE;
44
        fc = (RandomFileChannelJME) ch;
45
        try {
46
                        fileSize = fc.size();
47
                mode = acc_mode;
48
                sizeChunk = Math.min(fc.size(), amountMem);
49
                } catch (IOException e) {
50
                        logger.error("While instantiating: " + e.getMessage());
51
                }
52
                
53
        theBuffer = (ByteBufferJME) Impl.allocateDirect((int) sizeChunk);
54
        
55
        byte[] aux = new byte[(int) sizeChunk];
56
        
57
        fc.getAsIs(aux);
58
        
59
        theBuffer.put(aux);
60

    
61
        theBuffer.position(0);
62
        minAbs = 0;
63
        maxAbs = sizeChunk;
64
    }
65
    
66
    /**
67
     * Checks the position and loads the data if necessary.
68
     * 
69
     * @throws IOException 
70
     */
71
    private void prepareBuffer(long posActual, int numBytesToRead) 
72
    {
73
        long desiredPos = posActual + numBytesToRead;
74
        if ((desiredPos > maxAbs) || (posActual < minAbs)) {
75
                
76
                // logger.debug("Se ha pedido fuera del buffer: Tenemos: ["
77
                //                 + minAbs + " , "  + maxAbs + "], Se pide hasta: " + desiredPos);
78
            // Quiero leer fuera:
79
            sizeChunk = Math.min(fileSize-posActual, amountMem);
80
            try {
81
                mapFrom(posActual);
82
            } catch (IOException e) {
83
                e.printStackTrace();
84
            }
85
        } else {
86
                theBuffer.position((int) (posActual - minAbs));
87
                // System.out.println("NOT setting in buffer");
88
        }
89
        // Dejamos posAbs apuntando a donde va a quedar
90
        // "a priori", antes de leer de verdad, que se hace
91
        // al salir de esta funci?n.
92
        posAbs = desiredPos;
93
    }
94
    
95
    
96
    
97
    /**
98
     * @param posActual
99
     * @throws IOException
100
     */
101
    private IByteBuffer mapFrom(long newPos) throws IOException {
102
        ByteOrder lastOrder = theBuffer.order();
103
        // bb = fc.map(mode, newPos, sizeChunk);
104
        fc.position((int) newPos);
105
        // bb = ByteBuffer.wrap(buff);
106
        // bb = ByteBuffer.allocate((int)sizeChunk);
107
        theBuffer.position(0);
108
        
109
        byte[] newbuf = new byte[(int) sizeChunk];
110
        fc.getAsIs(newbuf);
111
        
112
        theBuffer = new ByteBufferJME(newbuf);
113
        // System.out.println("Mapeo desde " + newPos + " con sizeChunk= " + sizeChunk + " numRead = " + numRead);
114
        minAbs = newPos;
115
        maxAbs = sizeChunk + newPos;
116
        theBuffer.order(lastOrder);
117
        return theBuffer;
118
    }
119
    
120
    
121

    
122
        public void position(long p) {
123
                
124
        prepareBuffer(p, 0);
125
        int relPos = (int) (p - minAbs);
126
        if (relPos < 0) {
127
            System.out.println("Position=" + p);
128
        }
129
        }
130

    
131
        public int position() {
132
                // TODO Auto-generated method stub
133
                return (int) posAbs;
134
        }
135

    
136
        public byte get() {
137
        prepareBuffer(posAbs, 1);
138
        return theBuffer.get();
139
        }
140

    
141
        public byte getByte(int ind) {
142
        prepareBuffer(ind, 1);
143
        return theBuffer.get(ind - (int) minAbs);
144
        }
145

    
146
        public int getInt() {
147
        prepareBuffer(posAbs, 4);
148
        return theBuffer.getInt();
149
        }
150

    
151
        public short getShort() {
152
        prepareBuffer(posAbs, 2);
153
        return theBuffer.getShort();
154
        }
155

    
156
        public int getInt(int index) {
157
        prepareBuffer(index, 4);
158
        return theBuffer.getInt(index - (int) minAbs);
159
        }
160

    
161
        public void get(byte[] out) {
162
        prepareBuffer(posAbs, out.length);
163
        theBuffer.get(out);
164
        }
165

    
166
        public double getDouble() {
167
        prepareBuffer(posAbs, 8);
168
        return theBuffer.getDouble();
169
        }
170

    
171
        public void order(ByteOrder o) {
172
                theBuffer.order(o);
173
        }
174

    
175
}