Exemple #1
0
bool ReadString(char *str, int size)
{
	char ch;
	if (bufpoint >= bufsize)
	{
		FillBuf();
	}
	do // remove non symbolic data
	{
		if (PopFromBuf(&ch) == false)
		{
			return false;
		}
	} while (!IsLiteral(ch));
	do
	{
		if (IsLiteral(ch))
		{
			*str = ch;
			str++;
		}
		else // packet end
		{
			*str = 0; //  add end of string
			return true;
		}
	} while (PopFromBuf(&ch) == true);
	return false;
}
int RageFileObj::Read( void *pBuffer, size_t iBytes )
{
        int ret = 0;

	while( !m_bEOF && iBytes > 0 )
	{
		if( m_pBuffer != NULL && m_iBufAvail )
		{
			/* Copy data out of the buffer first. */
			int iFromBuffer = min( (int) iBytes, m_iBufAvail );
			memcpy( pBuffer, m_pBuf, iFromBuffer );
			if( m_bCRC32Enabled )
				CRC32( m_iCRC32, pBuffer, iFromBuffer );

			ret += iFromBuffer;
			m_iFilePos += iFromBuffer;
			iBytes -= iFromBuffer;
			m_iBufAvail -= iFromBuffer;
			m_pBuf += iFromBuffer;

			pBuffer = (char *) pBuffer + iFromBuffer;
		}

		if( !iBytes )
			break;

		ASSERT( m_iBufAvail == 0 );

		/* If buffering is disabled, or the block is bigger than the buffer,
		 * read the remainder of the data directly into the desteination buffer. */
		if( m_pBuffer == NULL || iBytes >= BSIZE )
		{
			/* We have a lot more to read, so don't waste time copying it into the
			 * buffer. */
			int iFromFile = this->ReadInternal( pBuffer, iBytes );
			if( iFromFile == -1 )
				return -1;

			if( iFromFile == 0 )
				m_bEOF = true;

			if( m_bCRC32Enabled )
				CRC32( m_iCRC32, pBuffer, iFromFile );
			ret += iFromFile;
			m_iFilePos += iFromFile;
			return ret;
		}

		/* If buffering is enabled, and we need more data, fill the buffer. */
		m_pBuf = m_pBuffer;
		int got = FillBuf();
		if( got == -1 )
			return got;
		if( got == 0 )
			m_bEOF = true;
	}

	return ret;
}
Exemple #3
0
int RageFile::Read( void *buffer, size_t bytes )
{
	if( !IsOpen() )
		RageException::Throw("\"%s\" is not open.", GetPath().c_str());

	if( !(m_Mode&READ) )
		RageException::Throw("\"%s\" is not open for reading", GetPath().c_str());

	int ret = 0;

	while( !m_EOF && bytes > 0 )
	{
		/* Copy data out of the buffer first. */
		int FromBuffer = min( (int) bytes, m_BufAvail );
		memcpy( buffer, m_pBuf, FromBuffer );

		ret += FromBuffer;
		m_FilePos += FromBuffer;
		bytes -= FromBuffer;
		m_BufAvail -= FromBuffer;
		m_pBuf += FromBuffer;
		
		buffer = (char *) buffer + FromBuffer;
	
		if( !bytes )
			break;

		ASSERT( !m_BufAvail );

		/* We need more; either fill the buffer and keep going, or just read directly
		 * into the destination buffer. */
		if( bytes >= sizeof(m_Buffer) )
		{
			/* We have a lot more to read, so don't waste time copying it into the
			 * buffer. */
			int FromFile = m_File->Read( buffer, bytes );
			if( FromFile < 0 )
				return FromFile;
			if( FromFile == 0 )
				m_EOF = true;
			ret += FromFile;
			m_FilePos += FromFile;
			return ret;
		}

		m_pBuf = m_Buffer;
		int got = FillBuf();
		if( got < 0 )
			return got;
		if( got == 0 )
			m_EOF = true;
	}

	return ret;
}
Exemple #4
0
/******************************************************************************
 * \name _tasctime
 * \brief Converts a UTC time into a string and returns a pointer to it.
 * \param ptm Pointer to the UTC time.
 * \remarks The string is stored in thread local buffer, shared between
 *          ctime, gmtime and localtime (32 and 64 bit versions).
 */
_TCHAR *
_tasctime(const struct tm *ptm)
{
    PTHREADDATA pThreadData;
    _TCHAR *pstr;

    /* Get pointer to TLS buffer */
    pThreadData = GetThreadData();
#ifndef _UNICODE
    pstr = pThreadData->asctimebuf;
#else
    pstr = pThreadData->wasctimebuf;
#endif

    /* Fill the buffer */
    FillBuf((timebuf_t*)pstr, ptm);

    return pstr;
}
Exemple #5
0
/******************************************************************************
 * \name _tasctime
 * \brief Converts a UTC time into a string and returns a pointer to it.
 * \param ptm Pointer to the UTC time.
 * \remarks The string is stored in thread local buffer, shared between
 *          ctime, gmtime and localtime (32 and 64 bit versions).
 */
