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 #include <memory.h>
00035 #include <zlib.h>
00036
00037 #include "tag.h"
00038 #include "utils.h"
00039 #include "frame_impl.h"
00040 #include "io_decorators.h"
00041 #include "io_strings.h"
00042 #include "io_helpers.h"
00043
00044 using namespace dami;
00045
00046 namespace
00047 {
00048 void renderFields(ID3_Writer& writer, const ID3_FrameImpl& frame)
00049 {
00050 ID3_TextEnc enc = ID3TE_ASCII;
00051 for (ID3_FrameImpl::const_iterator fi = frame.begin(); fi != frame.end(); ++fi)
00052 {
00053 ID3_Field* fld = *fi;
00054 if (fld != NULL && fld->InScope(frame.GetSpec()))
00055 {
00056 if (fld->GetID() == ID3FN_TEXTENC)
00057 {
00058 enc = static_cast<ID3_TextEnc>(fld->Get());
00059 ID3D_NOTICE( "id3::v2::renderFields(): found encoding = " << enc );
00060 }
00061 else
00062 {
00063 fld->SetEncoding(enc);
00064 }
00065 fld->Render(writer);
00066 }
00067 }
00068 }
00069 }
00070
00071 void ID3_FrameImpl::Render(ID3_Writer& writer) const
00072 {
00073
00074
00075 if (!this->NumFields())
00076 {
00077 return;
00078 }
00079
00080 ID3_FrameHeader hdr;
00081
00082 const size_t hdr_size = hdr.Size();
00083
00084
00085
00086 String flds;
00087 io::StringWriter fldWriter(flds);
00088 size_t origSize = 0;
00089 if (!this->GetCompression())
00090 {
00091 renderFields(fldWriter, *this);
00092 origSize = flds.size();
00093 ID3D_NOTICE ( "ID3_FrameImpl::Render(): uncompressed fields" );
00094 }
00095 else
00096 {
00097 io::CompressedWriter cr(fldWriter);
00098 renderFields(cr, *this);
00099 cr.flush();
00100 origSize = cr.getOrigSize();
00101 ID3D_NOTICE ( "ID3_FrameImpl::Render(): compressed fields, orig size = " <<
00102 origSize );
00103 }
00104
00105 size_t fldSize = flds.size();
00106 ID3D_NOTICE ( "ID3_FrameImpl::Render(): field size = " << fldSize );
00107 if (fldSize == 0)
00108 {
00109 ID3D_WARNING ( "ID3_FrameImpl::Render(): no field data" );
00110 return;
00111 }
00112
00113
00114 uchar eID = this->GetEncryptionID(), gID = this->GetGroupingID();
00115 hdr.SetFrameID(this->GetID());
00116 hdr.SetEncryption(eID > 0);
00117 hdr.SetGrouping(gID > 0);
00118 hdr.SetCompression(origSize > fldSize);
00119 hdr.SetDataSize(fldSize + ((hdr.GetCompression() ? 4 : 0) +
00120 (hdr.GetEncryption() ? 1 : 0) +
00121 (hdr.GetGrouping() ? 1 : 0)));
00122
00123
00124 hdr.Render(writer);
00125
00126
00127 if (hdr.GetCompression())
00128 {
00129 io::writeBENumber(writer, origSize, sizeof(uint32));
00130 ID3D_NOTICE( "ID3_FrameImpl::Render(): frame is compressed, wrote origSize = " << origSize );
00131 }
00132 if (hdr.GetEncryption())
00133 {
00134 writer.writeChar(eID);
00135 ID3D_NOTICE( "ID3_FrameImpl::Render(): frame is compressed, encryption id = " << eID );
00136 }
00137 if (hdr.GetGrouping())
00138 {
00139 writer.writeChar(gID);
00140 ID3D_NOTICE( "ID3_FrameImpl::Render(): frame is compressed, grouping id = " << gID );
00141 }
00142
00143
00144 writer.writeChars(flds.data(), fldSize);
00145 _changed = false;
00146 }