/*
* Copyright (C) 2010 Copyright 2010 Google Inc.
*
* 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 2 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, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package com.googlecode.gwtquake.server;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import com.googlecode.gwtquake.shared.common.Com;
import com.googlecode.gwtquake.shared.common.Constants;
import com.googlecode.gwtquake.shared.common.ResourceLoader;
public class ResourceLoaderImpl implements ResourceLoader.Impl {
protected static final Object LOAD_LOCK = new Object();
class Pending {
String path;
ResourceLoader.Callback callback;
byte[] bytes;
}
ArrayList<Pending> pending = new ArrayList<Pending>();
public void loadResourceAsync(String path,
final ResourceLoader.Callback callback) {
final byte[] bytes = loadResource(path);
Pending p = new Pending();
p.bytes = bytes;
p.callback = callback;
p.path = path;
pending.add(p);
}
public boolean pump() {
if (pending.size() == 0)
return false;
int i = (int) Math.random() * pending.size();
if (i < pending.size()) {
Pending p = pending.get(i);
pending.remove(i);
if (p.bytes != null) {
p.callback.onSuccess(ByteBuffer.wrap(p.bytes));
} else {
ResourceLoader.fail(new FileNotFoundException(p.path));
}
}
return true;
}
public byte[] loadResource(String path) {
RandomAccessFile file;
byte[] buf = null;
int len = 0;
// TODO hack for bad strings (fuck \0)
int index = path.indexOf('\0');
if (index != -1)
path = path.substring(0, index);
// look for it in the filesystem
len = FileLength(path);
if (len < 1)
return null;
try {
file = FOpenFile(path);
// Read(buf = new byte[len], len, h);
buf = new byte[len];
file.readFully(buf);
file.close();
} catch (IOException e) {
Com.Error(Constants.ERR_FATAL, e.toString());
}
return buf;
}
private static int FileLength(String filename) {
String netpath;
// check a file in the directory tree
netpath = Constants.BASEDIRNAME + '/' + filename;
File file = new File(netpath);
if (!file.canRead())
return -1;
Com.DPrintf("FindFile: " + netpath + '\n');
return (int) file.length();
}
private static RandomAccessFile FOpenFile(String filename) throws IOException {
String netpath;
File file = null;
netpath = Constants.BASEDIRNAME + '/' + filename;
file = new File(netpath);
if (!file.canRead())
return null;
return new RandomAccessFile(file, "r");
}
public void reset() {
// Only needed for deferred stuff
}
}