| /* This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| package org.mozilla.ffxcp; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| |
| import android.database.AbstractWindowedCursor; |
| import android.database.CursorWindow; |
| |
| public class FileCursor extends AbstractWindowedCursor { |
| public static final String _ID = "_id"; |
| public static final String CHUNK = "chunk"; |
| public static final String LENGTH = "length"; |
| static final String[] DEFCOLUMNS = new String[] { |
| _ID, |
| CHUNK, |
| LENGTH |
| }; |
| private String filePath = null; |
| private String [] theColumns = null; |
| |
| private static final int BUFSIZE = 4096; |
| private long lFileSize = 0; |
| private int nCount = 0; |
| private File theFile = null; |
| private byte [] theBuffer = null; |
| private long lOffset = 0; |
| private long lLength = -1; |
| |
| public FileCursor(String[] columnNames, String sFilePath, String [] selectionArgs) { |
| super(); |
| theColumns = (columnNames == null ? DEFCOLUMNS : columnNames); |
| filePath = sFilePath; |
| nCount = -1; |
| |
| if ((selectionArgs != null) && (selectionArgs.length > 0)) { |
| lOffset = Long.parseLong(selectionArgs[0]); |
| lLength = Long.parseLong(selectionArgs[1]); |
| } |
| |
| if (filePath.length() > 0) { |
| theFile = new File(filePath); |
| if (theFile.exists() && theFile.canRead()) { |
| lFileSize = theFile.length(); |
| |
| // lLength == -1 return everything between lOffset and eof |
| // lLength == 0 return file length |
| // lLength > 0 return lLength bytes |
| if (lLength == -1) { |
| lFileSize = lFileSize - lOffset; |
| } else if (lLength == 0) { |
| // just return the file length |
| } else { |
| lFileSize = ((lLength <= (lFileSize - lOffset)) ? lLength : (lFileSize - lOffset)); |
| } |
| |
| if (lLength != 0) { |
| nCount = (int) (lFileSize / BUFSIZE); |
| if ((lFileSize % BUFSIZE) > 0) |
| nCount++; |
| } else { |
| nCount = 1; |
| } |
| |
| } |
| } |
| } |
| |
| public String getColumnName (int columnIndex) { |
| return theColumns[columnIndex]; |
| } |
| |
| @Override |
| public String[] getColumnNames() { |
| return theColumns; |
| } |
| |
| @Override |
| public int getCount() { |
| return nCount; |
| } |
| |
| @Override |
| public boolean onMove(int oldPosition, int newPosition) { |
| boolean bRet = true; |
| |
| // get rid of old data |
| mWindow.clear(); |
| bRet = mWindow.setNumColumns(theColumns.length); |
| fillWindow(newPosition, mWindow); |
| |
| return bRet; |
| } |
| |
| @Override |
| public void fillWindow (int pos, CursorWindow window) { |
| int nNumRows = window.getNumRows(); |
| int nCIndex = 0; |
| window.setStartPosition(0); |
| |
| if (pos > -1) { |
| if (nNumRows == 0) { |
| window.allocRow(); |
| nNumRows = window.getNumRows(); |
| } |
| |
| if (nNumRows == 1) { |
| nCIndex = getColumnIndex(LENGTH); |
| if (nCIndex > -1) { |
| window.putLong(lFileSize, 0, nCIndex); |
| } |
| nCIndex = getColumnIndex(_ID); |
| if (nCIndex > -1) { |
| window.putLong((long)pos, 0, nCIndex); |
| } |
| nCIndex = getColumnIndex(CHUNK); |
| if (nCIndex > -1) { |
| if (lLength != 0) { |
| byte[] value = getABlob (pos, 1); |
| window.putBlob(value, 0, nCIndex); |
| } |
| } |
| } |
| window.setStartPosition(pos); |
| } |
| return; |
| } |
| |
| public byte[] getABlob (int row, int column) { |
| int nRead = 0; |
| int nOffset = 0; |
| int nBufSize = 0; |
| |
| if ((column == 1) && (theFile != null)) { |
| try { |
| FileInputStream fin = new FileInputStream(theFile); |
| nOffset = row * BUFSIZE; |
| if (row < (nCount - 1)) { |
| nBufSize = BUFSIZE; |
| } else { |
| nBufSize = (int) (lFileSize - nOffset); |
| } |
| theBuffer = new byte[nBufSize]; |
| |
| if (theBuffer != null) { |
| if (fin.skip(nOffset + lOffset) == (nOffset + lOffset)) { |
| if ((nRead = fin.read(theBuffer, 0, nBufSize)) != -1) { |
| if (nRead != nBufSize) { |
| return null; |
| } |
| } |
| } |
| } |
| |
| fin.close(); |
| } catch (FileNotFoundException e) { |
| e.printStackTrace(); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| return theBuffer; |
| } |
| } |