⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rio.cpp

📁 这是一个mp3的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{
	CDirHeader& cDirHeader = m_cDirBlock.m_cDirHeader;

	// init directory header
	memset( &m_cDirBlock.m_cDirHeader, 0, sizeof(m_cDirBlock.m_cDirHeader) );

	//	set version (so compatible with Rio Manager v1.01)
	cDirHeader.m_usVersion = 0x0100;
	// init directory entries
	memset( &m_cDirBlock.m_acDirEntry, 0, sizeof(m_cDirBlock.m_acDirEntry) );
	// init block used flags
	memset( &m_cDirBlock.m_auc32KBlockUsed, CRIO_ID_32KBLOCK_FREE, sizeof(m_cDirBlock.m_auc32KBlockUsed) );
	// init FAT
	memset( &m_cDirBlock.m_ausFAT, 0, sizeof(m_cDirBlock.m_ausFAT) );

	// if mark bad block request
	if ( bMarkBadBlock )
	{
		if ( !MarkBadBlocks(pfProgress, cookie) )
			return FALSE;
	}

	// available blocks
	if ( m_bUseExternalFlash )
		cDirHeader.m_usCount32KBlockAvailable = m_uiCount32KBlockAvailableExternal;
	else
		cDirHeader.m_usCount32KBlockAvailable = m_bSpecialEdition ? CRIO_COUNT_32KBLOCKIN64M : CRIO_COUNT_32KBLOCKIN32M;

	// blocks remaining (taking into account bad blocks)
	cDirHeader.m_usCount32KBlockRemaining =
		cDirHeader.m_usCount32KBlockAvailable -
		cDirHeader.m_usCount32KBlockBad;

	return TRUE;
}

BOOL CRio::RemoveFile( const char* pszFile )
{
	// get directory entry for file
	CDirEntry* pDirEntry = FindFile( pszFile );
	if ( !pDirEntry )
	{
		LogError( CRIO_ERROR_FILENOTFOUND, "file '%s' not present on device", pszFile );
		return FALSE;
	}

	// free FAT and blocks used
	USHORT usPos32KBlock = pDirEntry->m_usPos32KBlock;
	while( usPos32KBlock )
	{
		m_cDirBlock.m_auc32KBlockUsed[ usPos32KBlock ] = CRIO_ID_32KBLOCK_FREE;
		USHORT usTemp = m_cDirBlock.m_ausFAT[ usPos32KBlock ];
		m_cDirBlock.m_ausFAT[ usPos32KBlock ] = 0;
		usPos32KBlock = usTemp;
	}

	// adjust directory header
	CDirHeader& cDirHeader = m_cDirBlock.m_cDirHeader;
	--cDirHeader.m_usCountEntry;
	cDirHeader.m_usCount32KBlockUsed -= pDirEntry->m_usCount32KBlock;
	cDirHeader.m_usCount32KBlockRemaining += pDirEntry->m_usCount32KBlock;

	// clear directory entry
	memset( pDirEntry, 0, sizeof(CDirEntry) );

	// shuffle directory entries
	int iPosEntry = pDirEntry - m_cDirBlock.m_acDirEntry;
	int iCount = (int)cDirHeader.m_usCountEntry - iPosEntry;
	for( int iA=0; iA<iCount; ++iA )
	{
		memcpy(
			&m_cDirBlock.m_acDirEntry[ iPosEntry+iA ],
			&m_cDirBlock.m_acDirEntry[ iPosEntry+iA+1 ],
			sizeof(CDirEntry)
		);
	}

	return TRUE;
}

BOOL CRio::RemoveAllFiles( void )
{
	CDirHeader& cDirHeader = m_cDirBlock.m_cDirHeader;

	// init entries
	cDirHeader.m_usCountEntry = 0;

	// init block used flags
	UCHAR* pauc = m_cDirBlock.m_auc32KBlockUsed;
	for( int iA=0; iA<CRIO_MAX_32KBLOCK; ++iA, ++pauc )
	{
		if ( *pauc != CRIO_ID_32KBLOCK_BAD )
			*pauc = CRIO_ID_32KBLOCK_FREE;
	}

	// init FAT
	memset( &m_cDirBlock.m_ausFAT, 0, sizeof(m_cDirBlock.m_ausFAT) );

	// available blocks
	if ( m_bUseExternalFlash )
		cDirHeader.m_usCount32KBlockAvailable = m_uiCount32KBlockAvailableExternal;
	else
		cDirHeader.m_usCount32KBlockAvailable = m_bSpecialEdition ? CRIO_COUNT_32KBLOCKIN64M : CRIO_COUNT_32KBLOCKIN32M;

	// used
	cDirHeader.m_usCount32KBlockUsed = cDirHeader.m_usCount32KBlockBad;

	// blocks remaining
	cDirHeader.m_usCount32KBlockRemaining =
		cDirHeader.m_usCount32KBlockAvailable -
		cDirHeader.m_usCount32KBlockUsed;

	return TRUE;
}

