DCL 4.0
Loading...
Searching...
No Matches
ID3v2.cpp File Reference
#include <dcl/Config.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <dcl/size_t.h>
#include <dcl/Charset.h>
#include <dcl/File.h>
#include "ID3v2.h"

Go to the source code of this file.

Macros

#define __TRACE_THIS   0
#define __DCL_TRACE1_N(fmt, arg)
#define __DCL_TRACE2_N(fmt, arg1, arg2)
#define __DCL_TRACE3_N(fmt, arg1, arg2, arg3)
#define __DCL_TRACE4_N(fmt, arg1, arg2, arg3, arg4)
#define __IF_ENCODING__
#define __IF_LANGUAGE__
#define __IF_DESCRIPTION__
#define __IF_TEXT__
#define __IF_URL__
#define __IF_TYPE__
#define __IF_BINARY__

Functions

__DCL_BEGIN_NAMESPACE IMPLEMENT_CLASSINFO (ID3v2, Object) ID3v2
bool __IS_UPPER (const char *_begin, const char *_end)
int __find_frame_size_bits (char _version, const char *_begin, const char *_end, bool _debug)
 IMPLEMENT_CLASSINFO (ID3v2Frame, Object) ID3v2Frame
size_t __decode_length__ (char _encoding, const char *_psz, size_t _max)
size_t __skip_length__ (char _encoding, size_t _n)
bool __valid_language_code (const char _lang[3])

Macro Definition Documentation

◆ __DCL_TRACE1_N

#define __DCL_TRACE1_N ( fmt,
arg )

Definition at line 25 of file ID3v2.cpp.

◆ __DCL_TRACE2_N

#define __DCL_TRACE2_N ( fmt,
arg1,
arg2 )

Definition at line 26 of file ID3v2.cpp.

◆ __DCL_TRACE3_N

#define __DCL_TRACE3_N ( fmt,
arg1,
arg2,
arg3 )

Definition at line 27 of file ID3v2.cpp.

◆ __DCL_TRACE4_N

#define __DCL_TRACE4_N ( fmt,
arg1,
arg2,
arg3,
arg4 )

Definition at line 28 of file ID3v2.cpp.

◆ __IF_BINARY__

#define __IF_BINARY__
Value:
if (_begin < _end) { \
__binary.assign(_begin, _end - _begin); \
}

◆ __IF_DESCRIPTION__

#define __IF_DESCRIPTION__
Value:
if (_begin < _end) { \
size_t n = __decode_length__(__encoding, _begin, _end - _begin); \
__description = decode(__encoding, _begin, n).trim(); \
_begin += __skip_length__(__encoding, n); \
}
size_t __skip_length__(char _encoding, size_t _n)
Definition ID3v2.cpp:370
size_t __decode_length__(char _encoding, const char *_psz, size_t _max)
Definition ID3v2.cpp:349
void CharsetConvertException *size_t n
Definition SQLField.cpp:253

◆ __IF_ENCODING__

#define __IF_ENCODING__
Value:
if (_begin < _end) { \
__encoding = *_begin++; \
}

◆ __IF_LANGUAGE__

#define __IF_LANGUAGE__
Value:
if (_begin + 3 < _end && __valid_language_code(_begin)) { \
__url = AsciiDecoder::decode(_begin, 3).trim(); \
_begin += 3; \
}
bool __valid_language_code(const char _lang[3])
Definition ID3v2.cpp:376
static String decode(const char *_mbs, size_t _mbslen=(size_t) -1)

◆ __IF_TEXT__

#define __IF_TEXT__
Value:
if (_begin < _end) { \
size_t n = __decode_length__(__encoding, _begin, _end - _begin); \
__text = decode(__encoding, _begin, n).trim(); \
_begin += __skip_length__(__encoding, n); \
}

◆ __IF_TYPE__

#define __IF_TYPE__
Value:
if (_begin < _end) { \
__type = *_begin++; \
}

◆ __IF_URL__

#define __IF_URL__
Value:
if (_begin < _end) { \
size_t n = ByteString::length(_begin, _end - _begin); \
__url = decode(0, _begin, n).trim(); \
_begin += n + 1; \
}

◆ __TRACE_THIS

#define __TRACE_THIS   0

Definition at line 18 of file ID3v2.cpp.

Function Documentation

◆ __decode_length__()

size_t __decode_length__ ( char _encoding,
const char * _psz,
size_t _max )

Definition at line 349 of file ID3v2.cpp.

350{
351 __DCL_ASSERT_PARAM(_psz != NULL);
352 size_t r = 0;
353 if (_encoding == 1 || _encoding == 2) {
354 // UTF-16 LE (1), UTF-16 BE (2)
355 while ((*_psz++ | *_psz++) && r < _max) {
356 r++; r++;
357 }
358 return r < _max ? r: _max;
359 }
360 else {
361 // ISO-8859-1 (0), UTF-8 (3)
362 // cf. ByteString::length(const char* _psz, size_t _max)
363 while (*_psz++ && r < _max) {
364 r++;
365 }
366 }
367 return r;
368}
#define NULL
Definition Config.h:340
#define __DCL_ASSERT_PARAM(expr)
Definition Object.h:384
ByteString r

