foobar2000 SDK  2015-01-14
tag_processor_id3v2.cpp
Go to the documentation of this file.
1 #include "foobar2000.h"
2 
4 {
5  return service_enum_t<tag_processor_id3v2>().first(p_out);
6 }
7 
8 void tag_processor_id3v2::g_remove(const service_ptr_t<file> & p_file,t_uint64 & p_size_removed,abort_callback & p_abort) {
10  g_remove_ex(cb,p_file,p_size_removed,p_abort);
11 }
12 
13 void tag_processor_id3v2::g_remove_ex(tag_write_callback & p_callback,const service_ptr_t<file> & p_file,t_uint64 & p_size_removed,abort_callback & p_abort)
14 {
15  p_file->ensure_seekable();
16 
17  t_filesize len;
18 
19  len = p_file->get_size(p_abort);
20 
21  if (len == filesize_invalid) throw exception_io_no_length();
22 
23  p_file->seek(0,p_abort);
24 
25  t_uint64 offset;
26  g_multiskip(p_file,offset,p_abort);
27 
28  if (offset>0 && offset<len)
29  {
30  len-=offset;
32  if (p_callback.open_temp_file(temp,p_abort)) {
33  file::g_transfer_object(p_file,temp,len,p_abort);
34  } else {
35  if (len > 16*1024*1024) filesystem::g_open_temp(temp,p_abort);
36  else filesystem::g_open_tempmem(temp,p_abort);
37  file::g_transfer_object(p_file,temp,len,p_abort);
38  p_file->seek(0,p_abort);
39  p_file->set_eof(p_abort);
40  temp->seek(0,p_abort);
41  file::g_transfer_object(temp,p_file,len,p_abort);
42  }
43  }
44  p_size_removed = offset;
45 }
46 
48  t_filesize offset = 0;
49  t_size count = 0;
50  for(;;) {
51  t_filesize delta;
52  g_skip_at(p_file, offset, delta, p_abort);
53  if (delta == 0) break;
54  offset += delta;
55  ++count;
56  }
57  p_size_skipped = offset;
58  return count;
59 }
60 void tag_processor_id3v2::g_skip(const service_ptr_t<file> & p_file,t_uint64 & p_size_skipped,abort_callback & p_abort) {
61  g_skip_at(p_file, 0, p_size_skipped, p_abort);
62 }
63 
64 void tag_processor_id3v2::g_skip_at(const service_ptr_t<file> & p_file,t_filesize p_base, t_filesize & p_size_skipped,abort_callback & p_abort) {
65 
66  unsigned char tmp[10];
67 
68  p_file->seek ( p_base, p_abort );
69 
70  if (p_file->read( tmp, sizeof(tmp), p_abort) != sizeof(tmp)) {
71  p_file->seek ( p_base, p_abort );
72  p_size_skipped = 0;
73  return;
74  }
75 
76  if (
77  0 != memcmp ( tmp, "ID3", 3) ||
78  ( tmp[5] & 0x0F ) != 0 ||
79  ((tmp[6] | tmp[7] | tmp[8] | tmp[9]) & 0x80) != 0
80  ) {
81  p_file->seek ( p_base, p_abort );
82  p_size_skipped = 0;
83  return;
84  }
85 
86  int FooterPresent = tmp[5] & 0x10;
87 
88  t_uint32 ret;
89  ret = tmp[6] << 21;
90  ret += tmp[7] << 14;
91  ret += tmp[8] << 7;
92  ret += tmp[9] ;
93  ret += 10;
94  if ( FooterPresent ) ret += 10;
95 
96  try {
97  p_file->seek ( p_base + ret, p_abort );
98  } catch(exception_io_seek_out_of_range) {
99  p_file->seek( p_base, p_abort );
100  p_size_skipped = 0;
101  return;
102  }
103 
104  p_size_skipped = ret;
105 
106 }
static void g_remove(const service_ptr_t< file > &p_file, t_filesize &p_size_removed, abort_callback &p_abort)
static t_size g_multiskip(const service_ptr_t< file > &p_file, t_filesize &p_size_skipped, abort_callback &p_abort)
uint64_t t_uint64
Definition: int_types.h:3
Callback interface for write-tags-to-temp-file-and-swap scheme, used for ID3v2 tag updates and such w...
Definition: tag_processor.h:6
static const t_filesize filesize_invalid
Invalid/unknown file size constant. Also see: t_filesize.
Definition: filesystem.h:16
static void g_skip(const service_ptr_t< file > &p_file, t_filesize &p_size_skipped, abort_callback &p_abort)
virtual bool open_temp_file(service_ptr_t< file > &p_out, abort_callback &p_abort)=0
Called only once per operation (or not called at all when operation being performed can be done in-pl...
size_t t_size
Definition: int_types.h:48
static void g_skip_at(const service_ptr_t< file > &p_file, t_filesize p_base, t_filesize &p_size_skipped, abort_callback &p_abort)
static void g_remove_ex(tag_write_callback &p_callback, const service_ptr_t< file > &p_file, t_filesize &p_size_removed, abort_callback &p_abort)
static bool g_get(service_ptr_t< tag_processor_id3v2 > &p_out)
t_uint64 t_filesize
Type used for file size related variables.
Definition: filesystem.h:8
Autopointer class to be used with all services. Manages reference counter calls behind-the-scenes.
Definition: service.h:55
uint32_t t_uint32
Definition: int_types.h:5