00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00080 writer.writeChar(static_cast<uchar>(_flags.get() & MASK8));
00081 io::writeUInt28(writer, this->GetDataSize());
00082
00083
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
00102 uchar major = reader.readChar();
00103 uchar minor = reader.readChar();
00104 this->SetSpec(ID3_VerRevToV2Spec(major, minor));
00105
00106
00107 _flags.set(static_cast<ID3_Flags::TYPE>(reader.readChar()));
00108
00109
00110 this->SetDataSize(io::readUInt28(reader));
00111
00112 if (_flags.test(EXTENDED))
00113 {
00114 if (this->GetSpec() == ID3V2_2_1)
00115 {
00116
00117
00118 }
00119
00120 if (this->GetSpec() == ID3V2_3_0)
00121 {
00122
00123
00124 }
00125 }
00126 et.setExitPos(reader.getCur());
00127 return true;
00128 }