00001 // $Id: header_tag.cpp,v 1.21 2000/10/29 01:37:29 eldamitri Exp $ 00002 00003 // id3lib: a C++ library for creating and manipulating id3v1/v2 tags 00004 // Copyright 1999, 2000 Scott Thomas Haug 00005 00006 // This library is free software; you can redistribute it and/or modify it 00007 // under the terms of the GNU Library General Public License as published by 00008 // the Free Software Foundation; either version 2 of the License, or (at your 00009 // option) any later version. 00010 // 00011 // This library is distributed in the hope that it will be useful, but WITHOUT 00012 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00014 // License for more details. 00015 // 00016 // You should have received a copy of the GNU Library General Public License 00017 // along with this library; if not, write to the Free Software Foundation, 00018 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00019 00020 // The id3lib authors encourage improvements and optimisations to be sent to 00021 // the id3lib coordinator. Please see the README file for details on where to 00022 // send such submissions. See the AUTHORS file for a list of people who have 00023 // contributed to id3lib. See the ChangeLog file for a list of changes to 00024 // id3lib. These files are distributed with id3lib at 00025 // http://download.sourceforge.net/id3lib/ 00026 00027 #if defined HAVE_CONFIG_H 00028 #include <config.h> 00029 #endif 00030 00031 00032 00033 #include <string.h> 00034 00035 #include "header_tag.h" 00036 #include "utils.h" 00037 #include "tag.h" 00038 #include "io_helpers.h" 00039 #include "spec.h" 00040 00041 using namespace dami; 00042 00043 const char* const ID3_TagHeader::ID = "ID3"; 00044 00045 bool ID3_TagHeader::SetSpec(ID3_V2Spec spec) 00046 { 00047 bool changed = this->ID3_Header::SetSpec(spec); 00048 if (changed) 00049 { 00050 if (_info) 00051 { 00052 _flags.set(EXPERIMENTAL, _info->is_experimental); 00053 _flags.set(EXTENDED, _info->is_extended); 00054 } 00055 } 00056 return changed; 00057 } 00058 00059 size_t ID3_TagHeader::Size() const 00060 { 00061 size_t bytesUsed = ID3_TagHeader::SIZE; 00062 00063 if (_info->is_extended) 00064 { 00065 bytesUsed += _info->extended_bytes + sizeof(uint32); 00066 } 00067 00068 return bytesUsed; 00069 } 00070 00071 00072 void ID3_TagHeader::Render(ID3_Writer& writer) const 00073 { 00074 writer.writeChars((uchar *) ID, strlen(ID)); 00075 00076 writer.writeChar(ID3_V2SpecToVer(ID3V2_LATEST)); 00077 writer.writeChar(ID3_V2SpecToRev(ID3V2_LATEST)); 00078 00079 // set the flags byte in the header 00080 writer.writeChar(static_cast<uchar>(_flags.get() & MASK8)); 00081 io::writeUInt28(writer, this->GetDataSize()); 00082 00083 // now we render the extended header 00084 if (_flags.test(EXTENDED)) 00085 { 00086 io::writeBENumber(writer, _info->extended_bytes, sizeof(uint32)); 00087 } 00088 } 00089 00090 bool ID3_TagHeader::Parse(ID3_Reader& reader) 00091 { 00092 io::ExitTrigger et(reader); 00093 if (!ID3_Tag::IsV2Tag(reader)) 00094 { 00095 ID3D_NOTICE( "ID3_TagHeader::Parse(): not an id3v2 header" ); 00096 return false; 00097 } 00098 00099 uchar id[3]; 00100 reader.readChars(id, 3); 00101 // The spec version is determined with the MAJOR and MINOR OFFSETs 00102 uchar major = reader.readChar(); 00103 uchar minor = reader.readChar(); 00104 this->SetSpec(ID3_VerRevToV2Spec(major, minor)); 00105 00106 // Get the flags at the appropriate offset 00107 _flags.set(static_cast<ID3_Flags::TYPE>(reader.readChar())); 00108 00109 // set the data size 00110 this->SetDataSize(io::readUInt28(reader)); 00111 00112 if (_flags.test(EXTENDED)) 00113 { 00114 if (this->GetSpec() == ID3V2_2_1) 00115 { 00116 // okay, if we are ID3v2.2.1, then let's skip over the extended header 00117 // for now because I am lazy 00118 } 00119 00120 if (this->GetSpec() == ID3V2_3_0) 00121 { 00122 // okay, if we are ID3v2.3.0, then let's actually parse the extended 00123 // header (for now, we skip it because we are lazy) 00124 } 00125 } 00126 et.setExitPos(reader.getCur()); 00127 return true; 00128 }