BOOL CRio::SetFileOrder( UINT* pauiPosOrder, UINT uiCount )
{
	// create copy of directory entries
	CDirEntry* paDirEntry = m_cDirBlock.m_acDirEntry;
	CDirEntry* paDirEntryNew = new CDirEntry[ CRIO_MAX_DIRENTRY ];
	if ( !paDirEntryNew )
	{
		LogError( CRIO_ERROR_ALLOC, "new failed" );
		return FALSE;
	}
	memcpy( paDirEntryNew, paDirEntry, CRIO_MAX_DIRENTRY * sizeof(CDirEntry) );

	// current entry count
	UINT uiCountEntry = m_cDirBlock.m_cDirHeader.m_usCountEntry;

	// move entries
	for( UINT uiPosNew=0; uiPosNew<uiCount; ++uiPosNew )
	{
		UINT uiPosOld = pauiPosOrder[ uiPosNew ];

		if ( uiPosOld >= uiCountEntry || uiPosNew >= uiCountEntry )
		{
			LogError( CRIO_ERROR_INVALIDFILEPOSITION, "invalid file position" );
			DELETEARRAY paDirEntryNew;
			return FALSE;
		}

		memcpy( &paDirEntryNew[uiPosNew], &paDirEntry[uiPosOld], sizeof(CDirEntry) );
	}

	// update current directory entries
	memcpy( paDirEntry, paDirEntryNew, CRIO_MAX_DIRENTRY * sizeof(CDirEntry) );

	DELETEARRAY paDirEntryNew;

	return TRUE;
}

BOOL CRio::TxDirectory( void )
{
	// create zero initialized temp block
	UCHAR* paucBlock;
	ZERONEWBLOCK( paucBlock );

	// directory header
	CDirHeader& cDirHeader = m_cDirBlock.m_cDirHeader;
	// update directory header time
	cDirHeader.m_lTimeLastUpdate = time( NULL );
	// create checksums (note: second checksum needs to be calculated first as
	//	this makes up part of the first checksum)
	cDirHeader.m_usChecksum2 = CalculateChecksum2();
	cDirHeader.m_usChecksum1 = CalculateChecksum1();

	// copy directory block to temp block
	memcpy( paucBlock, &m_cDirBlock, sizeof(m_cDirBlock) );

	// send block
	BOOL bResult = Tx32KBlock( paucBlock, 0, 0, 0 );
	if ( bResult )
	{
		// IO outro
		IOOutro();
	}

	// release temp block
	DELETEBLOCK( paucBlock );

	return bResult;
}

BOOL CRio::RxDirectory( void )
{
	// create temp block
	UCHAR* paucBlock;
	NEWBLOCK( paucBlock );

	// get block
	BOOL bResult = Rx32KBlock( paucBlock, 0 );
	if ( bResult )
	{
		// io outro
		IOOutro();

		// store directory
		memcpy( &m_cDirBlock, paucBlock, sizeof(m_cDirBlock) );

		// validate checksums
		USHORT usChecksum1 = (USHORT)CalculateChecksum1();
		USHORT usChecksum2 = (USHORT)CalculateChecksum2();
		if (
			usChecksum1 != m_cDirBlock.m_cDirHeader.m_usChecksum1 ||
			usChecksum2 != m_cDirBlock.m_cDirHeader.m_usChecksum2
		)
		{
			LogError( CRIO_ERROR_CORRUPT, "invalid directory checksum, initialization recommended" );
			bResult = FALSE;
		}
	}

	// release temp block
	DELETEBLOCK( paucBlock );

	return bResult;
}

