// Scilab 4+ Implementation of BinaryMatrixFile



function [rows, cols]=getBMFSizeInternal(fhand)
	arch64 = part(sprintf("%li",2^32),[1]) <> '-';
	if arch64;
		a = mget(2,"ib",fhand);
	else;
		a = mget(2,"lb",fhand);
	end;

	rows = a(1);
	cols = a(2);
	//printf("getBMFSizeInternal(): rows = %i, cols = %i\n", rows, cols);
	if cols == 0 | rows == 0;
		if (rows == 0 & cols <> 0) | (cols == 0 & rows <> 0);
			printf("getBMFSizeInternal(): cols = %i but rows = %i\n", cols, rows);
		end;
		s=[0, 0];
		return;
	end;

	mseek(0,fhand,'end');
	fsiz = mtell(fhand);
	mseek(8,fhand,'set');
	rowsAvail = int((fsiz - 8) / (cols * 8));

	//printf("getBMFSizeInternal(): fsiz = %i, rowsAvail = %i\n", fsiz, rowsAvail);

	if rows < 0;
		rows = rowsAvail;
	elseif rows <> rowsAvail;
		printf("File reports %i rows but %i available in file\n", rows, rowsAvail);
		rows = rowsAvail;
	end;
	
	s=[rows, cols];
endfunction

function [rows, cols]=getBMFSize(fileName)
	fhand = mopen(fileName,"rb");
	[rows, cols] = getBMFSizeInternal(fhand);
	mclose(fhand);
endfunction

function data = binRead(fileName)

	fhand = mopen(fileName,"rb");
	[rows, cols] = getBMFSizeInternal(fhand);
	//printf("getBMFSizeInternal reports rows=%i, cols=%i\n", rows, cols);
	
	data = mget(rows*cols,"db",fhand);
	mclose(fhand);

	dlen = size(data,2);
	//printf("dlen=%i, rows*cols=%i\n", dlen, rows*cols);
	if dlen < rows*cols;
		printf("file says %i x %i but only got %i, using only ",rows,cols,dlen);
		rows = int(dlen / cols);
		data = data(1:rows*cols); //truncate to last complete row
		dlen=size(data,2);
		printf("%i rows. Data len now %i\n",rows,dlen);

	end;
	data = matrix(data,cols,rows)';	
endfunction

// Scilab 4+ Implementation of BinaryMatrixFile
// read a selected set of row/cols from file
function data = binReadPart(fileName, rowIdxs, colIdxs)

	fhand = mopen(fileName,"rb");
	[rows, cols] = getBMFSizeInternal(fhand);
	
	if length(rowIdxs) <= 0; rowIdxs = 1:rows; printf("All rows\n"); end;
	if length(colIdxs) <= 0; colIdxs = 1:cols; printf("All cols\n"); end;

	if min(rowIdxs) < 1; printf("Invalid row index (< 1)\n"); data=[]; return; end;
	if min(colIdxs) < 1; printf("Invalid col index (< 1)\n"); data=[]; return; end;
	if max(rowIdxs) > rows; printf("Row index out of range (> %i)\n", rows); data=[]; return; end;
	if max(colIdxs) > cols; printf("Col index out of range (> %i)\n", cols); data=[]; return; end;

	data = zeros( length(rowIdxs), length(colIdxs) );
	for i=1:length(rowIdxs);
		mseek(8 + ((rowIdxs(i)-1)*cols)*8, fhand, 'set');
		//read the whole column
		colData = mget(cols, "db", fhand);

		//and copy the relevant bits in
		data(i, :) = colData( colIdxs );
	end;
	mclose(fhand);

endfunction
