9
septembre
2012
lecture et écriture de tags ID3 en Vala
septembre
2012
voici une nouvelle version de ma librairie. malheureusement, l’écriture ne comprend pas encore les images . dans une possible future version, j’arrive à gérer les différentes versions de tags ID3.
using System;
namespace TagLib
{
public interface SaveHandler
{
public abstract void Save();
}
public abstract class Frame
{
public Frame(Bytes bytes){}
public abstract Bytes Data {get;}
public abstract Bytes NextData {get;}
public abstract string Type {get;}
public abstract int Size {get;}
}
public abstract class Picture
{
public Picture(Bytes bytes){}
public abstract Bytes Buffer{get;}
public abstract string MimeType {get;}
public abstract Bytes Description {get;}
}
public class File
{
uint8[] data;
Bytes bytes;
string identifier;
TagLib.Tag tag;
Bytes raw_data;
int size;
File (string filename)
{
FileUtils.get_data(filename, out data);
bytes = new Bytes(data);
Encoding enc = new Encoding();
identifier = enc.GetString(bytes.slice(0,3));
}
public static File Create (string filename)
{
File file = new File(filename);
switch(file.identifier)
{
case "Ogg":
TagLibOgg.File f = new TagLibOgg.File(filename);
file.tag = f.Tag;
break;
case "ID3":
TagLibId3v2.File f = new TagLibId3v2.File(filename);
file.tag = f.Tag;
file.raw_data = f.RawData;
break;
}
return file;
}
public void Save ()
{
Encoding enc = new Encoding();
ByteArray array = new ByteArray();
ByteArray array2 = new ByteArray();
ByteArray array3 = new ByteArray();
if(tag.Title != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Title.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
size = array2.data.length;
stdout.printf (size.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(size-2));
array2.prepend (enc.GetBytes("TIT2").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Album != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Album.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TALB").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Artist != null){
stdout.printf (tag.Artist+"\n");
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Artist.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TPE1").get_data ());
}
array3.append (array2.data);
array.append (enc.GetBytes("ID3").get_data ());
array.append (new uint8[]{3,0,0});
array.append (Convert.ToBytes.from_integer(array3.data.length));
array.append (array3.data);
array.append (raw_data.get_data());
FileUtils.set_data ("test_de_merde.mp3",array.data);
}
public virtual Bytes RawData {get{return raw_data;}}
public virtual TagLib.Tag Tag {get{return tag;}}
}
public class Tag
{
string title;
string encoder;
string genre;
string artist;
string album;
TagLib.Picture picture;
public Tag(List frames){}
public virtual string Album {get{return album;} set{album = value;}}
public virtual string Artist {get{return artist;} set{artist = value;}}
public virtual string Genre {get{return genre;} set{genre = value;}}
public virtual string Encoder {get{return encoder;} set{encoder = value;}}
public virtual string Title {get{return title;} set{title = value;}}
public virtual TagLib.Picture Picture {get{return picture;} set{picture = value;}}
}
}
namespace TagLibOgg
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
public File(string filename)
{
base(filename);
uint8[] data;
FileUtils.get_data (filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
string s = "(Schaufenugget)";
int index = Encoding.IndexOf(bytes,s)+s.length;
int not = (int)bytes[index];
frame = new Frame(bytes.slice(index+4,bytes.length-1));
frames = new List();
for(int i=0; i<not; i++){
frames.append(frame);
frame = new Frame(frame.NextData);
if(frame.Type == "COVERART")break;
}
tag = new TagLibOgg.Tag(frames);
}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public Tag(List frames){
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames){
switch(frame.Type)
{
case "TITLE":
title = enc.GetString(frame.Data);
break;
case "ARTIST":
artist = enc.GetString(frame.Data);
break;
case "ENCODER":
encoder = enc.GetString(frame.Data);
break;
case "GENRE":
genre = enc.GetString(frame.Data);
break;
case "ALBUM":
album = enc.GetString(frame.Data);
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
int size;
string type;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
size = (int)bytes[0]+256*(int)bytes[1]+256*256*(int)bytes[2]+256*256*256*(int)bytes[3];
data = bytes.slice(4,4+size);
int i = Encoding.IndexOf(data,"=");
type = enc.GetString(data.slice(0,i));
data = data.slice(i+1,data.length);
next_data = bytes.slice(4+size,bytes.length-1);
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
}
namespace TagLibId3v2
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
int size;
uint8[] data;
Bytes raw_data;
public File(string filename)
{
base(filename);
FileUtils.get_data(filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
frame = new Frame(bytes.slice(10,bytes.length-1));
frames = new List();
while(frame.Type!="APIC")
{
stdout.printf (frame.Type+"\n");
if(frame.NextData.get_data ()[0]>200 || frame.NextData.get_data ()[0]==0)break;
frames.append(frame);
frame = new Frame(frame.NextData);
}
frames.append(frame);
raw_data = frame.NextData;
int version;
if(data[3]==4)version = 1;
else version = 3;
tag = new TagLibId3v2.Tag(frames,version);
}
public override Bytes RawData {get{return raw_data;}}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
TagLib.Picture picture;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public override TagLib.Picture Picture {get{return picture;} set{picture = value;}}
public Tag(List frames, int version)
{
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames)
{
switch(frame.Type){
case "TIT2":
title = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TENC":
encoder = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TCON":
genre = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TPE1":
artist = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TALB":
album = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "APIC":
picture = new TagLibId3v2.Picture(frame.Data);
break;
default:
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
string type;
int size;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
type = enc.GetString(bytes.slice(0,4));
size = (int)bytes[7]+256*(int)bytes[6]+256*256*(int)bytes[5]+256*256*256*(int)bytes[4];
data = bytes.slice(10,10+size);
next_data = bytes.slice(10+size,bytes.length-1);
stdout.printf (next_data[0].to_string()+" "+next_data[1].to_string()+" "+next_data[2].to_string()+" "+next_data[3].to_string()+"\n");
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
public class Picture : TagLib.Picture
{
int index;
Bytes description;
Bytes buffer;
string mime_type;
public Picture(Bytes bytes)
{
base(bytes);
for(int i=0; i4)return -1;
int a = 256*256*256*(int)bytes[0];
int b = 256*256*(int)bytes[1];
int c = 256*(int)bytes[2];
int d = (int)bytes[3];
int result = a+b+c+d;
return result;
}
public static int from_list_bytes(GLib.List list)
{
if(list.length()>4)return -1;
int a = 256*256*256*(int)list.nth_data(0);
int b = 256*256*(int)list.nth_data(1);
int c = 256*(int)list.nth_data(2);
int d = (int)list.nth_data(3);
int result = a+b+c+d;
return result;
}
} using System;
namespace TagLib
{
public interface SaveHandler
{
public abstract void Save();
}
public abstract class Frame
{
public Frame(Bytes bytes){}
public abstract Bytes Data {get;}
public abstract Bytes NextData {get;}
public abstract string Type {get;}
public abstract int Size {get;}
}
public abstract class Picture
{
public Picture(Bytes bytes){}
public abstract Bytes Buffer{get;}
public abstract string MimeType {get;}
public abstract Bytes Description {get;}
}
public class File
{
uint8[] data;
Bytes bytes;
string identifier;
TagLib.Tag tag;
Bytes raw_data;
int size;
File (string filename)
{
FileUtils.get_data(filename, out data);
bytes = new Bytes(data);
Encoding enc = new Encoding();
identifier = enc.GetString(bytes.slice(0,3));
}
public static File Create (string filename)
{
File file = new File(filename);
switch(file.identifier)
{
case "Ogg":
TagLibOgg.File f = new TagLibOgg.File(filename);
file.tag = f.Tag;
break;
case "ID3":
TagLibId3v2.File f = new TagLibId3v2.File(filename);
file.tag = f.Tag;
file.raw_data = f.RawData;
break;
}
return file;
}
public void Save ()
{
Encoding enc = new Encoding();
ByteArray array = new ByteArray();
ByteArray array2 = new ByteArray();
ByteArray array3 = new ByteArray();
if(tag.Title != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Title.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
size = array2.data.length;
stdout.printf (size.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(size-2));
array2.prepend (enc.GetBytes("TIT2").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Album != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Album.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TALB").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Artist != null){
stdout.printf (tag.Artist+"\n");
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Artist.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TPE1").get_data ());
}
array3.append (array2.data);
array.append (enc.GetBytes("ID3").get_data ());
array.append (new uint8[]{3,0,0});
array.append (Convert.ToBytes.from_integer(array3.data.length));
array.append (array3.data);
array.append (raw_data.get_data());
FileUtils.set_data ("test_de_merde.mp3",array.data);
}
public virtual Bytes RawData {get{return raw_data;}}
public virtual TagLib.Tag Tag {get{return tag;}}
}
public class Tag
{
string title;
string encoder;
string genre;
string artist;
string album;
TagLib.Picture picture;
public Tag(List frames){}
public virtual string Album {get{return album;} set{album = value;}}
public virtual string Artist {get{return artist;} set{artist = value;}}
public virtual string Genre {get{return genre;} set{genre = value;}}
public virtual string Encoder {get{return encoder;} set{encoder = value;}}
public virtual string Title {get{return title;} set{title = value;}}
public virtual TagLib.Picture Picture {get{return picture;} set{picture = value;}}
}
}
namespace TagLibOgg
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
public File(string filename)
{
base(filename);
uint8[] data;
FileUtils.get_data (filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
string s = "(Schaufenugget)";
int index = Encoding.IndexOf(bytes,s)+s.length;
int not = (int)bytes[index];
frame = new Frame(bytes.slice(index+4,bytes.length-1));
frames = new List();
for(int i=0; i<not; i++){
frames.append(frame);
frame = new Frame(frame.NextData);
if(frame.Type == "COVERART")break;
}
tag = new TagLibOgg.Tag(frames);
}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public Tag(List frames){
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames){
switch(frame.Type)
{
case "TITLE":
title = enc.GetString(frame.Data);
break;
case "ARTIST":
artist = enc.GetString(frame.Data);
break;
case "ENCODER":
encoder = enc.GetString(frame.Data);
break;
case "GENRE":
genre = enc.GetString(frame.Data);
break;
case "ALBUM":
album = enc.GetString(frame.Data);
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
int size;
string type;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
size = (int)bytes[0]+256*(int)bytes[1]+256*256*(int)bytes[2]+256*256*256*(int)bytes[3];
data = bytes.slice(4,4+size);
int i = Encoding.IndexOf(data,"=");
type = enc.GetString(data.slice(0,i));
data = data.slice(i+1,data.length);
next_data = bytes.slice(4+size,bytes.length-1);
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
}
namespace TagLibId3v2
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
int size;
uint8[] data;
Bytes raw_data;
public File(string filename)
{
base(filename);
FileUtils.get_data(filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
frame = new Frame(bytes.slice(10,bytes.length-1));
frames = new List();
while(frame.Type!="APIC")
{
stdout.printf (frame.Type+"\n");
if(frame.NextData.get_data ()[0]>200 || frame.NextData.get_data ()[0]==0)break;
frames.append(frame);
frame = new Frame(frame.NextData);
}
frames.append(frame);
raw_data = frame.NextData;
int version;
if(data[3]==4)version = 1;
else version = 3;
tag = new TagLibId3v2.Tag(frames,version);
}
public override Bytes RawData {get{return raw_data;}}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
TagLib.Picture picture;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public override TagLib.Picture Picture {get{return picture;} set{picture = value;}}
public Tag(List frames, int version)
{
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames)
{
switch(frame.Type){
case "TIT2":
title = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TENC":
encoder = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TCON":
genre = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TPE1":
artist = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TALB":
album = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "APIC":
picture = new TagLibId3v2.Picture(frame.Data);
break;
default:
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
string type;
int size;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
type = enc.GetString(bytes.slice(0,4));
size = (int)bytes[7]+256*(int)bytes[6]+256*256*(int)bytes[5]+256*256*256*(int)bytes[4];
data = bytes.slice(10,10+size);
next_data = bytes.slice(10+size,bytes.length-1);
stdout.printf (next_data[0].to_string()+" "+next_data[1].to_string()+" "+next_data[2].to_string()+" "+next_data[3].to_string()+"\n");
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
public class Picture : TagLib.Picture
{
int index;
Bytes description;
Bytes buffer;
string mime_type;
public Picture(Bytes bytes)
{
base(bytes);
for(int i=0; i4)return -1;
int a = 256*256*256*(int)bytes[0];
int b = 256*256*(int)bytes[1];
int c = 256*(int)bytes[2];
int d = (int)bytes[3];
int result = a+b+c+d;
return result;
}
public static int from_list_bytes(GLib.List list)
{
if(list.length()>4)return -1;
int a = 256*256*256*(int)list.nth_data(0);
int b = 256*256*(int)list.nth_data(1);
int c = 256*(int)list.nth_data(2);
int d = (int)list.nth_data(3);
int result = a+b+c+d;
return result;
}
}
public class ToBytes
{
public static uint8[] from_integer(int number)
{
int a = number / (256*256*256);
number -= a*256*256*256;
int b = number / (256*256);
number -= b*256*256;
int c = number / 256;
number -= c*256;
uint8[] u = new uint8[4];
u[0] = (uint8)a;
u[1] = (uint8)b;
u[2] = (uint8)c;
u[3] = (uint8)number;
return u;
}
}
}
public class Encoding
{
public Encoding(){}
public string GetString(Bytes bytes)
{
string s = "";
foreach(uint8 u in bytes.get_data())
if(u!=0)s += ((char)u).to_string();
return s;
}
public Bytes GetBytes(string str)
{
uint8[] u = new uint8[str.length];
for(int i=0; i<str.length; i++)
u[i] = (uint8)str.get_char(i);
Bytes bytes = new Bytes(u);
return bytes;
}
public static int IndexOf(Bytes bytes, string str)
{
Encoding enc = new Encoding();
Bytes b = enc.GetBytes(str);
for(int i = 0; i < bytes.length-1-b.length; i++){
if(enc.GetString(bytes.slice(i,i+b.length))==str){
return i;
}
}
return -1;
}
}
}
public class ToBytes
{
public static uint8[] from_integer(int number)
{
int a = number / (256*256*256);
number -= a*256*256*256;
int b = number / (256*256);
number -= b*256*256;
int c = number / 256;
number -= c*256;
uint8[] u = new uint8[4];
u[0] = (uint8)a;
u[1] = (uint8)b;
u[2] = (uint8)c;
u[3] = (uint8)number;
return u;
}
}
}
public class Encoding
{
public Encoding(){}
public string GetString(Bytes bytes)
{
string s = "";
foreach(uint8 u in bytes.get_data())
if(u!=0)s += ((char)u).to_string();
return s;
}
public Bytes GetBytes(string str)
{
uint8[] u = new uint8[str.length];
for(int i=0; i<str.length; i++)
u[i] = (uint8)str.get_char(i);
Bytes bytes = new Bytes(u);
return bytes;
}
public static int IndexOf(Bytes bytes, string str)
{
Encoding enc = new Encoding();
Bytes b = enc.GetBytes(str);
for(int i = 0; i < bytes.length-1-b.length; i++){
if(enc.GetString(bytes.slice(i,i+b.length))==str){
return i;
}
}
return -1;
}
}
}
namespace TagLib
{
public interface SaveHandler
{
public abstract void Save();
}
public abstract class Frame
{
public Frame(Bytes bytes){}
public abstract Bytes Data {get;}
public abstract Bytes NextData {get;}
public abstract string Type {get;}
public abstract int Size {get;}
}
public abstract class Picture
{
public Picture(Bytes bytes){}
public abstract Bytes Buffer{get;}
public abstract string MimeType {get;}
public abstract Bytes Description {get;}
}
public class File
{
uint8[] data;
Bytes bytes;
string identifier;
TagLib.Tag tag;
Bytes raw_data;
int size;
File (string filename)
{
FileUtils.get_data(filename, out data);
bytes = new Bytes(data);
Encoding enc = new Encoding();
identifier = enc.GetString(bytes.slice(0,3));
}
public static File Create (string filename)
{
File file = new File(filename);
switch(file.identifier)
{
case "Ogg":
TagLibOgg.File f = new TagLibOgg.File(filename);
file.tag = f.Tag;
break;
case "ID3":
TagLibId3v2.File f = new TagLibId3v2.File(filename);
file.tag = f.Tag;
file.raw_data = f.RawData;
break;
}
return file;
}
public void Save ()
{
Encoding enc = new Encoding();
ByteArray array = new ByteArray();
ByteArray array2 = new ByteArray();
ByteArray array3 = new ByteArray();
if(tag.Title != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Title.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
size = array2.data.length;
stdout.printf (size.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(size-2));
array2.prepend (enc.GetBytes("TIT2").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Album != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Album.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TALB").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Artist != null){
stdout.printf (tag.Artist+"\n");
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Artist.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TPE1").get_data ());
}
array3.append (array2.data);
array.append (enc.GetBytes("ID3").get_data ());
array.append (new uint8[]{3,0,0});
array.append (Convert.ToBytes.from_integer(array3.data.length));
array.append (array3.data);
array.append (raw_data.get_data());
FileUtils.set_data ("test_de_merde.mp3",array.data);
}
public virtual Bytes RawData {get{return raw_data;}}
public virtual TagLib.Tag Tag {get{return tag;}}
}
public class Tag
{
string title;
string encoder;
string genre;
string artist;
string album;
TagLib.Picture picture;
public Tag(List frames){}
public virtual string Album {get{return album;} set{album = value;}}
public virtual string Artist {get{return artist;} set{artist = value;}}
public virtual string Genre {get{return genre;} set{genre = value;}}
public virtual string Encoder {get{return encoder;} set{encoder = value;}}
public virtual string Title {get{return title;} set{title = value;}}
public virtual TagLib.Picture Picture {get{return picture;} set{picture = value;}}
}
}
namespace TagLibOgg
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
public File(string filename)
{
base(filename);
uint8[] data;
FileUtils.get_data (filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
string s = "(Schaufenugget)";
int index = Encoding.IndexOf(bytes,s)+s.length;
int not = (int)bytes[index];
frame = new Frame(bytes.slice(index+4,bytes.length-1));
frames = new List();
for(int i=0; i<not; i++){
frames.append(frame);
frame = new Frame(frame.NextData);
if(frame.Type == "COVERART")break;
}
tag = new TagLibOgg.Tag(frames);
}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public Tag(List frames){
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames){
switch(frame.Type)
{
case "TITLE":
title = enc.GetString(frame.Data);
break;
case "ARTIST":
artist = enc.GetString(frame.Data);
break;
case "ENCODER":
encoder = enc.GetString(frame.Data);
break;
case "GENRE":
genre = enc.GetString(frame.Data);
break;
case "ALBUM":
album = enc.GetString(frame.Data);
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
int size;
string type;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
size = (int)bytes[0]+256*(int)bytes[1]+256*256*(int)bytes[2]+256*256*256*(int)bytes[3];
data = bytes.slice(4,4+size);
int i = Encoding.IndexOf(data,"=");
type = enc.GetString(data.slice(0,i));
data = data.slice(i+1,data.length);
next_data = bytes.slice(4+size,bytes.length-1);
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
}
namespace TagLibId3v2
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
int size;
uint8[] data;
Bytes raw_data;
public File(string filename)
{
base(filename);
FileUtils.get_data(filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
frame = new Frame(bytes.slice(10,bytes.length-1));
frames = new List();
while(frame.Type!="APIC")
{
stdout.printf (frame.Type+"\n");
if(frame.NextData.get_data ()[0]>200 || frame.NextData.get_data ()[0]==0)break;
frames.append(frame);
frame = new Frame(frame.NextData);
}
frames.append(frame);
raw_data = frame.NextData;
int version;
if(data[3]==4)version = 1;
else version = 3;
tag = new TagLibId3v2.Tag(frames,version);
}
public override Bytes RawData {get{return raw_data;}}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
TagLib.Picture picture;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public override TagLib.Picture Picture {get{return picture;} set{picture = value;}}
public Tag(List frames, int version)
{
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames)
{
switch(frame.Type){
case "TIT2":
title = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TENC":
encoder = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TCON":
genre = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TPE1":
artist = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TALB":
album = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "APIC":
picture = new TagLibId3v2.Picture(frame.Data);
break;
default:
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
string type;
int size;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
type = enc.GetString(bytes.slice(0,4));
size = (int)bytes[7]+256*(int)bytes[6]+256*256*(int)bytes[5]+256*256*256*(int)bytes[4];
data = bytes.slice(10,10+size);
next_data = bytes.slice(10+size,bytes.length-1);
stdout.printf (next_data[0].to_string()+" "+next_data[1].to_string()+" "+next_data[2].to_string()+" "+next_data[3].to_string()+"\n");
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
public class Picture : TagLib.Picture
{
int index;
Bytes description;
Bytes buffer;
string mime_type;
public Picture(Bytes bytes)
{
base(bytes);
for(int i=0; i4)return -1;
int a = 256*256*256*(int)bytes[0];
int b = 256*256*(int)bytes[1];
int c = 256*(int)bytes[2];
int d = (int)bytes[3];
int result = a+b+c+d;
return result;
}
public static int from_list_bytes(GLib.List list)
{
if(list.length()>4)return -1;
int a = 256*256*256*(int)list.nth_data(0);
int b = 256*256*(int)list.nth_data(1);
int c = 256*(int)list.nth_data(2);
int d = (int)list.nth_data(3);
int result = a+b+c+d;
return result;
}
} using System;
namespace TagLib
{
public interface SaveHandler
{
public abstract void Save();
}
public abstract class Frame
{
public Frame(Bytes bytes){}
public abstract Bytes Data {get;}
public abstract Bytes NextData {get;}
public abstract string Type {get;}
public abstract int Size {get;}
}
public abstract class Picture
{
public Picture(Bytes bytes){}
public abstract Bytes Buffer{get;}
public abstract string MimeType {get;}
public abstract Bytes Description {get;}
}
public class File
{
uint8[] data;
Bytes bytes;
string identifier;
TagLib.Tag tag;
Bytes raw_data;
int size;
File (string filename)
{
FileUtils.get_data(filename, out data);
bytes = new Bytes(data);
Encoding enc = new Encoding();
identifier = enc.GetString(bytes.slice(0,3));
}
public static File Create (string filename)
{
File file = new File(filename);
switch(file.identifier)
{
case "Ogg":
TagLibOgg.File f = new TagLibOgg.File(filename);
file.tag = f.Tag;
break;
case "ID3":
TagLibId3v2.File f = new TagLibId3v2.File(filename);
file.tag = f.Tag;
file.raw_data = f.RawData;
break;
}
return file;
}
public void Save ()
{
Encoding enc = new Encoding();
ByteArray array = new ByteArray();
ByteArray array2 = new ByteArray();
ByteArray array3 = new ByteArray();
if(tag.Title != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Title.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
size = array2.data.length;
stdout.printf (size.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(size-2));
array2.prepend (enc.GetBytes("TIT2").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Album != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Album.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TALB").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Artist != null){
stdout.printf (tag.Artist+"\n");
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Artist.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TPE1").get_data ());
}
array3.append (array2.data);
array.append (enc.GetBytes("ID3").get_data ());
array.append (new uint8[]{3,0,0});
array.append (Convert.ToBytes.from_integer(array3.data.length));
array.append (array3.data);
array.append (raw_data.get_data());
FileUtils.set_data ("test_de_merde.mp3",array.data);
}
public virtual Bytes RawData {get{return raw_data;}}
public virtual TagLib.Tag Tag {get{return tag;}}
}
public class Tag
{
string title;
string encoder;
string genre;
string artist;
string album;
TagLib.Picture picture;
public Tag(List frames){}
public virtual string Album {get{return album;} set{album = value;}}
public virtual string Artist {get{return artist;} set{artist = value;}}
public virtual string Genre {get{return genre;} set{genre = value;}}
public virtual string Encoder {get{return encoder;} set{encoder = value;}}
public virtual string Title {get{return title;} set{title = value;}}
public virtual TagLib.Picture Picture {get{return picture;} set{picture = value;}}
}
}
namespace TagLibOgg
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
public File(string filename)
{
base(filename);
uint8[] data;
FileUtils.get_data (filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
string s = "(Schaufenugget)";
int index = Encoding.IndexOf(bytes,s)+s.length;
int not = (int)bytes[index];
frame = new Frame(bytes.slice(index+4,bytes.length-1));
frames = new List();
for(int i=0; i<not; i++){
frames.append(frame);
frame = new Frame(frame.NextData);
if(frame.Type == "COVERART")break;
}
tag = new TagLibOgg.Tag(frames);
}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public Tag(List frames){
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames){
switch(frame.Type)
{
case "TITLE":
title = enc.GetString(frame.Data);
break;
case "ARTIST":
artist = enc.GetString(frame.Data);
break;
case "ENCODER":
encoder = enc.GetString(frame.Data);
break;
case "GENRE":
genre = enc.GetString(frame.Data);
break;
case "ALBUM":
album = enc.GetString(frame.Data);
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
int size;
string type;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
size = (int)bytes[0]+256*(int)bytes[1]+256*256*(int)bytes[2]+256*256*256*(int)bytes[3];
data = bytes.slice(4,4+size);
int i = Encoding.IndexOf(data,"=");
type = enc.GetString(data.slice(0,i));
data = data.slice(i+1,data.length);
next_data = bytes.slice(4+size,bytes.length-1);
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
}
namespace TagLibId3v2
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
int size;
uint8[] data;
Bytes raw_data;
public File(string filename)
{
base(filename);
FileUtils.get_data(filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
frame = new Frame(bytes.slice(10,bytes.length-1));
frames = new List();
while(frame.Type!="APIC")
{
stdout.printf (frame.Type+"\n");
if(frame.NextData.get_data ()[0]>200 || frame.NextData.get_data ()[0]==0)break;
frames.append(frame);
frame = new Frame(frame.NextData);
}
frames.append(frame);
raw_data = frame.NextData;
int version;
if(data[3]==4)version = 1;
else version = 3;
tag = new TagLibId3v2.Tag(frames,version);
}
public override Bytes RawData {get{return raw_data;}}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
TagLib.Picture picture;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public override TagLib.Picture Picture {get{return picture;} set{picture = value;}}
public Tag(List frames, int version)
{
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames)
{
switch(frame.Type){
case "TIT2":
title = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TENC":
encoder = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TCON":
genre = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TPE1":
artist = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TALB":
album = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "APIC":
picture = new TagLibId3v2.Picture(frame.Data);
break;
default:
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
string type;
int size;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
type = enc.GetString(bytes.slice(0,4));
size = (int)bytes[7]+256*(int)bytes[6]+256*256*(int)bytes[5]+256*256*256*(int)bytes[4];
data = bytes.slice(10,10+size);
next_data = bytes.slice(10+size,bytes.length-1);
stdout.printf (next_data[0].to_string()+" "+next_data[1].to_string()+" "+next_data[2].to_string()+" "+next_data[3].to_string()+"\n");
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
public class Picture : TagLib.Picture
{
int index;
Bytes description;
Bytes buffer;
string mime_type;
public Picture(Bytes bytes)
{
base(bytes);
for(int i=0; i4)return -1;
int a = 256*256*256*(int)bytes[0];
int b = 256*256*(int)bytes[1];
int c = 256*(int)bytes[2];
int d = (int)bytes[3];
int result = a+b+c+d;
return result;
}
public static int from_list_bytes(GLib.List list)
{
if(list.length()>4)return -1;
int a = 256*256*256*(int)list.nth_data(0);
int b = 256*256*(int)list.nth_data(1);
int c = 256*(int)list.nth_data(2);
int d = (int)list.nth_data(3);
int result = a+b+c+d;
return result;
}
}
public class ToBytes
{
public static uint8[] from_integer(int number)
{
int a = number / (256*256*256);
number -= a*256*256*256;
int b = number / (256*256);
number -= b*256*256;
int c = number / 256;
number -= c*256;
uint8[] u = new uint8[4];
u[0] = (uint8)a;
u[1] = (uint8)b;
u[2] = (uint8)c;
u[3] = (uint8)number;
return u;
}
}
}
public class Encoding
{
public Encoding(){}
public string GetString(Bytes bytes)
{
string s = "";
foreach(uint8 u in bytes.get_data())
if(u!=0)s += ((char)u).to_string();
return s;
}
public Bytes GetBytes(string str)
{
uint8[] u = new uint8[str.length];
for(int i=0; i<str.length; i++)
u[i] = (uint8)str.get_char(i);
Bytes bytes = new Bytes(u);
return bytes;
}
public static int IndexOf(Bytes bytes, string str)
{
Encoding enc = new Encoding();
Bytes b = enc.GetBytes(str);
for(int i = 0; i < bytes.length-1-b.length; i++){
if(enc.GetString(bytes.slice(i,i+b.length))==str){
return i;
}
}
return -1;
}
}
}
public class ToBytes
{
public static uint8[] from_integer(int number)
{
int a = number / (256*256*256);
number -= a*256*256*256;
int b = number / (256*256);
number -= b*256*256;
int c = number / 256;
number -= c*256;
uint8[] u = new uint8[4];
u[0] = (uint8)a;
u[1] = (uint8)b;
u[2] = (uint8)c;
u[3] = (uint8)number;
return u;
}
}
}
public class Encoding
{
public Encoding(){}
public string GetString(Bytes bytes)
{
string s = "";
foreach(uint8 u in bytes.get_data())
if(u!=0)s += ((char)u).to_string();
return s;
}
public Bytes GetBytes(string str)
{
uint8[] u = new uint8[str.length];
for(int i=0; i<str.length; i++)
u[i] = (uint8)str.get_char(i);
Bytes bytes = new Bytes(u);
return bytes;
}
public static int IndexOf(Bytes bytes, string str)
{
Encoding enc = new Encoding();
Bytes b = enc.GetBytes(str);
for(int i = 0; i < bytes.length-1-b.length; i++){
if(enc.GetString(bytes.slice(i,i+b.length))==str){
return i;
}
}
return -1;
}
}
}