~ubuntu-branches/ubuntu/karmic/taglib-extras/karmic

« back to all changes in this revision

Viewing changes to taglib-extras/audible/audibletag.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2009-04-01 15:35:05 UTC
  • Revision ID: james.westby@ubuntu.com-20090401153505-vwi459v8y2c1xnbr
Tags: upstream-0.1.1
ImportĀ upstreamĀ versionĀ 0.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
    copyright            : (C) 2005 by Martin Aumueller
 
3
    email                : aumuell@reserv.at
 
4
 
 
5
    copyright            : (C) 2005 by Andy Leadbetter
 
6
    email                : andrew.leadbetter@gmail.com
 
7
                           (original mp4 implementation)
 
8
 ***************************************************************************/
 
9
 
 
10
/***************************************************************************
 
11
 *   This library is free software; you can redistribute it and/or modify  *
 
12
 *   it  under the terms of the GNU Lesser General Public License version  *
 
13
 *   2.1 as published by the Free Software Foundation.                     *
 
14
 *                                                                         *
 
15
 *   This library is distributed in the hope that it will be useful, but   *
 
16
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 
17
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 
18
 *   Lesser General Public License for more details.                       *
 
19
 *                                                                         *
 
20
 *   You should have received a copy of the GNU Lesser General Public      *
 
21
 *   License along with this library; if not, write to the Free Software   *
 
22
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,            *
 
23
 *   MA  02110-1301  USA                                                   *
 
24
 ***************************************************************************/
 
25
 
 
26
#include "audibletag.h"
 
27
 
 
28
#include <tag.h>
 
29
#include <string.h>
 
30
#include <stdio.h>
 
31
#include <stdlib.h>
 
32
 
 
33
#if !defined(_WIN32) && !defined(_WIN64)
 
34
#include <netinet/in.h> // ntohl
 
35
#else
 
36
#include <winsock2.h>
 
37
#endif
 
38
 
 
39
using namespace TagLib;
 
40
 
 
41
Audible::Tag::Tag() {
 
42
    m_title = String::null;
 
43
    m_artist = String::null;
 
44
    m_album = String::null;
 
45
    m_comment = String::null;
 
46
    m_genre = String::null;
 
47
    m_year = 0;
 
48
    m_track = 0;
 
49
    m_userID = 0;
 
50
    m_tagsEndOffset = -1;
 
51
}
 
52
 
 
53
Audible::Tag::~Tag() {
 
54
}
 
55
 
 
56
bool Audible::Tag::isEmpty() const {
 
57
    return  m_title == String::null &&
 
58
        m_artist == String::null &&
 
59
        m_album == String::null && 
 
60
        m_comment == String::null &&
 
61
        m_genre == String::null &&
 
62
        m_year == 0 &&
 
63
        m_track == 0 &&
 
64
        m_userID == 0;
 
65
}
 
66
 
 
67
void Audible::Tag::duplicate(const Tag *source, Tag *target, bool overwrite) {
 
68
    // No nonstandard information stored yet
 
69
    TagLib::Tag::duplicate(source, target, overwrite);
 
70
}
 
71
 
 
72
#define OFF_PRODUCT_ID 197
 
73
#define OFF_TAGS 189
 
74
 
 
75
void Audible::Tag::readTags( FILE *fp )
 
