void ID3v2_PopularimeterFrame::parseFields(const SjByteVector& data)
{
	m_email.Empty();
	m_rating255 = 0;
	m_counter = 0;

	int offset, pos = 0, size = (int)data.size();
	offset = data.find(textDelimiter(SJ_LATIN1), pos);
	if( offset < pos ) {
		return;
	}

	m_email = data.mid(pos, offset - pos).toString(SJ_LATIN1);
	pos = offset + 1;

	if(pos < size)
	{
		m_rating255 = (int)(data[pos]);
		pos++;

		if(pos < size)
		{
			m_counter = data.mid(pos, 4).toUInt();
		}
	}
}
void ID3v2_AttachedPictureFrame::parseFields(const SjByteVector &data)
{
	if(data.size() < 5) {
		wxLogDebug(wxT("A picture frame must contain at least 5 bytes."));
		return;
	}

	int pos = 0, offset;

	// read text encoding
	m_textEncoding = (SjStringType)(data[pos]);
	pos += 1;

	if( header()->version() <= 2 )
	{
		// read image format (3 characters), valid for ID3V2_2_1 or older
		m_mimeType = data.mid(pos, 3).toString(SJ_LATIN1);
		pos += 3;
	}
	else
	{
		// read mime type (null-terminated), valid for newer specs
		offset = data.find(textDelimiter(SJ_LATIN1), pos);

		if(offset < pos)
			return;

		m_mimeType = data.mid(pos, offset - pos).toString(SJ_LATIN1);
		pos = offset + 1;
	}

	// read type
	m_type = (ID3v2_AttachedPictureType)(data[pos]);
	pos += 1;

	// read description
	offset = data.find(textDelimiter(m_textEncoding), pos);

	if(offset < pos)
		return;

	m_description = data.mid(pos, offset - pos).toString(m_textEncoding);
	pos = offset + 1;

	// read image data
	m_data = data.mid(pos);
}
Example #3
0
long MPEG_File::findID3v2()
{
	// This method is based on the contents of Tagger_File::find(), but because
	// of some subtlteies -- specifically the need to look for the bit pattern of
	// an MPEG sync, it has been modified for use here.

	if( IsValid()
	        && ID3v2_Header::fileIdentifier().size() <= BufferSize() )
	{
		// The position in the file that the current buffer starts at.

		long bufferOffset = 0;
		SjByteVector buffer;

		// These variables are used to keep track of a partial match that happens at
		// the end of a buffer.

		int previousPartialMatch = -1;
		bool previousPartialSynchMatch = false;

		// Save the location of the current read pointer.  We will restore the
		// position using seek() before all returns.

		long originalPosition = Tell();

		// Start the search at the beginning of the file.

		Seek(0);

		// This loop is the crux of the find method.  There are three cases that we
		// want to account for:
		// (1) The previously searched buffer contained a partial match of the search
		// pattern and we want to see if the next one starts with the remainder of
		// that pattern.
		//
		// (2) The search pattern is wholly contained within the current buffer.
		//
		// (3) The current buffer ends with a partial match of the pattern.  We will
		// note this for use in the next itteration, where we will check for the rest
		// of the pattern.

		for(buffer = ReadBlock(BufferSize()); buffer.size() > 0; buffer = ReadBlock(BufferSize()))
		{

			// (1) previous partial match

			if(previousPartialSynchMatch && secondSynchByte(buffer[0]))
			{
				return -1;
			}

			if(previousPartialMatch >= 0 && int(BufferSize()) > previousPartialMatch)
			{
				const int patternOffset = (BufferSize() - previousPartialMatch);
				if(buffer.containsAt(ID3v2_Header::fileIdentifier(), 0, patternOffset))
				{
					Seek(originalPosition);
					return bufferOffset - BufferSize() + previousPartialMatch;
				}
			}

			// (2) pattern contained in current buffer

			long location = buffer.find(ID3v2_Header::fileIdentifier());
			if(location >= 0)
			{
				Seek(originalPosition);
				return bufferOffset + location;
			}

			int firstSynchByte = buffer.find(/*(char)*/((unsigned char)(255)));

			// Here we have to loop because there could be several of the first
			// (11111111) byte, and we want to check all such instances until we find
			// a full match (11111111 111) or hit the end of the buffer.

			while(firstSynchByte >= 0)
			{

				// if this *is not* at the end of the buffer

				if(firstSynchByte < int(buffer.size()) - 1)
				{
					if(secondSynchByte(buffer[firstSynchByte + 1]))
					{
						// We've found the frame synch pattern.
						Seek(originalPosition);
						return -1;
					}
					else
					{

						// We found 11111111 at the end of the current buffer indicating a
						// partial match of the synch pattern.  The find() below should
						// return -1 and break out of the loop.

						previousPartialSynchMatch = true;
					}
				}

				// Check in the rest of the buffer.

				firstSynchByte = buffer.find(/*char*/((unsigned char)(255)), firstSynchByte + 1);
			}

			// (3) partial match

			previousPartialMatch = buffer.endsWithPartialMatch(ID3v2_Header::fileIdentifier());

			bufferOffset += BufferSize();

		} // for()

		// Since we hit the end of the file, reset the status before continuing.

		Clear();

		Seek(originalPosition);
	}

	return -1;
}