BOOL CRio::TxFile( const char* pszPathFile, BOOL (*pfProgress)(int iPos, int iCount, void* cookie), void* cookie)
{
	// directory header
	CDirHeader& cDirHeader = m_cDirBlock.m_cDirHeader;

	// if no enough room in directory for entry
	if ( cDirHeader.m_usCountEntry >= CRIO_MAX_DIRENTRY )
	{
		LogError( CRIO_ERROR_MAXDIRENTRY, "max number of directory entries (%d) already in use", CRIO_MAX_DIRENTRY );
		return FALSE;
	}

	// open file for read
	FILE* fpFile = fopen( pszPathFile, "rb" );
	if ( !fpFile )
	{
		LogError( CRIO_ERROR_OPEN, "unable to open '%s' for read", pszPathFile );
		return FALSE;
	}

	// get fileinfo
	struct stat sStat;
	if ( stat(pszPathFile, &sStat) )
	{
		LogError( CRIO_ERROR_STAT, "stat() failed for '%s'", pszPathFile );
		fclose( fpFile );
		return FALSE;
	}

	// determine if enough room to store file
	USHORT usCount32KBlock = (sStat.st_size/CRIO_SIZE_32KBLOCK) +
		(sStat.st_size % CRIO_SIZE_32KBLOCK ? 1 : 0);
	if ( usCount32KBlock > cDirHeader.m_usCount32KBlockRemaining )
	{
		LogError( CRIO_ERROR_MEMORY, "not enough memory on device to upload '%s'", pszPathFile );
		fclose( fpFile );
		return FALSE;
	}

	// get first four bytes of file which determine mp3 properties
	UCHAR aucProperty[ 4 ];
	if ( fread(aucProperty, sizeof(aucProperty), 1, fpFile) < 1 )
	{
		LogError( CRIO_ERROR_READ, "error reading from file '%s'", pszPathFile );
		fclose( fpFile );
		return FALSE;
	}
	rewind( fpFile );

	// point to directory entry that will be used
	CDirEntry& cDirEntry = m_cDirBlock.m_acDirEntry[ cDirHeader.m_usCountEntry ];

	// update directory header
	if ( !cDirHeader.m_usCountEntry )
	{
		// adjust for dir block
		++cDirHeader.m_usCount32KBlockUsed;
		--cDirHeader.m_usCount32KBlockRemaining;

		// mark first block as used by directory
		m_cDirBlock.m_auc32KBlockUsed[ 0 ] = CRIO_ID_32KBLOCK_USED;

		// first entry in FAT used by directory
		m_cDirBlock.m_ausFAT[ 0 ] = 0;
	}
	++cDirHeader.m_usCountEntry;
	cDirHeader.m_usCount32KBlockUsed += usCount32KBlock;
	cDirHeader.m_usCount32KBlockRemaining -= usCount32KBlock;

	// find first free 32K block
	USHORT usPos32KBlockFree = FindFirstFree32KBlock();
	if ( usPos32KBlockFree == 0xffff )
	{
		LogError( CRIO_ERROR_CORRUPT, "no free 32K blocks, initialization recommended" );
		fclose( fpFile );
		return FALSE;
	}

	// update directory entry
	memset( &cDirEntry, 0, sizeof(CDirEntry) );
	cDirEntry.m_usPos32KBlock = usPos32KBlockFree;
	cDirEntry.m_usCount32KBlock = usCount32KBlock;
	cDirEntry.m_usSize32KMod = sStat.st_size % CRIO_SIZE_32KBLOCK;
	cDirEntry.m_lSize = sStat.st_size;
	cDirEntry.m_lTimeUpload = time( NULL );
	cDirEntry.m_aucProperty[ 0 ] = aucProperty[ 3 ];
	cDirEntry.m_aucProperty[ 1 ] = aucProperty[ 2 ];
	cDirEntry.m_aucProperty[ 2 ] = aucProperty[ 1 ];
	cDirEntry.m_aucProperty[ 3 ] = aucProperty[ 0 ];
	strncpy( cDirEntry.m_szName, GetFile(pszPathFile), sizeof(cDirEntry.m_szName) );

	// create zero initialized temp block
	UCHAR* paucBlock;
	ZERONEWBLOCK( paucBlock );

	// default return
	BOOL bResult = FALSE;

	// process all 32K blocks of file
	USHORT usPos32KBlockCurrent = cDirEntry.m_usPos32KBlock;
	USHORT usPos32KBlockPrev = 0xffff;
	USHORT usPos32KBlockEnd = cDirEntry.m_usCount32KBlock;
	USHORT usPos32KBlockNext;
	USHORT usPos32KBlock;
	for( usPos32KBlock=0; usPos32KBlock<usPos32KBlockEnd; ++usPos32KBlock )
	{
		// progress callback
		if ( pfProgress )
		{
			if ( !pfProgress(usPos32KBlock, usPos32KBlockEnd, cookie) )
			{
				LogError( CRIO_ERROR_INTERRUPTED, "operation interrupted" );
				break;
			}
		}

		// mark as block used
		m_cDirBlock.m_auc32KBlockUsed[ usPos32KBlockCurrent ] = CRIO_ID_32KBLOCK_USED;

		// get next block and update FAT
		if ( usPos32KBlock == (usPos32KBlockEnd-1) )
		{
			usPos32KBlockNext = 0xffff;
			m_cDirBlock.m_ausFAT[ usPos32KBlockCurrent ] = 0;
		}
		else
		{
			usPos32KBlockNext = FindFirstFree32KBlock();
			if ( usPos32KBlockNext == 0xffff )
			{
				LogError( CRIO_ERROR_CORRUPT, "no free 32K blocks, initialization recommended" );
				break;
			}
			m_cDirBlock.m_ausFAT[ usPos32KBlockCurrent ] = usPos32KBlockNext;
		}

		// determine read size
		UINT uiSize;
		if ( usPos32KBlock == (usPos32KBlockEnd-1) && cDirEntry.m_usSize32KMod )
		{
			uiSize = cDirEntry.m_usSize32KMod;
			memset( paucBlock+uiSize, 0, CRIO_SIZE_32KBLOCK-uiSize );
		}
		else
			uiSize = CRIO_SIZE_32KBLOCK;

		// read block
		if ( fread(paucBlock, uiSize, 1, fpFile) < 1 )
		{
			LogError( CRIO_ERROR_READ, "error reading from file '%s'", pszPathFile );
			break;
		}

		// tx block
		if ( !Tx32KBlock(paucBlock, usPos32KBlockCurrent, usPos32KBlockPrev,
			usPos32KBlockNext) )
			break;

		// update current and prev block markers
		usPos32KBlockPrev = usPos32KBlockCurrent;
		usPos32KBlockCurrent = usPos32KBlockNext;
	}

	// if transfer ok
	if ( usPos32KBlock == usPos32KBlockEnd )
	{
		// flag as ok
		bResult = TRUE;
		// IO outro
		IOOutro();
	}

	// release temp block
	DELETEBLOCK( paucBlock );

	// close file
	fclose( fpFile );

	return bResult;
}

