/* ==========================================
     zmd2mid 可変長形式の数値を読み書きする
   ========================================== */

#include "config.h"
int PutVarLen(UBYTE *MTrk,DWORD value);
int GetVarLen(UBYTE *MTrk,DWORD *value);
int get_VarLen_bytes(DWORD num);

/* =====================================
     MTrkにvalueを可変長形式で書き込む (from StdMIDIfileのテキスト)
   ===================================== */

int PutVarLen(UBYTE *MTrk,DWORD value)	/* 返り値：書き込んだバイト数 */
{
	DWORD buffer = value & 0x7F;
	int count = 0;

	while ((value >>= 7) > 0) {
		buffer <<= 8;
		buffer |= 0x80;
		buffer += (value & 0x7f);
	}
	while (1) {
		MTrk[count++] = (buffer & 0xFF);
		if (buffer & 0x80) {
			buffer >>= 8;
		} else {
			break;
		}
	}
	return count;
}


/* =====================================
     MTrkから可変長形式のvalueを読み、*valueに返す (from StdMIDIfileのテキスト)
　　　ついでに読み進めたバイト数を返す
   ===================================== */

int GetVarLen(UBYTE *MTrk,DWORD *value)
{
	int count = 1;
	UBYTE c;

	if ( ((*value) = MTrk[0]) & 0x80 ) {
		(*value) &= 0x7f;
		do {
			(*value) <<= 7;
			(*value) += ((c = MTrk[count++]) & 0x7f);
		} while (c & 0x80);
	}

	return count;
}


/* ==================================================
     引数を可変長形式の数値にした時のバイト数を返す
   ================================================== */

int get_VarLen_bytes(DWORD num)
{
	int bytes;

	if (num < 0x80)
		bytes = 1;
	else if (num < 0x80 * 0x80)
		bytes = 2;
	else if (num < 0x80 * 0x80 * 0x80)
		bytes = 3;
	else
		bytes = 4;

	return bytes;
}
