aboutsummaryrefslogtreecommitdiffstats
path: root/src/playlist
diff options
context:
space:
mode:
Diffstat (limited to 'src/playlist')
-rw-r--r--src/playlist/AsxPlaylistPlugin.cxx38
-rw-r--r--src/playlist/CuePlaylistPlugin.cxx5
-rw-r--r--src/playlist/EmbeddedCuePlaylistPlugin.cxx6
-rw-r--r--src/playlist/ExtM3uPlaylistPlugin.cxx14
-rw-r--r--src/playlist/PlsPlaylistPlugin.cxx23
-rw-r--r--src/playlist/RssPlaylistPlugin.cxx38
-rw-r--r--src/playlist/SoundCloudPlaylistPlugin.cxx89
-rw-r--r--src/playlist/XspfPlaylistPlugin.cxx34
8 files changed, 119 insertions, 128 deletions
diff --git a/src/playlist/AsxPlaylistPlugin.cxx b/src/playlist/AsxPlaylistPlugin.cxx
index 94198b8c3..47983358a 100644
--- a/src/playlist/AsxPlaylistPlugin.cxx
+++ b/src/playlist/AsxPlaylistPlugin.cxx
@@ -23,7 +23,7 @@
#include "MemorySongEnumerator.hxx"
#include "InputStream.hxx"
#include "Song.hxx"
-#include "tag/Tag.hxx"
+#include "tag/TagBuilder.hxx"
#include "util/ASCII.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
@@ -31,7 +31,6 @@
#include <glib.h>
-#include <assert.h>
#include <string.h>
static constexpr Domain asx_domain("asx");
@@ -58,7 +57,7 @@ struct AsxParser {
* valid if state==ENTRY. TAG_NUM_OF_ITEM_TYPES means there
* is no (known) tag.
*/
- TagType tag;
+ TagType tag_type;
/**
* The current song. It is allocated after the "location"
@@ -66,6 +65,8 @@ struct AsxParser {
*/
Song *song;
+ TagBuilder tag_builder;
+
AsxParser()
:state(ROOT) {}
@@ -96,7 +97,7 @@ asx_start_element(gcc_unused GMarkupParseContext *context,
if (StringEqualsCaseASCII(element_name, "entry")) {
parser->state = AsxParser::ENTRY;
parser->song = Song::NewRemote("asx:");
- parser->tag = TAG_NUM_OF_ITEM_TYPES;
+ parser->tag_type = TAG_NUM_OF_ITEM_TYPES;
}
break;
@@ -107,27 +108,22 @@ asx_start_element(gcc_unused GMarkupParseContext *context,
attribute_values,
"href");
if (href != nullptr) {
- /* create new song object, and copy
- the existing tag over; we cannot
+ /* create new song object; we cannot
replace the existing song's URI,
because that attribute is
immutable */
Song *song = Song::NewRemote(href);
-
- if (parser->song != nullptr) {
- song->tag = parser->song->tag;
- parser->song->tag = nullptr;
+ if (parser->song != nullptr)
parser->song->Free();
- }
parser->song = song;
}
} else if (StringEqualsCaseASCII(element_name, "author"))
/* is that correct? or should it be COMPOSER
or PERFORMER? */
- parser->tag = TAG_ARTIST;
+ parser->tag_type = TAG_ARTIST;
else if (StringEqualsCaseASCII(element_name, "title"))
- parser->tag = TAG_TITLE;
+ parser->tag_type = TAG_TITLE;
break;
}
@@ -146,14 +142,16 @@ asx_end_element(gcc_unused GMarkupParseContext *context,
case AsxParser::ENTRY:
if (StringEqualsCaseASCII(element_name, "entry")) {
- if (strcmp(parser->song->uri, "asx:") != 0)
+ if (strcmp(parser->song->uri, "asx:") != 0) {
+ assert(parser->song->tag == nullptr);
+ parser->song->tag = parser->tag_builder.Commit();
parser->songs.emplace_front(parser->song);
- else
+ } else
parser->song->Free();
parser->state = AsxParser::ROOT;
} else
- parser->tag = TAG_NUM_OF_ITEM_TYPES;
+ parser->tag_type = TAG_NUM_OF_ITEM_TYPES;
break;
}
@@ -171,11 +169,9 @@ asx_text(gcc_unused GMarkupParseContext *context,
break;
case AsxParser::ENTRY:
- if (parser->tag != TAG_NUM_OF_ITEM_TYPES) {
- if (parser->song->tag == nullptr)
- parser->song->tag = new Tag();
- parser->song->tag->AddItem(parser->tag,
- text, text_len);
+ if (parser->tag_type != TAG_NUM_OF_ITEM_TYPES) {
+ parser->tag_builder.AddItem(parser->tag_type,
+ text, text_len);
}
break;
diff --git a/src/playlist/CuePlaylistPlugin.cxx b/src/playlist/CuePlaylistPlugin.cxx
index 42a43bbad..00aa758b0 100644
--- a/src/playlist/CuePlaylistPlugin.cxx
+++ b/src/playlist/CuePlaylistPlugin.cxx
@@ -21,13 +21,10 @@
#include "CuePlaylistPlugin.hxx"
#include "PlaylistPlugin.hxx"
#include "SongEnumerator.hxx"
-#include "tag/Tag.hxx"
-#include "Song.hxx"
#include "cue/CueParser.hxx"
#include "TextInputStream.hxx"
-#include <assert.h>
-#include <string.h>
+#include <string>
class CuePlaylist final : public SongEnumerator {
InputStream &is;
diff --git a/src/playlist/EmbeddedCuePlaylistPlugin.cxx b/src/playlist/EmbeddedCuePlaylistPlugin.cxx
index d758650eb..96d83b968 100644
--- a/src/playlist/EmbeddedCuePlaylistPlugin.cxx
+++ b/src/playlist/EmbeddedCuePlaylistPlugin.cxx
@@ -27,7 +27,6 @@
#include "EmbeddedCuePlaylistPlugin.hxx"
#include "PlaylistPlugin.hxx"
#include "SongEnumerator.hxx"
-#include "tag/Tag.hxx"
#include "tag/TagHandler.hxx"
#include "tag/TagId3.hxx"
#include "tag/ApeTag.hxx"
@@ -38,7 +37,6 @@
#include "fs/AllocatedPath.hxx"
#include "util/ASCII.hxx"
-#include <assert.h>
#include <string.h>
class EmbeddedCuePlaylist final : public SongEnumerator {
@@ -95,7 +93,7 @@ embcue_playlist_open_uri(const char *uri,
gcc_unused Mutex &mutex,
gcc_unused Cond &cond)
{
- if (!PathTraits::IsAbsoluteUTF8(uri))
+ if (!PathTraitsUTF8::IsAbsolute(uri))
/* only local files supported */
return nullptr;
@@ -118,7 +116,7 @@ embcue_playlist_open_uri(const char *uri,
return nullptr;
}
- playlist->filename = PathTraits::GetBaseUTF8(uri);
+ playlist->filename = PathTraitsUTF8::GetBase(uri);
playlist->next = &playlist->cuesheet[0];
playlist->parser = new CueParser();
diff --git a/src/playlist/ExtM3uPlaylistPlugin.cxx b/src/playlist/ExtM3uPlaylistPlugin.cxx
index 8d260fec7..d48db1ed2 100644
--- a/src/playlist/ExtM3uPlaylistPlugin.cxx
+++ b/src/playlist/ExtM3uPlaylistPlugin.cxx
@@ -23,11 +23,10 @@
#include "SongEnumerator.hxx"
#include "Song.hxx"
#include "tag/Tag.hxx"
+#include "tag/TagBuilder.hxx"
#include "util/StringUtil.hxx"
#include "TextInputStream.hxx"
-#include <glib.h>
-
#include <string.h>
#include <stdlib.h>
@@ -74,7 +73,6 @@ extm3u_parse_tag(const char *line)
long duration;
char *endptr;
const char *name;
- Tag *tag;
duration = strtol(line, &endptr, 10);
if (endptr[0] != ',')
@@ -91,16 +89,16 @@ extm3u_parse_tag(const char *line)
object */
return NULL;
- tag = new Tag();
- tag->time = duration;
+ TagBuilder tag;
+ tag.SetTime(duration);
/* unfortunately, there is no real specification for the
EXTM3U format, so we must assume that the string after the
comma is opaque, and is just the song name*/
if (*name != 0)
- tag->AddItem(TAG_NAME, name);
+ tag.AddItem(TAG_NAME, name);
- return tag;
+ return tag.Commit();
}
Song *
@@ -119,7 +117,7 @@ ExtM3uPlaylist::NextSong()
line_s = line.c_str();
- if (g_str_has_prefix(line_s, "#EXTINF:")) {
+ if (StringStartsWith(line_s, "#EXTINF:")) {
delete tag;
tag = extm3u_parse_tag(line_s + 8);
continue;
diff --git a/src/playlist/PlsPlaylistPlugin.cxx b/src/playlist/PlsPlaylistPlugin.cxx
index d44a34cdf..329bd8bfb 100644
--- a/src/playlist/PlsPlaylistPlugin.cxx
+++ b/src/playlist/PlsPlaylistPlugin.cxx
@@ -23,7 +23,7 @@
#include "MemorySongEnumerator.hxx"
#include "InputStream.hxx"
#include "Song.hxx"
-#include "tag/Tag.hxx"
+#include "tag/TagBuilder.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "Log.hxx"
@@ -32,6 +32,8 @@
#include <string>
+#include <stdio.h>
+
static constexpr Domain pls_domain("pls");
static void
@@ -75,14 +77,14 @@ pls_parser(GKeyFile *keyfile, std::forward_list<SongPointer> &songs)
song = Song::NewRemote(value);
g_free(value);
+ TagBuilder tag;
+
sprintf(key, "Title%u", num_entries);
value = g_key_file_get_string(keyfile, "playlist", key,
&error);
- if(error == nullptr && value){
- if (song->tag == nullptr)
- song->tag = new Tag();
- song->tag->AddItem(TAG_TITLE, value);
- }
+ if (error == nullptr && value != nullptr)
+ tag.AddItem(TAG_TITLE, value);
+
/* Ignore errors? Most likely value not present */
if(error) g_error_free(error);
error = nullptr;
@@ -91,15 +93,14 @@ pls_parser(GKeyFile *keyfile, std::forward_list<SongPointer> &songs)
sprintf(key, "Length%u", num_entries);
length = g_key_file_get_integer(keyfile, "playlist", key,
&error);
- if(error == nullptr && length > 0){
- if (song->tag == nullptr)
- song->tag = new Tag();
- song->tag->time = length;
- }
+ if (error == nullptr && length > 0)
+ tag.SetTime(length);
+
/* Ignore errors? Most likely value not present */
if(error) g_error_free(error);
error = nullptr;
+ song->tag = tag.Commit();
songs.emplace_front(song);
num_entries--;
}
diff --git a/src/playlist/RssPlaylistPlugin.cxx b/src/playlist/RssPlaylistPlugin.cxx
index e2a44bfd3..62f636126 100644
--- a/src/playlist/RssPlaylistPlugin.cxx
+++ b/src/playlist/RssPlaylistPlugin.cxx
@@ -23,7 +23,7 @@
#include "MemorySongEnumerator.hxx"
#include "InputStream.hxx"
#include "Song.hxx"
-#include "tag/Tag.hxx"
+#include "tag/TagBuilder.hxx"
#include "util/ASCII.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
@@ -31,7 +31,6 @@
#include <glib.h>
-#include <assert.h>
#include <string.h>
static constexpr Domain rss_domain("rss");
@@ -58,7 +57,7 @@ struct RssParser {
* valid if state==ITEM. TAG_NUM_OF_ITEM_TYPES means there
* is no (known) tag.
*/
- TagType tag;
+ TagType tag_type;
/**
* The current song. It is allocated after the "location"
@@ -66,6 +65,8 @@ struct RssParser {
*/
Song *song;
+ TagBuilder tag_builder;
+
RssParser()
:state(ROOT) {}
};
@@ -95,7 +96,7 @@ rss_start_element(gcc_unused GMarkupParseContext *context,
if (StringEqualsCaseASCII(element_name, "item")) {
parser->state = RssParser::ITEM;
parser->song = Song::NewRemote("rss:");
- parser->tag = TAG_NUM_OF_ITEM_TYPES;
+ parser->tag_type = TAG_NUM_OF_ITEM_TYPES;
}
break;
@@ -106,25 +107,21 @@ rss_start_element(gcc_unused GMarkupParseContext *context,
attribute_values,
"url");
if (href != nullptr) {
- /* create new song object, and copy
- the existing tag over; we cannot
+ /* create new song object; we cannot
replace the existing song's URI,
because that attribute is
immutable */
Song *song = Song::NewRemote(href);
- if (parser->song != nullptr) {
- song->tag = parser->song->tag;
- parser->song->tag = nullptr;
+ if (parser->song != nullptr)
parser->song->Free();
- }
parser->song = song;
}
} else if (StringEqualsCaseASCII(element_name, "title"))
- parser->tag = TAG_TITLE;
+ parser->tag_type = TAG_TITLE;
else if (StringEqualsCaseASCII(element_name, "itunes:author"))
- parser->tag = TAG_ARTIST;
+ parser->tag_type = TAG_ARTIST;
break;
}
@@ -143,14 +140,16 @@ rss_end_element(gcc_unused GMarkupParseContext *context,
case RssParser::ITEM:
if (StringEqualsCaseASCII(element_name, "item")) {
- if (strcmp(parser->song->uri, "rss:") != 0)
+ if (strcmp(parser->song->uri, "rss:") != 0) {
+ assert(parser->song->tag == nullptr);
+ parser->song->tag = parser->tag_builder.Commit();
parser->songs.emplace_front(parser->song);
- else
+ } else
parser->song->Free();
parser->state = RssParser::ROOT;
} else
- parser->tag = TAG_NUM_OF_ITEM_TYPES;
+ parser->tag_type = TAG_NUM_OF_ITEM_TYPES;
break;
}
@@ -168,12 +167,9 @@ rss_text(gcc_unused GMarkupParseContext *context,
break;
case RssParser::ITEM:
- if (parser->tag != TAG_NUM_OF_ITEM_TYPES) {
- if (parser->song->tag == nullptr)
- parser->song->tag = new Tag();
- parser->song->tag->AddItem(parser->tag,
- text, text_len);
- }
+ if (parser->tag_type != TAG_NUM_OF_ITEM_TYPES)
+ parser->tag_builder.AddItem(parser->tag_type,
+ text, text_len);
break;
}
diff --git a/src/playlist/SoundCloudPlaylistPlugin.cxx b/src/playlist/SoundCloudPlaylistPlugin.cxx
index f6797b14d..0ab250b22 100644
--- a/src/playlist/SoundCloudPlaylistPlugin.cxx
+++ b/src/playlist/SoundCloudPlaylistPlugin.cxx
@@ -24,7 +24,8 @@
#include "ConfigData.hxx"
#include "InputStream.hxx"
#include "Song.hxx"
-#include "tag/Tag.hxx"
+#include "tag/TagBuilder.hxx"
+#include "util/StringUtil.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "Log.hxx"
@@ -62,12 +63,13 @@ soundcloud_init(const config_param &param)
* @return Constructed URL. Must be freed with g_free.
*/
static char *
-soundcloud_resolve(const char* uri) {
+soundcloud_resolve(const char* uri)
+{
char *u, *ru;
- if (g_str_has_prefix(uri, "http://")) {
+ if (StringStartsWith(uri, "http://")) {
u = g_strdup(uri);
- } else if (g_str_has_prefix(uri, "soundcloud.com")) {
+ } else if (StringStartsWith(uri, "soundcloud.com")) {
u = g_strconcat("http://", uri, nullptr);
} else {
/* assume it's just a path on soundcloud.com */
@@ -108,12 +110,13 @@ struct parse_data {
std::forward_list<SongPointer> songs;
};
-static int handle_integer(void *ctx,
- long
+static int
+handle_integer(void *ctx,
+ long
#ifndef HAVE_YAJL1
- long
+ long
#endif
- intval)
+ intval)
{
struct parse_data *data = (struct parse_data *) ctx;
@@ -128,13 +131,14 @@ static int handle_integer(void *ctx,
return 1;
}
-static int handle_string(void *ctx, const unsigned char* stringval,
+static int
+handle_string(void *ctx, const unsigned char* stringval,
#ifdef HAVE_YAJL1
- unsigned int
+ unsigned int
#else
- size_t
+ size_t
#endif
- stringlen)
+ stringlen)
{
struct parse_data *data = (struct parse_data *) ctx;
const char *s = (const char *) stringval;
@@ -158,13 +162,14 @@ static int handle_string(void *ctx, const unsigned char* stringval,
return 1;
}
-static int handle_mapkey(void *ctx, const unsigned char* stringval,
+static int
+handle_mapkey(void *ctx, const unsigned char* stringval,
#ifdef HAVE_YAJL1
- unsigned int
+ unsigned int
#else
- size_t
+ size_t
#endif
- stringlen)
+ stringlen)
{
struct parse_data *data = (struct parse_data *) ctx;
@@ -181,7 +186,8 @@ static int handle_mapkey(void *ctx, const unsigned char* stringval,
return 1;
}
-static int handle_start_map(void *ctx)
+static int
+handle_start_map(void *ctx)
{
struct parse_data *data = (struct parse_data *) ctx;
@@ -191,7 +197,8 @@ static int handle_start_map(void *ctx)
return 1;
}
-static int handle_end_map(void *ctx)
+static int
+handle_end_map(void *ctx)
{
struct parse_data *data = (struct parse_data *) ctx;
@@ -206,19 +213,16 @@ static int handle_end_map(void *ctx)
/* got_url == 1, track finished, make it into a song */
data->got_url = 0;
- Song *s;
- char *u;
-
- u = g_strconcat(data->stream_url, "?client_id=",
- soundcloud_config.apikey.c_str(), nullptr);
- s = Song::NewRemote(u);
+ char *u = g_strconcat(data->stream_url, "?client_id=",
+ soundcloud_config.apikey.c_str(), nullptr);
+ Song *s = Song::NewRemote(u);
g_free(u);
- Tag *t = new Tag();
- t->time = data->duration / 1000;
+ TagBuilder tag;
+ tag.SetTime(data->duration / 1000);
if (data->title != nullptr)
- t->AddItem(TAG_NAME, data->title);
- s->tag = t;
+ tag.AddItem(TAG_NAME, data->title);
+ s->tag = tag.Commit();
data->songs.emplace_front(s);
@@ -249,9 +253,6 @@ static int
soundcloud_parse_json(const char *url, yajl_handle hand,
Mutex &mutex, Cond &cond)
{
- char buffer[4096];
- unsigned char *ubuffer = (unsigned char *)buffer;
-
Error error;
InputStream *input_stream = InputStream::Open(url, mutex, cond,
error);
@@ -268,6 +269,8 @@ soundcloud_parse_json(const char *url, yajl_handle hand,
int done = 0;
while (!done) {
+ char buffer[4096];
+ unsigned char *ubuffer = (unsigned char *)buffer;
const size_t nbytes =
input_stream->Read(buffer, sizeof(buffer), error);
if (nbytes == 0) {
@@ -318,22 +321,22 @@ soundcloud_parse_json(const char *url, yajl_handle hand,
* soundcloud://playlist/<playlist-id>
* soundcloud://url/<url or path of soundcloud page>
*/
-
static SongEnumerator *
soundcloud_open_uri(const char *uri, Mutex &mutex, Cond &cond)
{
- char *s, *p;
- char *scheme, *arg, *rest;
- s = g_strdup(uri);
- scheme = s;
- for (p = s; *p; p++) {
+ char *s = g_strdup(uri);
+ char *scheme = s;
+
+ char *p = s;
+ for (; *p; p++) {
if (*p == ':' && *(p+1) == '/' && *(p+2) == '/') {
*p = 0;
p += 3;
break;
}
}
- arg = p;
+
+ char *arg = p;
for (; *p; p++) {
if (*p == '/') {
*p = 0;
@@ -341,7 +344,8 @@ soundcloud_open_uri(const char *uri, Mutex &mutex, Cond &cond)
break;
}
}
- rest = p;
+
+ char *rest = p;
if (strcmp(scheme, "soundcloud") != 0) {
FormatWarning(soundcloud_domain,
@@ -372,16 +376,15 @@ soundcloud_open_uri(const char *uri, Mutex &mutex, Cond &cond)
return nullptr;
}
- yajl_handle hand;
struct parse_data data;
-
data.got_url = 0;
data.title = nullptr;
data.stream_url = nullptr;
#ifdef HAVE_YAJL1
- hand = yajl_alloc(&parse_callbacks, nullptr, nullptr, (void *) &data);
+ yajl_handle hand = yajl_alloc(&parse_callbacks, nullptr, nullptr,
+ &data);
#else
- hand = yajl_alloc(&parse_callbacks, nullptr, (void *) &data);
+ yajl_handle hand = yajl_alloc(&parse_callbacks, nullptr, &data);
#endif
int ret = soundcloud_parse_json(u, hand, mutex, cond);
diff --git a/src/playlist/XspfPlaylistPlugin.cxx b/src/playlist/XspfPlaylistPlugin.cxx
index dcfab5a80..2935225e4 100644
--- a/src/playlist/XspfPlaylistPlugin.cxx
+++ b/src/playlist/XspfPlaylistPlugin.cxx
@@ -22,14 +22,13 @@
#include "PlaylistPlugin.hxx"
#include "MemorySongEnumerator.hxx"
#include "InputStream.hxx"
-#include "tag/Tag.hxx"
+#include "tag/TagBuilder.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "Log.hxx"
#include <glib.h>
-#include <assert.h>
#include <string.h>
static constexpr Domain xspf_domain("xspf");
@@ -57,7 +56,7 @@ struct XspfParser {
* valid if state==TRACK. TAG_NUM_OF_ITEM_TYPES means there
* is no (known) tag.
*/
- TagType tag;
+ TagType tag_type;
/**
* The current song. It is allocated after the "location"
@@ -65,6 +64,8 @@ struct XspfParser {
*/
Song *song;
+ TagBuilder tag_builder;
+
XspfParser()
:state(ROOT) {}
};
@@ -95,7 +96,7 @@ xspf_start_element(gcc_unused GMarkupParseContext *context,
if (strcmp(element_name, "track") == 0) {
parser->state = XspfParser::TRACK;
parser->song = nullptr;
- parser->tag = TAG_NUM_OF_ITEM_TYPES;
+ parser->tag_type = TAG_NUM_OF_ITEM_TYPES;
}
break;
@@ -104,17 +105,17 @@ xspf_start_element(gcc_unused GMarkupParseContext *context,
if (strcmp(element_name, "location") == 0)
parser->state = XspfParser::LOCATION;
else if (strcmp(element_name, "title") == 0)
- parser->tag = TAG_TITLE;
+ parser->tag_type = TAG_TITLE;
else if (strcmp(element_name, "creator") == 0)
/* TAG_COMPOSER would be more correct
according to the XSPF spec */
- parser->tag = TAG_ARTIST;
+ parser->tag_type = TAG_ARTIST;
else if (strcmp(element_name, "annotation") == 0)
- parser->tag = TAG_COMMENT;
+ parser->tag_type = TAG_COMMENT;
else if (strcmp(element_name, "album") == 0)
- parser->tag = TAG_ALBUM;
+ parser->tag_type = TAG_ALBUM;
else if (strcmp(element_name, "trackNum") == 0)
- parser->tag = TAG_TRACK;
+ parser->tag_type = TAG_TRACK;
break;
@@ -148,12 +149,15 @@ xspf_end_element(gcc_unused GMarkupParseContext *context,
case XspfParser::TRACK:
if (strcmp(element_name, "track") == 0) {
- if (parser->song != nullptr)
+ if (parser->song != nullptr) {
+ assert(parser->song->tag == nullptr);
+ parser->song->tag = parser->tag_builder.Commit();
parser->songs.emplace_front(parser->song);
+ }
parser->state = XspfParser::TRACKLIST;
} else
- parser->tag = TAG_NUM_OF_ITEM_TYPES;
+ parser->tag_type = TAG_NUM_OF_ITEM_TYPES;
break;
@@ -178,11 +182,9 @@ xspf_text(gcc_unused GMarkupParseContext *context,
case XspfParser::TRACK:
if (parser->song != nullptr &&
- parser->tag != TAG_NUM_OF_ITEM_TYPES) {
- if (parser->song->tag == nullptr)
- parser->song->tag = new Tag();
- parser->song->tag->AddItem(parser->tag, text, text_len);
- }
+ parser->tag_type != TAG_NUM_OF_ITEM_TYPES)
+ parser->tag_builder.AddItem(parser->tag_type,
+ text, text_len);
break;