<commit_before>package hxd.fmt.pak;
import hxd.fs.FileEntry;
#if air3
import hxd.impl.Air3File;
#else
import sys.io.File;
import sys.io.FileInput;
#end

@:allow(hxd.fmt.pak.FileSystem)
private class PakEntry extends FileEntry {

	var parent : PakEntry;
	var file : Data.File;
	var pak : FileInput;
	var subs : Array<PakEntry>;

	var openedBytes : haxe.io.Bytes;
	var bytesPosition : Int;

	public function new(parent, f, p) {
		this.file = f;
		this.pak = p;
		this.parent = parent;
		name = file.name;
		if( f.isDirectory ) subs = [];
	}

	override function get_path() {
		return parent == null ? "<root>" : (parent.parent == null ? name : parent.path + "/" + name);
	}

	override function get_size() {
		return file.dataSize;
	}

	override function get_isDirectory() {
		return file.isDirectory;
	}

	override function getSign() {
		pak.seek(file.dataPosition, SeekBegin);
		return pak.readInt32();
	}

	override function getBytes() {
		pak.seek(file.dataPosition, SeekBegin);
		return pak.read(file.dataSize);
	}

	override function getTmpBytes() {
		pak.seek(file.dataPosition, SeekBegin);
		var tmp = hxd.impl.Tmp.getBytes(file.dataSize);
		pak.readFullBytes(tmp, 0, file.dataSize);
		return tmp;
	}

	override function open() {
		if( openedBytes == null ) {
			openedBytes = hxd.impl.Tmp.getBytes(file.dataSize);
			pak.seek(file.dataPosition, SeekBegin);
			pak.readBytes(openedBytes, 0, file.dataSize);
		}
		bytesPosition = 0;
	}

	override function close() {
		if( openedBytes != null ) {
			hxd.impl.Tmp.saveBytes(openedBytes);
			openedBytes = null;
		}
	}

	override function skip( nbytes ) {
		if( nbytes < 0 || bytesPosition + nbytes > file.dataSize ) throw "Invalid skip";
		bytesPosition += nbytes;
	}

	override function readByte() {
		return openedBytes.get(bytesPosition++);
	}

	override function read( out : haxe.io.Bytes, pos : Int, len : Int ) {
		out.blit(pos, openedBytes, bytesPosition, len);
		bytesPosition += len;
	}

	override function exists( name : String ) {
		if( subs != null )
			for( c in subs )
				if( c.name == name )
					return true;
		return false;
	}

	override function get( name : String ) : FileEntry {
		if( subs != null )
			for( c in subs )
				if( c.name == name )
					return c;
		return null;
	}

	override function iterator() {
		return new hxd.impl.ArrayIterator<FileEntry>(cast subs);
	}

	override function loadBitmap( onLoaded ) {
		#if flash
		var loader = new flash.display.Loader();
		loader.contentLoaderInfo.addEventListener(flash.events.IOErrorEvent.IO_ERROR, function(e:flash.events.IOErrorEvent) {
			throw Std.string(e) + " while loading " + path;
		});
		loader.contentLoaderInfo.addEventListener(flash.events.Event.COMPLETE, function(_) {
			var content : flash.display.Bitmap = cast loader.content;
			onLoaded(new hxd.fs.LoadedBitmap(content.bitmapData));
			loader.unload();
		});
		var op = openedBytes != null;
		if( !op ) open();
		loader.loadBytes(openedBytes.getData());
		if( !op ) close();
		#else
		super.loadBitmap(onLoaded);
		#end
	}

}

class FileSystem implements hxd.fs.FileSystem {

	var root : PakEntry;
	var dict : Map<String,PakEntry>;
	var files : Array<FileInput>;<commit_msg>fixed loadBitmap reusing wrong data<commit_after>package hxd.fmt.pak;
import hxd.fs.FileEntry;
#if air3
import hxd.impl.Air3File;
#else
import sys.io.File;
import sys.io.FileInput;
#end

@:allow(hxd.fmt.pak.FileSystem)
private class PakEntry extends FileEntry {

