123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586 |
- /*
- ** Copyright © 2003-2014 Winamp SA
- **
- ** This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held
- ** liable for any damages arising from the use of this software.
- **
- ** Permission is granted to anyone to use this software for any purpose, including commercial applications, and to
- ** alter it and redistribute it freely, subject to the following restrictions:
- **
- ** 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
- ** If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
- **
- ** 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
- **
- ** 3. This notice may not be removed or altered from any source distribution.
- **
- */
- #include <windows.h>
- #include "ml.h"
- void freeRecord(itemRecord *p)
- {
- if (p)
- {
- free(p->title);
- free( p->artist );
- free( p->ext );
- free(p->comment);
- free(p->album);
- free(p->genre);
- free(p->filename);
- if (p->extended_info)
- {
- for (int x = 0; p->extended_info[x]; x ++)
- free(p->extended_info[x]);
- free(p->extended_info);
- p->extended_info = 0;
- }
- }
- }
- void freeRecordList(itemRecordList *obj)
- {
- if (obj)
- {
- emptyRecordList(obj);
- free(obj->Items);
- obj->Items=0;
- obj->Alloc=obj->Size=0;
- }
- }
- void emptyRecordList(itemRecordList *obj)
- {
- if (obj)
- {
- itemRecord *p=obj->Items;
- while (obj->Size-->0)
- {
- freeRecord(p);
- p++;
- }
- obj->Size=0;
- }
- }
- void allocRecordList(itemRecordList *obj, int newsize, int granularity)
- {
- if (newsize < obj->Alloc || newsize < obj->Size) return;
- int old_Alloc = obj->Alloc;
- obj->Alloc=newsize+granularity;
- itemRecord *data = (itemRecord*)realloc(obj->Items, sizeof(itemRecord) * obj->Alloc);
- if (!data)
- {
- data = (itemRecord*)malloc(sizeof(itemRecord) * obj->Alloc);
- if (data)
- {
- memcpy(data, obj->Items, sizeof(itemRecord) * old_Alloc);
- free(obj->Items);
- obj->Items = data;
- }
- else
- obj->Alloc = old_Alloc;
- }
- else
- obj->Items = data;
- if (!old_Alloc) memset(data, 0, sizeof(itemRecordW) * obj->Alloc);
- if (!obj->Items) obj->Alloc = 0;
- }
- void compactRecordList(itemRecordListW *obj)
- {
- if (obj->Size && obj->Size < obj->Alloc - 1024)
- {
- size_t old_Alloc = obj->Size;
- obj->Alloc = obj->Size;
- itemRecordW *data = (itemRecordW *)realloc(obj->Items, sizeof(itemRecordW) * obj->Alloc);
- if (!data)
- {
- data = (itemRecordW *)malloc(sizeof(itemRecordW) * obj->Alloc);
- if (data)
- {
- memcpy(data, obj->Items, sizeof(itemRecordW) * old_Alloc);
- free(obj->Items);
- obj->Items = data;
- }
- else
- obj->Alloc = (int)old_Alloc;
- }
- else
- obj->Items = data;
- }
- }
- void copyRecord(itemRecord *out, const itemRecord *in)
- {
- #define COPYSTR(FOO) out->FOO = in->FOO ? _strdup(in->FOO) : 0;
- COPYSTR(filename)
- COPYSTR( title )
- COPYSTR( ext )
- COPYSTR(album)
- COPYSTR(artist)
- COPYSTR(comment)
- COPYSTR(genre)
- out->year=in->year;
- out->track=in->track;
- out->length=in->length;
- #undef COPYSTR
- out->extended_info=0;
- if (in->extended_info)
- {
- for (int y = 0; in->extended_info[y]; y ++)
- {
- char *p=in->extended_info[y];
- if (*p) setRecordExtendedItem(out,p,p+strlen(p)+1);
- }
- }
- }
- void copyRecordList(itemRecordList *out, const itemRecordList *in)
- {
- allocRecordList(out,out->Size+in->Size,0);
- if (!out->Items) return;
- for (int x = 0; x < in->Size; x ++)
- {
- copyRecord(&out->Items[out->Size++],&in->Items[x]);
- }
- }
- char *getRecordExtendedItem(const itemRecord *item, const char *name)
- {
- if (item->extended_info)
- {
- for (int x = 0; item->extended_info[x]; x ++)
- {
- if (!_stricmp(item->extended_info[x],name))
- return item->extended_info[x]+strlen(name)+1;
- }
- }
- return NULL;
- }
- void setRecordExtendedItem(itemRecord *item, const char *name, char *value)
- {
- int x=0;
- if (item->extended_info)
- {
- for (x = 0; item->extended_info[x]; x ++)
- {
- if (!_stricmp(item->extended_info[x],name))
- {
- size_t name_len = strlen(name), value_len = strlen(value);
- if (value_len>strlen(item->extended_info[x]+name_len+1))
- {
- free(item->extended_info[x]);
- item->extended_info[x]=(char*)malloc(name_len+value_len+2);
- }
- strncpy(item->extended_info[x], name, name_len);
- strncpy(item->extended_info[x]+strlen(name)+1, value, value_len);
- return;
- }
- }
- }
- // x=number of valid items.
- char **data = (char**)realloc(item->extended_info,sizeof(char*) * (x+2));
- if (data)
- {
- // if we could allocate then add, otherwise we'll have to skip
- item->extended_info = data;
- size_t name_len = strlen(name), value_len = strlen(value);
- item->extended_info[x]=(char*)malloc(name_len+value_len+2);
- strncpy(item->extended_info[x], name, name_len);
- strncpy(item->extended_info[x]+name_len+1, value, value_len);
- item->extended_info[x+1]=0;
- }
- else
- {
- data=(char**)_aligned_malloc(sizeof(char*) * (x+2), 16);
- if (data)
- {
- memcpy(data, item->extended_info, sizeof(char*) * x);
- free(item->extended_info);
- // if we could allocate then add, otherwise we'll have to skip
- item->extended_info = data;
- size_t name_len = strlen(name), value_len = strlen(value);
- item->extended_info[x]=(char*)malloc(name_len+value_len+2);
- strncpy(item->extended_info[x], name, name_len);
- strncpy(item->extended_info[x]+name_len+1, value, value_len);
-
- item->extended_info[x+1]=0;
- }
- }
- }
- /*
- ----------------------------------
- wide version starts here
- ----------------------------------
- */
- void freeRecord(itemRecordW *p)
- {
- if (p)
- {
- free(p->title);
- free(p->artist);
- free(p->comment);
- free(p->album);
- free(p->genre);
- free(p->filename);
- free(p->albumartist);
- free(p->replaygain_album_gain);
- free(p->replaygain_track_gain);
- free(p->publisher);
- free(p->composer);
- if (p->extended_info)
- {
- for (int x = 0; p->extended_info[x].key; x ++)
- {
- free(p->extended_info[x].key);
- free(p->extended_info[x].value);
- }
- free(p->extended_info);
- p->extended_info = 0;
- }
- }
- }
- void freeRecordList(itemRecordListW *obj)
- {
- if (obj)
- {
- emptyRecordList(obj);
- free(obj->Items);
- obj->Items=0;
- obj->Alloc=obj->Size=0;
- }
- }
- void emptyRecordList(itemRecordListW *obj)
- {
- if (obj)
- {
- itemRecordW *p=obj->Items;
- while (obj->Size-->0)
- {
- freeRecord(p);
- p++;
- }
- obj->Size=0;
- }
- }
- void allocRecordList(itemRecordListW *obj, int newsize, int granularity)
- {
- if (newsize < obj->Alloc || newsize < obj->Size) return;
- int old_Alloc = obj->Alloc;
- obj->Alloc=newsize+granularity;
- itemRecordW *data = (itemRecordW*)realloc(obj->Items,sizeof(itemRecordW)*obj->Alloc);
- if (!data)
- {
- data = (itemRecordW*)malloc(sizeof(itemRecordW) * obj->Alloc);
- if (data)
- {
- memcpy(data, obj->Items, sizeof(itemRecordW) * obj->Alloc);
- free(obj->Items);
- obj->Items = data;
- }
- else
- obj->Alloc = old_Alloc;
- }
- else
- obj->Items = data;
- if (!old_Alloc) memset(data, 0, sizeof(itemRecordW) * obj->Alloc);
- if (!obj->Items) obj->Alloc = 0;
- }
- void copyRecord(itemRecordW *out, const itemRecordW *in)
- {
- #define COPYSTR(FOO) out->FOO = in->FOO ? _wcsdup(in->FOO) : 0;
- #define COPY(FOO) out->FOO = in->FOO;
- COPYSTR(filename);
- COPYSTR(title);
- COPYSTR(album);
- COPYSTR(artist);
- COPYSTR(comment);
- COPYSTR(genre);
- COPYSTR(albumartist);
- COPYSTR(replaygain_album_gain);
- COPYSTR(replaygain_track_gain);
- COPYSTR(publisher);
- COPYSTR(composer);
- COPY(year);
- COPY(track);
- COPY(tracks);
- COPY(length);
- COPY(rating);
- COPY(playcount);
- COPY(lastplay);
- COPY(lastupd);
- COPY(filetime);
- COPY(filesize);
- COPY(bitrate);
- COPY(type);
- COPY(disc);
- COPY(discs);
- COPY(bpm);
- COPYSTR(category);
- #undef COPYSTR
- out->extended_info=0;
- if (in->extended_info)
- {
- for (int y = 0; in->extended_info[y].key; y ++)
- {
- setRecordExtendedItem(out,in->extended_info[y].key,in->extended_info[y].value);
- }
- }
- }
- void copyRecordList(itemRecordListW *out, const itemRecordListW *in)
- {
- allocRecordList(out,out->Size+in->Size,0);
- if (!out->Items) return;
- for (int x = 0; x < in->Size; x ++)
- {
- copyRecord(&out->Items[out->Size++],&in->Items[x]);
- }
- }
- wchar_t *getRecordExtendedItem(const itemRecordW *item, const wchar_t *name)
- {
- if (item->extended_info)
- {
- for (size_t x = 0; item->extended_info[x].key; x ++)
- {
- if (!_wcsicmp(item->extended_info[x].key,name))
- return item->extended_info[x].value;
- }
- }
- return NULL;
- }
- wchar_t *getRecordExtendedItem_fast(const itemRecordW *item, const wchar_t *name)
- {
- if (item->extended_info)
- {
- for (size_t x = 0; item->extended_info[x].key; x ++)
- {
- if (item->extended_info[x].key == name)
- return item->extended_info[x].value;
- }
- }
- return NULL;
- }
- void setRecordExtendedItem(itemRecordW *item, const wchar_t *name, const wchar_t *value)
- {
- size_t x=0;
- if (item->extended_info) for (x = 0; item->extended_info[x].key; x ++)
- {
- if (!_wcsicmp(item->extended_info[x].key,name))
- {
- free(item->extended_info[x].value);
- item->extended_info[x].value = _wcsdup(value);
- return;
- }
- }
- // x=number of valid items.
- extendedInfoW *data = (extendedInfoW *)realloc(item->extended_info, sizeof(extendedInfoW) * (x+2));
- if (data)
- {
- item->extended_info = data;
- item->extended_info[x].key = _wcsdup(name);
- item->extended_info[x].value = _wcsdup(value);
- item->extended_info[x+1].key=0;
- item->extended_info[x+1].value=0;
- }
- else
- {
- data=(extendedInfoW *)_aligned_malloc(sizeof(extendedInfoW) * (x+2), 16);
- if (data)
- {
- item->extended_info=data;
-
- item->extended_info[x].key = _wcsdup(name);
- item->extended_info[x].value = _wcsdup(value);
-
- item->extended_info[x+1].key=0;
- item->extended_info[x+1].value=0;
- }
- }
- }
- // this version assumes that the 'name' won't already be in the itemRecord
- void setRecordExtendedItem_fast(itemRecordW *item, const wchar_t *name, const wchar_t *value)
- {
- int x=0;
- if (item->extended_info)
- {
- for (x = 0; item->extended_info[x].key; x ++)
- {
- }
- }
- // x=number of valid items.
- extendedInfoW *data=(extendedInfoW *)_aligned_realloc(item->extended_info,sizeof(extendedInfoW) * (x+2), 16);
- if (data)
- {
- item->extended_info=data;
- item->extended_info[x].key = _wcsdup(name);
- item->extended_info[x].value = _wcsdup(value);
- item->extended_info[x+1].key=0;
- item->extended_info[x+1].value=0;
- }
- else
- {
- data=(extendedInfoW *)_aligned_malloc(sizeof(extendedInfoW) * (x+2), 16);
- if (data)
- {
- item->extended_info=data;
-
- item->extended_info[x].key = _wcsdup(name);
- item->extended_info[x].value = _wcsdup(value);
-
- item->extended_info[x+1].key=0;
- item->extended_info[x+1].value=0;
- }
- }
- }
- // TODO: redo this without AutoChar
- #include "../nu/AutoChar.h"
- #define COPY_EXTENDED_STR(field) if (input-> ## field && input-> ## field ## [0]) setRecordExtendedItem(output, #field, AutoChar(input-> ## field));
- #define COPY_EXTENDED_INT(field) if (input->##field > 0) { char temp[64] = {0}; _itoa(input->##field, temp, 10); setRecordExtendedItem(output, #field, temp); }
- #define COPY_EXTENDED_INT64(field) if (input->##field > 0) { char temp[64] = {0}; _i64toa(input->##field, temp, 10); setRecordExtendedItem(output, #field, temp); }
- #define COPY_EXTENDED_INT0(field) if (input->##field >= 0) { char temp[64] = {0}; _itoa(input->##field, temp, 10); setRecordExtendedItem(output, #field, temp); }
- void convertRecord(itemRecord *output, const itemRecordW *input)
- {
- output->filename=AutoCharDup(input->filename);
- output->title = AutoCharDup( input->title );
- output->ext = AutoCharDup( input->ext );
- output->album=AutoCharDup(input->album);
- output->artist=AutoCharDup(input->artist);
- output->comment=AutoCharDup(input->comment);
- output->genre=AutoCharDup(input->genre);
- output->year=input->year;
- output->track=input->track;
- output->length=input->length;
- output->extended_info=0;
- COPY_EXTENDED_STR(albumartist);
- COPY_EXTENDED_STR(replaygain_album_gain);
- COPY_EXTENDED_STR(replaygain_track_gain);
- COPY_EXTENDED_STR(publisher);
- COPY_EXTENDED_STR(composer);
- COPY_EXTENDED_INT(tracks);
- COPY_EXTENDED_INT(rating);
- COPY_EXTENDED_INT(playcount);
- COPY_EXTENDED_INT64(lastplay);
- COPY_EXTENDED_INT64(lastupd);
- COPY_EXTENDED_INT64(filetime);
- COPY_EXTENDED_INT(filesize);
- COPY_EXTENDED_INT(bitrate);
- COPY_EXTENDED_INT0(type);
- COPY_EXTENDED_INT(disc);
- COPY_EXTENDED_INT(discs);
- COPY_EXTENDED_INT(bpm);
- COPY_EXTENDED_STR(category);
- if (input->extended_info)
- {
- for (int y = 0; input->extended_info[y].key; y ++)
- {
- setRecordExtendedItem(output, AutoChar(input->extended_info[y].key), AutoChar(input->extended_info[y].value));
- }
- }
- }
- #undef COPY_EXTENDED_STR
- #undef COPY_EXTENDED_INT
- #undef COPY_EXTENDED_INT0
- #include "../nu/AutoWide.h"
- #define COPY_EXTENDED_STR(field) output->##field = AutoWideDup(getRecordExtendedItem(input, #field));
- #define COPY_EXTENDED_INT(field) { char *x = getRecordExtendedItem(input, #field); output->##field=x?atoi(x):-1; }
- void convertRecord(itemRecordW *output, const itemRecord *input)
- {
- output->filename=AutoWideDup(input->filename);
- output->title=AutoWideDup(input->title);
- output->ext = AutoWideDup( input->ext );
- output->album=AutoWideDup(input->album);
- output->artist=AutoWideDup(input->artist);
- output->comment=AutoWideDup(input->comment);
- output->genre=AutoWideDup(input->genre);
- output->year=input->year;
- output->track=input->track;
- output->length=input->length;
- output->extended_info=0;
- COPY_EXTENDED_STR(albumartist);
- COPY_EXTENDED_STR(replaygain_album_gain);
- COPY_EXTENDED_STR(replaygain_track_gain);
- COPY_EXTENDED_STR(publisher);
- COPY_EXTENDED_STR(composer);
- COPY_EXTENDED_INT(tracks);
- COPY_EXTENDED_INT(rating);
- COPY_EXTENDED_INT(playcount);
- COPY_EXTENDED_INT(lastplay);
- COPY_EXTENDED_INT(lastupd);
- COPY_EXTENDED_INT(filetime);
- COPY_EXTENDED_INT(filesize);
- COPY_EXTENDED_INT(type);
- COPY_EXTENDED_INT(disc);
- COPY_EXTENDED_INT(discs);
- COPY_EXTENDED_INT(bpm);
- COPY_EXTENDED_INT(bitrate);
- COPY_EXTENDED_STR(composer);
- COPY_EXTENDED_STR(category);
- // TODO: copy input's extended fields
- }
- #undef COPY_EXTENDED_STR
- #undef COPY_EXTENDED_INT
- void convertRecordList(itemRecordList *output, const itemRecordListW *input)
- {
- output->Alloc = output->Size = input->Size;
- output->Items = (itemRecord*)calloc(sizeof(itemRecord),input->Size);
- if (output->Items)
- {
- for(int i=0; i < input->Size; i++)
- {
- convertRecord(&output->Items[i],&input->Items[i]);
- }
- }
- else
- output->Alloc = output->Size = 0;
- }
- void convertRecordList(itemRecordListW *output, const itemRecordList *input)
- {
- output->Alloc = output->Size = input->Size;
- output->Items = (itemRecordW*)calloc(sizeof(itemRecordW),input->Size);
- if (output->Items)
- {
- for(int i=0; i < input->Size; i++)
- {
- convertRecord(&output->Items[i],&input->Items[i]);
- }
- }
- }
|