/* Subspace Mobile - A Android Subspace Client Copyright (C) 2012 Kingsley Masters. All Rights Reserved. kingsley dot masters at gmail dot com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.subspace.android; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.FileChannel.MapMode; import java.nio.channels.WritableByteChannel; import java.util.zip.InflaterInputStream; import java.util.zip.InflaterOutputStream; import org.apache.hadoop.util.PureJavaCrc32; import android.content.Context; import android.util.Log; import com.subspace.network.Util; public abstract class ZoneFile { protected static final String TAG = "Subspace"; public boolean Exists; public final String Filename; protected Context context; private static final int CRC32_BUFFERSIZE = 8 * 1024; private PureJavaCrc32 crc32Fast = new PureJavaCrc32(); private int CRC; private LittleEndianDataInputStream inputStream; public ZoneFile(Context context, String zoneName, String filename) { this.context = context; Exists = false; Filename = Util.GetSafeFilename(zoneName + "_" + filename); File file = context.getFileStreamPath(Filename); Exists = file.exists(); if (Exists) { Reload(); } } public void Save(ByteBuffer data, boolean requiresDecompressing) { Log.i(TAG, "Writing " + Filename + " " + data.limit() + " bytes"); OutputStream fos; try { if (requiresDecompressing) { fos = new alt.java.util.zip.InflaterOutputStream(context.openFileOutput(Filename, Context.MODE_PRIVATE)); } else { fos = context.openFileOutput(Filename, Context.MODE_PRIVATE); } writeBuffer(data, fos); fos.close(); } catch (IOException e) { Log.e(TAG, Log.getStackTraceString(e)); } Reload(); } public void Reload() { Log.i(TAG, "Loading " + Filename); try { getFileStream(); UpdateCRC(); } catch (IOException e) { Log.e(TAG, Log.getStackTraceString(e)); } finally { try { inputStream.close(); } catch (IOException e) { Log.e(TAG, Log.getStackTraceString(e)); } } try { getFileStream(); AfterLoad(inputStream); } catch (IOException e) { Log.e(TAG, Log.getStackTraceString(e)); } } protected void getFileStream() { inputStream = littleEndianInputStreamForFile(context.getFileStreamPath(Filename)); } protected void AfterLoad(LittleEndianDataInputStream inputStream) throws IOException { } private void UpdateCRC() throws IOException { if (inputStream != null) { Log.d(TAG, "Init CRC32"); crc32Fast.reset(); byte[] buffer = new byte[CRC32_BUFFERSIZE]; Log.d(TAG, "Processing File"); //read into buffer int len = inputStream.read(buffer); while (len>0) { //update crc32 crc32Fast.update(buffer, 0, len); //read next line into buffer len = inputStream.read(buffer); } CRC = (int)crc32Fast.getValue(); Log.d(TAG, "Completed CRC32: " + CRC); } } public void writeBuffer(ByteBuffer buffer, OutputStream stream) { WritableByteChannel channel = Channels.newChannel(stream); try { channel.write(buffer); } catch (IOException e) { // TODO Auto-generated catch block Log.e(TAG, Log.getStackTraceString(e)); } } public int getCRC32() { return CRC; } protected static LittleEndianDataInputStream littleEndianInputStreamForFile(File file) { FileInputStream fin; LittleEndianDataInputStream result =null; try { fin = new FileInputStream(file); result = new LittleEndianDataInputStream(new BufferedInputStream(fin)); } catch (FileNotFoundException e1) { Log.e(TAG, Log.getStackTraceString(e1)); } return result; } }