_TCHAR *
_tasctime(const struct tm *ptm)
{
    thread_data_t *data = msvcrt_get_thread_data();
    _TCHAR *pstr;

#ifndef _UNICODE
    pstr = data->asctime_buffer;
#else
    pstr = data->wasctime_buffer;
#endif

    if(!pstr)
        pstr = malloc(sizeof(struct tm));

    /* Fill the buffer */
    FillBuf((timebuf_t*)pstr, ptm);

    return pstr;
}
Exemple #6
0
/******************************************************************************
 * \name _tasctime_s
 * \brief Converts a local time into a string and returns a pointer to it.
 * \param buffer Buffer that receives the string (26 characters).
 * \param numberOfElements Size of the buffer in characters.
 * \param time Pointer to the UTC time.
 */
errno_t 
_tasctime_s( 
    _TCHAR* buffer,
    size_t numberOfElements,
    const struct tm *ptm)
{
    /* Validate parameters */
    if (!buffer || numberOfElements < 26 || !ptm ||
        (unsigned int)ptm->tm_sec > 59 ||
        (unsigned int)ptm->tm_min > 59 ||
        (unsigned int)ptm->tm_hour > 23 ||
        (unsigned int)ptm->tm_mday > 31 ||
        (unsigned int)ptm->tm_mon > 11 ||
        (unsigned int)ptm->tm_year > 2038 ||
        (unsigned int)ptm->tm_wday > 6 ||
        (unsigned int)ptm->tm_yday > 365)
    {
#if 0
        _invalid_parameter(NULL,
#ifdef UNICODE
                            L"_wasctime",
#else
                            L"asctime",
#endif
                           _CRT_WIDE(__FILE__),
                           __LINE__,
                           0);
#endif
        return EINVAL;
    }

    /* Fill the buffer */
    FillBuf((timebuf_t*)buffer, ptm);

    return 0;
}
Exemple #7
0
/* Retrieve audio data, for mixing.  At the time of this call, the frameno at which the
 * sound will be played doesn't have to be known.  Once committed, and the frameno
 * is known, call CommitPCMData.  size is in bytes.
 *
 * If the data returned is at the end of the stream, return false.
 *
 * size is in frames
 * iSoundFrame is in frames (abstract)
 */