BOOL CRio::RxFile( const char* pszPathFile, BOOL (*pfProgress)(int iPos, int iCount, void* cookie), void* cookie)
{
	// get directory entry for file
	const char* pszFile = GetFile( pszPathFile );
	CDirEntry* pDirEntry = FindFile( pszFile );
	if ( !pDirEntry )
	{
		LogError( CRIO_ERROR_FILENOTFOUND, "file '%s' not present on device", pszFile );
		return FALSE;
	}

	// open file for write
	FILE* fpFile = fopen( pszPathFile, "wb" );
	if ( !fpFile )
	{
		LogError( CRIO_ERROR_OPEN, "unable to open '%s' for write", pszPathFile );
		return FALSE;
	}

	// create temp block
	UCHAR* paucBlock;
	NEWBLOCK( paucBlock );

	// default return
	BOOL bResult = FALSE;

	// get all blocks
	USHORT usPos32KBlockCurrent = pDirEntry->m_usPos32KBlock;
	USHORT usPos32KBlockEnd = pDirEntry->m_usCount32KBlock;
	USHORT usPos32KBlock;
	for( usPos32KBlock=0; usPos32KBlock<usPos32KBlockEnd; ++usPos32KBlock )
	{
		// progress callback
		if ( pfProgress )
		{
			if ( !pfProgress(usPos32KBlock, usPos32KBlockEnd, cookie) )
			{
				LogError( CRIO_ERROR_INTERRUPTED, "operation interrupted" );
				break;
			}
		}

		// rx block
		if ( !Rx32KBlock(paucBlock, usPos32KBlockCurrent) )
			break;

		// determine write size
		int iSizeWrite;
		if ( usPos32KBlock == (usPos32KBlockEnd-1) && pDirEntry->m_usSize32KMod )
			iSizeWrite = pDirEntry->m_usSize32KMod;
		else
			iSizeWrite = CRIO_SIZE_32KBLOCK;

		// save block
		if ( fwrite(paucBlock, iSizeWrite, 1, fpFile) < 1 )
		{
			LogError( CRIO_ERROR_WRITE, "error writing to file '%s'", pszPathFile );
			break;
		}

		// next block
		usPos32KBlockCurrent = m_cDirBlock.m_ausFAT[ usPos32KBlockCurrent ];
	}

	// if transfer ok
	if ( usPos32KBlock == usPos32KBlockEnd )
	{
		// flag as ok
		bResult = TRUE;
		// IO outro
		IOOutro();
	}

	// release temp block
	DELETEBLOCK( paucBlock );

	// close file
	fclose( fpFile );

	return bResult;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -