id3lib  3.8.3
frame_render.cpp
Go to the documentation of this file.
1 // $Id: frame_render.cpp,v 1.27 2002/07/31 13:45:18 t1mpy Exp $
2 
3 // id3lib: a C++ library for creating and manipulating id3v1/v2 tags
4 // Copyright 1999, 2000 Scott Thomas Haug
5 // Copyright 2002 Thijmen Klok (thijmen@id3lib.org)
6 
7 // This library is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU Library General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or (at your
10 // option) any later version.
11 //
12 // This library is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Library General Public License
18 // along with this library; if not, write to the Free Software Foundation,
19 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 
21 // The id3lib authors encourage improvements and optimisations to be sent to
22 // the id3lib coordinator. Please see the README file for details on where to
23 // send such submissions. See the AUTHORS file for a list of people who have
24 // contributed to id3lib. See the ChangeLog file for a list of changes to
25 // id3lib. These files are distributed with id3lib at
26 // http://download.sourceforge.net/id3lib/
27 
28 #if defined HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 
33 
34 //#include <string.h>
35 #include <memory.h>
36 #include <zlib.h>
37 
38 #include "tag.h"
39 #include "frame_impl.h"
40 #include "id3/io_decorators.h" //has "readers.h" "io_helpers.h" "utils.h"
41 #include "io_strings.h"
42 #include "io_helpers.h"
43 
44 using namespace dami;
45 
46 namespace
47 {
48  void renderFields(ID3_Writer& writer, const ID3_FrameImpl& frame)
49  {
51  for (ID3_FrameImpl::const_iterator fi = frame.begin(); fi != frame.end(); ++fi)
52  {
53  ID3_Field* fld = *fi;
54  if (fld != NULL && fld->InScope(frame.GetSpec()))
55  {
56  if (fld->GetID() == ID3FN_TEXTENC)
57  {
58  enc = static_cast<ID3_TextEnc>(fld->Get());
59  ID3D_NOTICE( "id3::v2::renderFields(): found encoding = " << enc );
60  }
61  else
62  {
63  fld->SetEncoding(enc);
64  }
65  fld->Render(writer);
66  }
67  }
68  }
69 }
70 
71 void ID3_FrameImpl::Render(ID3_Writer& writer) const
72 {
73  // Return immediately if we have no fields, which (usually) means we're
74  // trying to render a frame which has been Cleared or hasn't been initialized
75  if (!this->NumFields())
76  {
77  return;
78  }
79 
80  ID3_FrameHeader hdr;
81 
82  const size_t hdr_size = hdr.Size();
83 
84  // 1. Write out the field data to the buffer, with the assumption that
85  // we won't be decompressing, since this is the usual behavior
86  String flds;
87  io::StringWriter fldWriter(flds);
88  size_t origSize = 0;
89  if (!this->GetCompression())
90  {
91  renderFields(fldWriter, *this);
92  origSize = flds.size();
93  ID3D_NOTICE ( "ID3_FrameImpl::Render(): uncompressed fields" );
94  }
95  else
96  {
97  io::CompressedWriter cr(fldWriter);
98  renderFields(cr, *this);
99  cr.flush();
100  origSize = cr.getOrigSize();
101  ID3D_NOTICE ( "ID3_FrameImpl::Render(): compressed fields, orig size = " <<
102  origSize );
103  }
104 
105  size_t fldSize = flds.size();
106  ID3D_NOTICE ( "ID3_FrameImpl::Render(): field size = " << fldSize );
107 // No need to not write empty frames, why would we not? They can be used to fill up padding space
108 // which is even recommended in the id3 spec.
109 // if (fldSize == 0)
110 // {
111 // ID3D_WARNING ( "ID3_FrameImpl::Render(): no field data" );
112 // return;
113 // }
114 
115  // determine which flags need to be set
116  uchar eID = this->GetEncryptionID(), gID = this->GetGroupingID();
117  ID3_FrameID fid = this->GetID();
118  if (fid == ID3FID_NOFRAME)
119  {
120  const char *tid = this->GetTextID();
121  hdr.SetUnknownFrame(tid);
122  }
123  else
124  {
125  hdr.SetFrameID(fid);
126  }
127  hdr.SetEncryption(eID > 0);
128  hdr.SetGrouping(gID > 0);
129  hdr.SetCompression(origSize > fldSize);
130  hdr.SetDataSize(fldSize + ((hdr.GetCompression() ? 4 : 0) +
131  (hdr.GetEncryption() ? 1 : 0) +
132  (hdr.GetGrouping() ? 1 : 0)));
133 
134  // write out the header
135  hdr.Render(writer);
136 
137  if (fldSize != 0)
138  {
139  // No-man's land! Not part of the header, not part of the data
140  if (hdr.GetCompression())
141  {
142  io::writeBENumber(writer, origSize, sizeof(uint32));
143  ID3D_NOTICE( "ID3_FrameImpl::Render(): frame is compressed, wrote origSize = " << origSize );
144  }
145  if (hdr.GetEncryption())
146  {
147  writer.writeChar(eID);
148  ID3D_NOTICE( "ID3_FrameImpl::Render(): frame is compressed, encryption id = " << eID );
149  }
150  if (hdr.GetGrouping())
151  {
152  writer.writeChar(gID);
153  ID3D_NOTICE( "ID3_FrameImpl::Render(): frame is compressed, grouping id = " << gID );
154  }
155 
156  // Write the field data
157  writer.writeChars(flds.data(), fldSize);
158  }
159  _changed = false;
160 }
161 
The representative class of an ID3v2 field.
Definition: field.h:37
virtual uint32 Get() const =0
Returns the value of the integer field.
virtual ID3_FieldID GetID() const =0
virtual bool SetEncoding(ID3_TextEnc enc)=0
virtual bool InScope(ID3_V2Spec spec) const =0
virtual void Render(ID3_Writer &) const =0
void Render(ID3_Writer &) const
bool GetGrouping() const
Definition: header_frame.h:69
void SetUnknownFrame(const char *)
bool GetEncryption() const
Definition: header_frame.h:68
size_t Size() const
bool SetEncryption(bool b)
Definition: header_frame.h:64
bool SetFrameID(ID3_FrameID id)
bool SetCompression(bool b)
Definition: header_frame.h:63
bool GetCompression() const
Definition: header_frame.h:67
bool SetGrouping(bool b)
Definition: header_frame.h:65
iterator end()
Definition: frame_impl.h:117
ID3_V2Spec GetSpec() const
Definition: frame_impl.cpp:145
void Render(ID3_Writer &) const
Fields::const_iterator const_iterator
Definition: frame_impl.h:47
iterator begin()
Definition: frame_impl.h:116
bool SetDataSize(size_t size)
Definition: header.h:64
virtual size_type writeChars(const char_type buf[], size_type len)=0
Write up to len characters into buf and advance the internal position accordingly.
virtual int_type writeChar(char_type ch)
Write a single character and advance the internal position.
Definition: writer.h:71
#define NULL
Definition: globals.h:743
@ ID3FN_TEXTENC
Text encoding (unicode or ASCII)
Definition: globals.h:200
ID3_TextEnc
Enumeration of the types of text encodings: ascii or unicode.
Definition: globals.h:138
@ ID3TE_ASCII
Definition: globals.h:145
unsigned char uchar
Definition: globals.h:114
ID3_FrameID
Enumeration of the different types of frames recognized by id3lib.
Definition: globals.h:230
@ ID3FID_NOFRAME
No known frame.
Definition: globals.h:231
Definition: tag_impl.h:42