76
{
 
77
    char buf[1023];
 
78
    if ( fseek(fp, OFF_PRODUCT_ID, SEEK_SET) != 0 )
 
79
        return;
 
80
 
 
81
    if ( fread(buf, strlen("product_id"), 1, fp) != 1 )
 
82
        return;
 
83
 
 
84
    if(memcmp(buf, "product_id", strlen("product_id")))
 
85
    {
 
86
        buf[20]='\0';
 
87
        fprintf(stderr, "no valid Audible aa file: %s\n", buf);
 
88
        return;
 
89
    }
 
90
 
 
91
    // Now parse tag.
 
92
 
 
93
    fseek(fp, OFF_TAGS, SEEK_SET);
 
94
    char *name = 0, *value = 0;
 
95
 
 
96
    m_tagsEndOffset = OFF_TAGS;
 
97
 
 
98
    bool lasttag = false;
 
99
    while(!lasttag)
 
100
    {
 
101
        lasttag = !readTag(fp, &name, &value);
 
102
        if(!strcmp(name, "title"))
 
103
        {
 
104
            m_title = String(value, String::Latin1);
 
105
        }
 
106
        else if(!strcmp(name, "author"))
 
107
        {
 
108
            m_artist = String(value, String::Latin1);
 
109
        }
 
110
        else if(!strcmp(name, "long_description"))
 
111
        {
 
112
            m_comment = String(value, String::Latin1);
 
113
        }
 
114
        else if(!strcmp(name, "description"))
 
115
        {
 
116
            if( m_comment.isNull() )
 
117
                m_comment = String(value, String::Latin1);
 
118
        }
 
119
        else if(!strcmp(name, "pubdate"))
 
120
        {
 
121
            m_year = 0;
 
122
            
 
123
            char *p = value ? strrchr(value, '-') : 0;
 
124
            if(p)
 
125
                m_year = strtol(p+1, NULL, 10);
 
126
        }
 
127
        else if(!strcmp(name, "user_id"))
 
128
        {
 
129
            m_userID = value ? strtol(value, NULL, 10) : -1;
 
130
        }
 
131
 
 
132
        delete[] name;
 
133
        name = 0;
 
134
        delete[] value;
 
135
        value = 0;
 
136
    }
 
137
 
 
138
    m_album  =  String("", String::Latin1);
 
139
    m_track = 0;
 
140
    m_genre = String("Audiobook", String::Latin1);
 
141
}
 
142
 
 
143
bool Audible::Tag::readTag( FILE *fp, char **name, char **value)
 
144
{
 
145
    // arbitrary value that has to be smaller than 2^32-1 and that should be large enough for all tags
 
146
    const uint32_t maxtaglen = 100000;
 
147
 
 
148
    uint32_t nlen;
 
149
    if ( fread(&nlen, sizeof(nlen), 1, fp) != 1 )
 
150
        return false;
 
151
 
 
152
    nlen = ntohl(nlen);
 
153
    //fprintf(stderr, "tagname len=%x\n", (unsigned)nlen);
 
154
    if(nlen > maxtaglen)
 
155
        return false;
 
156
    *name = new char[nlen+1];
 
157
    if (!*name)
 
158
        return false;
 
159
    (*name)[nlen] = '\0';
 
160
 
 
161
    uint32_t vlen;
 
162
    if ( fread(&vlen, sizeof(vlen), 1, fp) != 1 )
 
163
    {
 
164
        delete [] *name;
 
165
        *name = 0;
 
166
        return false;
 
167
    }
 
168
 
 
169
    vlen = ntohl(vlen);
 
170
    if (vlen > maxtaglen)
 
171
    {
 
172
        delete [] *name;
 
173
        *name = 0;
 
174
        return false;
 
175
    }
 
176
    //fprintf(stderr, "tag len=%x\n", (unsigned)vlen);
 
177
    if ( fread(*name, nlen, 1, fp) != 1 )
 
178
    {
 
179
        delete [] *name;
 
180
        *name = 0;
 
181
        return false;
 
182
    }
 
183
 
 
184
    *value = new char[vlen+1];
 
185
    if (!*value)
 
186
    {
 
187
        delete [] *name;
 
188
        *name = 0;
 
189
        return false;
 
190
    }
 
191
    (*value)[vlen] = '\0';
 
192
 
 
193
    if ( fread(*value, vlen, 1, fp) != 1 )
 
194
    {
 
195
        delete [] *value;
 
196
        *value = 0;
 
197
        return false;
 
198
    }
 
199
 
 
200
    char lasttag;
 
201
    if ( fread(&lasttag, 1, 1, fp) != 1 )
 
202
        return false;
 
203
 
 
204
    //fprintf(stderr, "%s: \"%s\"\n", *name, *value);
 
205
 
 
206
    m_tagsEndOffset += 2 * 4 + nlen + vlen + 1;
 
207
 
 
208
    return !lasttag;
 
209
}
 
210
 
 
211
int Audible::Tag::getTagsEndOffset()
 
212
{
 
213
    return m_tagsEndOffset;
 
214
}