bool RageSound::GetDataToPlay( int16_t *pBuffer, int iSize, int &iSoundFrame, int &iFramesStored )
{
	int iNumRewindsThisCall = 0;

	/* We only update m_iDecodePosition; only take a shared lock, so we don't block the main thread. */
//	LockMut(m_Mutex);

	ASSERT_M( m_bPlaying, ssprintf("%p", this) );

	iFramesStored = 0;
	iSoundFrame = m_iDecodePosition;

	while( 1 )
	{
		/* If we don't have any data left buffered, fill the buffer by
		 * up to as much as we need. */
		if( !Bytes_Available() )
			FillBuf( iSize );

		/* Get a block of data. */
		int iGotFrames = GetData( (char *) pBuffer, iSize );

		/* If we didn't get any data, see if we need to pad the end of the file with
		 * silence for m_LengthSeconds. */
		if( !iGotFrames && m_Param.m_LengthSeconds != -1 )
		{
			const float LastSecond = m_Param.m_StartSecond + m_Param.m_LengthSeconds;
			int LastFrame = int(LastSecond*samplerate());
			int FramesOfSilence = LastFrame - m_iDecodePosition;
			FramesOfSilence = clamp( FramesOfSilence, 0, iSize );
			if( FramesOfSilence > 0 )
			{
				memset( pBuffer, 0, FramesOfSilence * framesize );
				iGotFrames = FramesOfSilence;
			}
		}

		if( !iGotFrames )
		{
			/* EOF. */
			switch( GetStopMode() )
			{
			case RageSoundParams::M_STOP:
				/* Not looping.  Normally, we'll just stop here. */
				return false;

			case RageSoundParams::M_LOOP:
				/* Rewind and restart. */
				iNumRewindsThisCall++;
				if( iNumRewindsThisCall > 3 )
				{
					/* We're rewinding a bunch of times in one call.  This probably means
					 * that the length is too short.  It might also mean that the start
					 * position is very close to the end of the file, so we're looping
					 * over the remainder.  If we keep doing this, we'll chew CPU rewinding,
					 * so stop. */
					LOG->Warn( "Sound %s is busy looping.  Sound stopped (start = %f, length = %f)",
						GetLoadedFilePath().c_str(), m_Param.m_StartSecond, m_Param.m_LengthSeconds );

					return false;
				}

				/* Rewind and start over.  XXX: this will take an exclusive lock */
				SetPositionSeconds( m_Param.m_StartSecond );

				/* Make sure we can get some data.  If we can't, then we'll have
				 * nothing to send and we'll just end up coming back here. */
				if( !Bytes_Available() )
					FillBuf( iSize );
				if( GetData(NULL, iSize) == 0 )
				{
					LOG->Warn( "Can't loop data in %s; no data available at start point %f",
						GetLoadedFilePath().c_str(), m_Param.m_StartSecond );

					/* Stop here. */
					return false;
				}
				continue;

			case RageSoundParams::M_CONTINUE:
				/* Keep playing silence. */
				memset( pBuffer, 0, iSize*framesize );
				iGotFrames = iSize;
				break;

			default:
				ASSERT(0);
			}
		}

		/* This block goes from m_iDecodePosition to m_iDecodePosition+iGotFrames. */

		/* We want to fade when there's m_FadeLength seconds left, but if
		 * m_LengthFrames is -1, we don't know the length we're playing.
		 * (m_LengthFrames is the length to play, not the length of the
		 * source.)  If we don't know the length, don't fade. */
		if( m_Param.m_FadeLength != 0 && m_Param.m_LengthSeconds != -1 )
		{
			const float fFinishFadingOutAt = m_Param.m_StartSecond + m_Param.m_LengthSeconds;
			const float fStartFadingOutAt = fFinishFadingOutAt - m_Param.m_FadeLength;
			const float fStartSecond = float(m_iDecodePosition) / samplerate();
			const float fEndSecond = float(m_iDecodePosition+iGotFrames) / samplerate();
			const float fStartVolume = SCALE( fStartSecond, fStartFadingOutAt, fFinishFadingOutAt, 1.0f, 0.0f );
			const float fEndVolume = SCALE( fEndSecond, fStartFadingOutAt, fFinishFadingOutAt, 1.0f, 0.0f );
			RageSoundUtil::Fade( pBuffer, iGotFrames, fStartVolume, fEndVolume );
		}

		RageSoundUtil::Pan( pBuffer, iGotFrames, m_Param.m_Balance );

		iSoundFrame = m_iDecodePosition;

		iFramesStored = iGotFrames;
		m_iDecodePosition += iGotFrames;
		return true;
	}
}
Exemple #8
0
/* Read up to the next \n, and return it in out.  Strip the \n.  If the \n is
 * preceded by a \r (DOS newline), strip that, too. */
int RageFile::GetLine( CString &out )
{
	out = "";

    if ( !IsOpen() )
        RageException::Throw("\"%s\" is not open.", m_Path.c_str());

	if( !(m_Mode&READ) )
		RageException::Throw("\"%s\" is not open for reading", GetPath().c_str());

	if( m_EOF )
		return 0;

	bool GotData = false;
	while( 1 )
	{
		bool done = false;

		/* Find the end of the block we'll move to out. */
		char *p = (char *) memchr( m_pBuf, '\n', m_BufAvail );
		bool ReAddCR = false;
		if( p == NULL )
		{
			/* Hack: If the last character of the buffer is \r, then it's likely that an
			 * \r\n has been split across buffers.  Move everything else, then move the
			 * \r to the beginning of the buffer and handle it the next time around the loop. */
			if( m_BufAvail && m_pBuf[m_BufAvail-1] == '\r' )
			{
				ReAddCR = true;
				--m_BufAvail;
			}

			p = m_pBuf+m_BufAvail; /* everything */
		}
		else
			done = true;

		if( p >= m_pBuf )
		{
			char *RealEnd = p;
			if( done && p > m_pBuf && p[-1] == '\r' )
				--RealEnd; /* not including \r */
			out.append( m_pBuf, RealEnd );

			if( done )
				++p; /* skip \n */

			const int used = p-m_pBuf;
			if( used )
			{
				m_BufAvail -= used;
				m_FilePos += used;
				GotData = true;
				m_pBuf = p;
			}
		}

		if( ReAddCR )
		{
			ASSERT( m_BufAvail == 0 );
			m_pBuf = m_Buffer;
			m_Buffer[m_BufAvail] = '\r';
			++m_BufAvail;
		}

		if( done )
			break;

		/* We need more data. */
		m_pBuf = m_Buffer;

		const int size = FillBuf();

		/* If we've read data already, then don't mark EOF yet.  Wait until the
		 * next time we're called. */
		if( size == 0 && !GotData )
		{
			m_EOF = true;
			return 0;
		}
		if( size == -1 )
			return -1; // error
		if( size == 0 )
			break; // EOF or error
	}
	return GotData? 1:0;
}