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); }
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; }