id3lib 3.8.3
field_string_ascii.cpp
Go to the documentation of this file.
1// $Id: field_string_ascii.cpp,v 1.29 2003/03/02 14:23:58 t1mpy Exp $
2
3// id3lib: a C++ library for creating and manipulating id3v1/v2 tags
4// Copyright 1999, 2000 Scott Thomas Haug
5
6// This library is free software; you can redistribute it and/or modify it
7// under the terms of the GNU Library General Public License as published by
8// the Free Software Foundation; either version 2 of the License, or (at your
9// option) any later version.
10//
11// This library is distributed in the hope that it will be useful, but WITHOUT
12// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14// License for more details.
15//
16// You should have received a copy of the GNU Library General Public License
17// along with this library; if not, write to the Free Software Foundation,
18// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20// The id3lib authors encourage improvements and optimisations to be sent to
21// the id3lib coordinator. Please see the README file for details on where to
22// send such submissions. See the AUTHORS file for a list of people who have
23// contributed to id3lib. See the ChangeLog file for a list of changes to
24// id3lib. These files are distributed with id3lib at
25// http://download.sourceforge.net/id3lib/
26
27#include "field_impl.h"
28#include "id3/utils.h" // has <config.h> "id3/id3lib_streams.h" "id3/globals.h" "id3/id3lib_strings.h"
29#include "io_helpers.h"
30
31using namespace dami;
32
38
45size_t ID3_FieldImpl::Set(const char* data)
46{
47 size_t len = 0;
48 if ((this->GetType() == ID3FTY_TEXTSTRING) && data)
49 {
50 String str(data);
51 len = this->SetText_i(str);
52 }
53 return len;
54}
55
56// the ::Get() function for ASCII
57
87size_t ID3_FieldImpl::Get(char* buffer, size_t maxLength) const
88{
89 size_t size = 0;
90 if (this->GetType() == ID3FTY_TEXTSTRING &&
91 this->GetEncoding() == ID3TE_ASCII &&
92 buffer != NULL && maxLength > 0)
93 {
94 String data = this->GetText();
95 size = dami::min(maxLength, data.size());
96 ::memcpy(buffer, data.data(), size);
97 if (size < maxLength)
98 {
99 buffer[size] = '\0';
100 }
101 }
102
103 return size;
104}
105
106size_t ID3_FieldImpl::Get(char* buf, size_t maxLen, size_t index) const
107{
108 size_t size = 0;
109 if (this->GetType() == ID3FTY_TEXTSTRING &&
110 this->GetEncoding() == ID3TE_ASCII &&
111 buf != NULL && maxLen > 0)
112 {
113 String data = this->GetTextItem(index);
114 size = dami::min(maxLen, data.size());
115 ::memcpy(buf, data.data(), size);
116 if (size < maxLen)
117 {
118 buf[size] = '\0';
119 }
120 }
121 return size;
122}
123
125{
126 String data;
127 if (this->GetType() == ID3FTY_TEXTSTRING)
128 {
129 data = _text;
130 }
131 return data;
132}
133
134String ID3_FieldImpl::GetTextItem(size_t index) const
135{
136 String data;
137 if (this->GetType() == ID3FTY_TEXTSTRING &&
138 this->GetEncoding() == ID3TE_ASCII)
139 {
140 const char* raw = this->GetRawTextItem(index);
141 if (raw != NULL)
142 {
143 data = raw;
144 }
145 }
146 return data;
147}
148
149namespace
150{
151 String getFixed(String data, size_t size)
152 {
153 String text(data, 0, size);
154 if (text.size() < size)
155 {
156 text.append(size - text.size(), '\0');
157 }
158 return text;
159 }
160}
161
162
163size_t ID3_FieldImpl::SetText_i(String data)
164{
165 this->Clear();
166 if (_fixed_size > 0)
167 {
168 _text = getFixed(data, _fixed_size);
169 }
170 else
171 {
172 _text = data;
173 }
174 ID3D_NOTICE( "SetText_i: text = \"" << _text << "\"" );
175 _changed = true;
176
177 if (_text.size() == 0)
178 {
179 _num_items = 0;
180 }
181 else
182 {
183 _num_items = 1;
184 }
185
186 return _text.size();
187}
188
189size_t ID3_FieldImpl::SetText(String data)
190{
191 size_t len = 0;
192 if (this->GetType() == ID3FTY_TEXTSTRING)
193 {
194 len = this->SetText_i(data);
195 }
196 return len;
197}
198
199
213size_t ID3_FieldImpl::AddText_i(String data)
214{
215 size_t len = 0; // how much of str we copied into this field (max is strLen)
216 ID3D_NOTICE ("ID3_FieldImpl::AddText_i: Adding \"" << data << "\"" );
217 if (this->GetNumTextItems() == 0)
218 {
219 // there aren't any text items in the field so just assign the string to
220 // the field
221 len = this->SetText_i(data);
222 }
223 else
224 {
225
226 // ASSERT(_fixed_size == 0)
227 _text += '\0';
228 if (this->GetEncoding() == ID3TE_UNICODE)
229 {
230 _text += '\0';
231 }
232 _text.append(data);
233 len = data.size();
234 _num_items++;
235 }
236
237 return len;
238}
239
240size_t ID3_FieldImpl::AddText(String data)
241{
242 size_t len = 0;
243 if (this->GetType() == ID3FTY_TEXTSTRING)
244 {
245 len = this->AddText_i(data);
246 }
247 return len;
248}
249
250size_t ID3_FieldImpl::Add(const char* data)
251{
252 size_t len = 0;
253 if (this->GetType() == ID3FTY_TEXTSTRING)
254 {
255 String str(data);
256 len = this->AddText_i(str);
257 }
258 return len;
259}
260
261const char* ID3_FieldImpl::GetRawText() const
262{
263 const char* text = NULL;
264 if (this->GetType() == ID3FTY_TEXTSTRING &&
265 this->GetEncoding() == ID3TE_ASCII)
266 {
267 text = _text.c_str();
268 }
269 return text;
270}
271
272const char* ID3_FieldImpl::GetRawTextItem(size_t index) const
273{
274 const char* text = NULL;
275 if (this->GetType() == ID3FTY_TEXTSTRING &&
276 this->GetEncoding() == ID3TE_ASCII &&
277 index < this->GetNumTextItems())
278 {
279 text = _text.c_str();
280 for (size_t i = 0; i < index; ++i)
281 {
282 text += strlen(text) + 1;
283 }
284 }
285 return text;
286}
287
288namespace
289{
290 String readEncodedText(ID3_Reader& reader, size_t len, ID3_TextEnc enc)
291 {
292 if (enc == ID3TE_ASCII)
293 {
294 return io::readText(reader, len);
295 }
296 return io::readUnicodeText(reader, len);
297 }
298
299 String readEncodedString(ID3_Reader& reader, ID3_TextEnc enc)
300 {
301 if (enc == ID3TE_ASCII)
302 {
303 return io::readString(reader);
304 }
305 return io::readUnicodeString(reader);
306 }
307
308 size_t writeEncodedText(ID3_Writer& writer, String data, ID3_TextEnc enc)
309 {
310 if (enc == ID3TE_ASCII)
311 {
312 return io::writeText(writer, data);
313 }
314 return io::writeUnicodeText(writer, data);
315 }
316
317 size_t writeEncodedString(ID3_Writer& writer, String data, ID3_TextEnc enc)
318 {
319 if (enc == ID3TE_ASCII)
320 {
321 return io::writeString(writer, data);
322 }
323 return io::writeUnicodeString(writer, data);
324 }
325}
326
328{
329 ID3D_NOTICE( "ID3_Field::ParseText(): reader.getBeg() = " << reader.getBeg() );
330 ID3D_NOTICE( "ID3_Field::ParseText(): reader.getCur() = " << reader.getCur() );
331 ID3D_NOTICE( "ID3_Field::ParseText(): reader.getEnd() = " << reader.getEnd() );
332 this->Clear();
333
334 ID3_TextEnc enc = this->GetEncoding();
335 size_t fixed_size = this->Size();
336 if (fixed_size)
337 {
338 ID3D_NOTICE( "ID3_Field::ParseText(): fixed size string" );
339 // The string is of fixed length
340 String text = readEncodedText(reader, fixed_size, enc);
341 this->SetText(text);
342 ID3D_NOTICE( "ID3_Field::ParseText(): fixed size string = " << text );
343 }
344 else if (_flags & ID3FF_LIST)
345 {
346 ID3D_NOTICE( "ID3_Field::ParseText(): text list" );
347 // lists are always the last field in a frame. parse all remaining
348 // characters in the reader
349 while (!reader.atEnd())
350 {
351 String text = readEncodedString(reader, enc);
352 this->AddText(text);
353 ID3D_NOTICE( "ID3_Field::ParseText(): adding string = " << text );
354 }
355 }
356 else if (_flags & ID3FF_CSTR)
357 {
358 ID3D_NOTICE( "ID3_Field::ParseText(): null terminated string" );
359 String text = readEncodedString(reader, enc);
360 this->SetText(text);
361 ID3D_NOTICE( "ID3_Field::ParseText(): null terminated string = " << text );
362 }
363 else
364 {
365 ID3D_NOTICE( "ID3_Field::ParseText(): last field string" );
366 String text = readEncodedText(reader, reader.remainingBytes(), enc);
367 // not null terminated.
368 this->AddText(text);
369 ID3D_NOTICE( "ID3_Field::ParseText(): last field string = " << text );
370 }
371
372 _changed = false;
373 return true;
374}
375
377{
378 ID3_TextEnc enc = this->GetEncoding();
379
380 if (_flags & ID3FF_CSTR)
381 {
382 writeEncodedString(writer, _text, enc);
383 }
384 else
385 {
386 writeEncodedText(writer, _text, enc);
387 }
388 _changed = false;
389};
390
400{
401 return _num_items;
402}
403
dami::String GetText() const
size_t Add(const char *data)
const char * GetRawTextItem(size_t) const
size_t SetText(dami::String)
void RenderText(ID3_Writer &) const
const char * GetRawText() const
size_t GetNumTextItems() const
Returns the number of items in a text list.
dami::String GetTextItem(size_t) const
size_t AddText(dami::String)
ID3_FieldType GetType() const
Definition field_impl.h:103
void Set(uint32)
Sets the value of the field to the specified integer.
void Clear()
Clears any data and frees any memory associated with the field.
Definition field.cpp:923
ID3_TextEnc GetEncoding() const
Definition field_impl.h:105
uint32 Get() const
Returns the value of the integer field.
bool ParseText(ID3_Reader &)
size_t Size() const
Returns the size of a field.
Definition field.cpp:1018
virtual pos_type getCur()=0
Return the current position in the reader.
virtual bool atEnd()
Definition reader.h:125
virtual pos_type getEnd()
Return the ending position in the reader.
Definition reader.h:51
virtual size_type remainingBytes()
Definition reader.h:109
virtual pos_type getBeg()
Return the beginning position in the reader.
Definition reader.h:48
#define NULL
Definition globals.h:743
ID3_TextEnc
Enumeration of the types of text encodings: ascii or unicode.
Definition globals.h:138
@ ID3TE_ASCII
Definition globals.h:145
@ ID3TE_UNICODE
Definition globals.h:146
@ ID3FF_CSTR
Definition globals.h:344
@ ID3FF_LIST
Definition globals.h:345
@ ID3FTY_TEXTSTRING
Definition globals.h:356
const T & min(const T &a, const T &b)
Definition utils.h:51