	var parent : PakEntry;
	var file : Data.File;
	var pak : FileInput;
	var subs : Array<PakEntry>;

	var openedBytes : haxe.io.Bytes;
	var bytesPosition : Int;

	public function new(parent, f, p) {
		this.file = f;
		this.pak = p;
		this.parent = parent;
		name = file.name;
		if( f.isDirectory ) subs = [];
	}

	override function get_path() {
		return parent == null ? "<root>" : (parent.parent == null ? name : parent.path + "/" + name);
	}

	override function get_size() {
		return file.dataSize;
	}

	override function get_isDirectory() {
		return file.isDirectory;
	}

	override function getSign() {
		pak.seek(file.dataPosition, SeekBegin);
		return pak.readInt32();
	}

	override function getBytes() {
		pak.seek(file.dataPosition, SeekBegin);
		return pak.read(file.dataSize);
	}

	override function getTmpBytes() {
		pak.seek(file.dataPosition, SeekBegin);
		var tmp = hxd.impl.Tmp.getBytes(file.dataSize);
		pak.readFullBytes(tmp, 0, file.dataSize);
		return tmp;
	}

	override function open() {
		if( openedBytes == null ) {
			openedBytes = hxd.impl.Tmp.getBytes(file.dataSize);
			pak.seek(file.dataPosition, SeekBegin);
			pak.readBytes(openedBytes, 0, file.dataSize);
		}
		bytesPosition = 0;
	}

	override function close() {
		if( openedBytes != null ) {
			hxd.impl.Tmp.saveBytes(openedBytes);
			openedBytes = null;
		}
	}

	override function skip( nbytes ) {
		if( nbytes < 0 || bytesPosition + nbytes > file.dataSize ) throw "Invalid skip";
		bytesPosition += nbytes;
	}

	override function readByte() {
		return openedBytes.get(bytesPosition++);
	}

	override function read( out : haxe.io.Bytes, pos : Int, len : Int ) {
		out.blit(pos, openedBytes, bytesPosition, len);
		bytesPosition += len;
	}

	override function exists( name : String ) {
		if( subs != null )
			for( c in subs )
				if( c.name == name )
					return true;
		return false;
	}

	override function get( name : String ) : FileEntry {
		if( subs != null )
			for( c in subs )
				if( c.name == name )
					return c;
		return null;
	}

	override function iterator() {
		return new hxd.impl.ArrayIterator<FileEntry>(cast subs);
	}

	override function loadBitmap( onLoaded ) {
		#if flash
		if( openedBytes != null ) throw "Must close() before loadBitmap";
		open();
		var old = openedBytes;
		var loader = new flash.display.Loader();
		loader.contentLoaderInfo.addEventListener(flash.events.IOErrorEvent.IO_ERROR, function(e:flash.events.IOErrorEvent) {
			throw Std.string(e) + " while loading " + path;
		});
		loader.contentLoaderInfo.addEventListener(flash.events.Event.COMPLETE, function(_) {
			if( openedBytes == null ) {
				openedBytes = old;
				close();
			}
			var content : flash.display.Bitmap = cast loader.content;
			onLoaded(new hxd.fs.LoadedBitmap(content.bitmapData));
			loader.unload();
		});
		loader.loadBytes(openedBytes.getData());
		openedBytes = null;
		#else
		super.loadBitmap(onLoaded);
		#end
	}

}

class FileSystem implements hxd.fs.FileSystem {

	var root : PakEntry;
	var dict : Map<String,PakEntry>;
	var files : Array<FileInput>;
{'fraction_non_alphanumeric': 0.13186304750154226, 'fraction_numerical': 0.0024676125848241827, 'mean_word_length': 3.740497076023392, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5363305', 'n_tokens_mistral': 2447, 'n_tokens_neox': 2213, 'n_words': 537}