shithub: zuke

ref: 74e64942e26b41965b6921d40d5174eeab41b048
dir: /plist.h/

View raw version
/* Playlist begins with "# x\n" where x is the total number of records.
 * Each record begins with "# x y\n" where x is record index, y is its size in bytes.
 * Records are sorted according to mkplist.c:/^cmpmeta function.
 * This makes it somewhat easy to just load the whole playlist into memory once,
 * map all (Meta*)->... fields to it, saving on memory allocations, and using the same
 * data to provide poor's man full text searching.
 * Encoding: mkplist.c:/^printmeta/.
 * Decoding: zuke.c:/^readplist/.
 */
enum
{
	Precord='#',

	Palbum=			'a',
	Partist=		'A',
	Pdate=			'd',
	Pduration=		'D',
	Pimage=			'i',
	Ptitle=			't',
	Ptrack=			'T',
	Ppath=			'p',
	Pfilefmt=		'f',

	/* unused */
	Pchannels=		'c',
	Psamplerate=	's',

	Maxartist=16, /* max artists for a track */
};

typedef struct Meta Meta;

struct Meta
{
	char *artist[Maxartist];
	char *album;
	char *title;
	char *date;
	char *track;
	char *path;
	char *imagefmt;
	char *filefmt;
	uvlong duration;
	int numartist;
	int imageoffset;
	int imagesize;
	int imagereader; /* non-zero if a special reader required */
};

static void
printmeta(Biobuf *b, Meta *m)
{
	int i;

	Bprint(b, "%c %s\n%c %s\n", Ppath, m->path, Pfilefmt, m->filefmt);
	for(i = 0; i < m->numartist; i++)
		Bprint(b, "%c %s\n", Partist, m->artist[i]);
	if(m->album != nil)
		Bprint(b, "%c %s\n", Palbum, m->album);
	if(m->title != nil)
		Bprint(b, "%c %s\n", Ptitle, m->title);
	if(m->date != nil)
		Bprint(b, "%c %s\n", Pdate, m->date);
	if(m->track != nil)
		Bprint(b, "%c %s\n", Ptrack, m->track);
	if(m->duration > 0)
		Bprint(b, "%c %llud\n", Pduration, m->duration);
	if(m->imagesize > 0)
		Bprint(b, "%c %d %d %d %s\n", Pimage, m->imageoffset, m->imagesize, m->imagereader, m->imagefmt);
	Bprint(b, "\n");
}