◆ __find_frame_size_bits()

int __find_frame_size_bits ( char _version,
const char * _begin,
const char * _end,
bool _debug )

Definition at line 91 of file ID3v2.cpp.

93{
94 size_t __3_or_4 = 3;
95 size_t __6_or_10 = 6;
96 if (_version > 2) {
97 __3_or_4 = 4;
98 __6_or_10 = 10;
99 }
100
101 // 8bits를 검사한다.
102 const char* p = _begin;
103 bool valid = true;
104 while (p + __6_or_10 < _end && *p != '\0') {
105 if (__IS_UPPER(p, p + __3_or_4)) {
106 String name = AsciiDecoder::decode(p, __3_or_4);
107 uint32_t size = ID3v2::word8(p + __3_or_4, __3_or_4);
108 if (_debug) {
109 __DCL_TRACE2(L"[%ls][%d]\n", name.data(), size);
110 }
111 p += size + __6_or_10;
112 }
113 else {
114 if (_debug) {
115 __DCL_TRACE0(L"false\n");
116 }
117 valid = false;
118 break;
119 }
120 }
121
122 if (p > _end || (p < _end && *p != '\0')) {
123 // 마지막 프레임의 size로 인해 p가 _end 지나쳤거나
124 // padding 위치가 아니면
125 if (_debug) {
126 __DCL_TRACE3(L"false [%p][%p][%x]\n", p, _end, *p);
127 }
128 valid = false;
129 }
130
131 if (valid) {
132 return 8;
133 }
134
135 // 7bits를 검사한다.
136 p = _begin;
137 valid = true;
138 while (p + __6_or_10 < _end && *p != '\0') {
139 if (__IS_UPPER(p, p + __3_or_4)) {
140 String name = AsciiDecoder::decode(p, __3_or_4);
141 uint32_t size = ID3v2::word7(p + __3_or_4, __3_or_4);
142 if (_debug) {
143 __DCL_TRACE2(L"[%ls][%d]\n", name.data(), size);
144 }
145 p += size + __6_or_10;
146 }
147 else {
148 if (_debug) {
149 __DCL_TRACE0(L"false\n");
150 }
151 valid = false;
152 break;
153 }
154 }
155
156 if (p > _end || (p < _end && *p != '\0')) {
157 // 마지막 프레임의 size로 인해 p가 _end 지나쳤거나
158 // padding 위치가 아니면
159 if (_debug) {
160 __DCL_TRACE3(L"false [%p][%p][%x]\n", p, _end, *p);
161 }
162 valid = false;
163 }
164
165 if (valid) {
166 return 7;
167 }
168
169 return 0;
170}
bool __IS_UPPER(const char *_begin, const char *_end)
Definition ID3v2.cpp:80
#define __DCL_TRACE0(psz)
Definition Object.h:375
#define __DCL_TRACE3(fmt, arg1, arg2, arg3)
Definition Object.h:378
#define __DCL_TRACE2(fmt, arg1, arg2)
Definition Object.h:377

◆ __IS_UPPER()

bool __IS_UPPER ( const char * _begin,
const char * _end )

Definition at line 80 of file ID3v2.cpp.

81{
82 while (_begin < _end) {
83 if (!(isupper(*_begin) || isdigit(*_begin))) {
84 return false;
85 }
86 _begin++;
87 }
88 return true;
89}

◆ __skip_length__()

size_t __skip_length__ ( char _encoding,
size_t _n )

Definition at line 370 of file ID3v2.cpp.

371{
372 // UTF-16은 $00 $00, ASCII ISO-8858-1 UTF-8는 $00
373 return _encoding == 1 || _encoding == 2 ? _n + 2 : _n + 1;
374}

◆ __valid_language_code()

bool __valid_language_code ( const char _lang[3])

Definition at line 376 of file ID3v2.cpp.

377{
378 // https://www.loc.gov/standards/iso639-2/
379 return (_lang[0] == 'X' && _lang[1] == 'X' && _lang[2] == 'X') ||
380 (islower(_lang[0]) && islower(_lang[1]) && islower(_lang[2]));
381}

◆ IMPLEMENT_CLASSINFO() [1/2]

__DCL_BEGIN_NAMESPACE IMPLEMENT_CLASSINFO ( ID3v2 ,
Object  )

Definition at line 38 of file ID3v2.cpp.

41 : __header{'\0', }, __data(NULL), __fsbits(0)
42{
43}

◆ IMPLEMENT_CLASSINFO() [2/2]

IMPLEMENT_CLASSINFO ( ID3v2Frame ,
Object  )

Definition at line 283 of file ID3v2.cpp.

286 : __tag(_tag)
287{
288 __size = 0;
289 __flags = 0;
290 __encoding = 0;
291 __type = 0;
292}