Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include "locale.h"
- #include "malloc.h"
- #include <string.h>
- #include <math.h>
- /*
- file structure:
- ID3v2/file identifier "ID3"
- ID3v2 version $03 00
- ID3v2 flags %abc00000
- ID3v2 size 4 * %0xxxxxxx
- Frame ID $xx xx xx xx (four characters)
- Size $xx xx xx xx
- Flags $xx xx
- <Frame contents>
- etc...
- */
- int buffToIntegerForFrame(unsigned char *bytes) //char to integer size
- {
- return
- bytes[0] * pow(2, 24) + //2^21
- bytes[1] * pow(2, 16) + //2^14
- bytes[2] * pow(2, 8) + //2^7
- bytes[3];
- }
- int buffToInteger(unsigned char *bytes) {
- return
- bytes[0] * 0x200000 + //2^21
- bytes[1] * 0x4000 + //2^14
- bytes[2] * 0x80 + //2^7
- bytes[3];
- }
- void integerToBuff(int number, unsigned char *result) {
- result[0] = (unsigned char) ((number & 0xfe00000) >> 21); //0100000
- result[1] = (unsigned char) ((number & 0x1fc000) >> 14); //0010010
- result[2] = (unsigned char) ((number & 0x3f80) >> 7); //0000001
- result[3] = (unsigned char) (number & 0x7f); //0000100
- }
- void integerToBuffForFrame(int number, unsigned char *result) {
- result[0] = (unsigned char) ((number & 0xff000000) >> 24); //0100000
- result[1] = (unsigned char) ((number & 0xff0000) >> 16); //0010010
- result[2] = (unsigned char) ((number & 0xff00) >> 8); //0000001
- result[3] = (unsigned char) (number & 0xff); //0000100
- }
- struct tagHeader {
- unsigned char name[3]; //ID3
- unsigned char version[2]; //2 bytes ex. 3 0
- unsigned char flags; //1 byte
- unsigned int framesCount;
- unsigned int size; //4 bytes for tagHeader`s size
- };
- struct oframe {
- unsigned char name[4];//4 bytes FRAME NAME ex. TIT2, TALB and etc.
- unsigned char flags[2]; //2 bytes
- unsigned int size; //4 FRAME`S size
- unsigned char enc; //1 encoding
- unsigned char *content; //container
- };
- void readBytes(unsigned char *res, unsigned int size, FILE *file) {
- for (int i = 0; i < size; i++) {
- res[i] = getc(file);
- }
- }
- void writeBytes(unsigned char *res, unsigned int size, FILE *file) {
- for (int i = 0; i < size; i++) {
- putc(res[i], file);
- }
- }
- struct tagHeader readTagHeader(FILE *file) //function
- {
- struct tagHeader tag;
- unsigned char flags[1]; // flags
- unsigned char sizeb[4]; // tag size in bytes
- readBytes(tag.name, 3, file);
- readBytes(tag.version, 2, file);
- readBytes(flags, 1, file);
- readBytes(sizeb, 4, file);
- tag.flags = flags[0];
- tag.size = buffToInteger(sizeb);
- return tag;
- }
- void writeTagHeader(FILE *file, struct tagHeader tag) //function
- {
- unsigned char flags[1]; // flags
- unsigned char sizeb[4]; // tag size in bytes
- writeBytes(tag.name, 3, file);
- writeBytes(tag.version, 2, file);
- flags[0] = tag.flags;
- writeBytes(flags, 1, file);
- integerToBuff(tag.size, sizeb);
- writeBytes(sizeb, 4, file);
- }
- void writeFrame(FILE *file, struct oframe frame) //function
- {
- unsigned char sizeb[4]; // tag size in bytes
- unsigned char enc[1]; // tag size in bytes
- writeBytes(frame.name, 4, file);
- integerToBuffForFrame(frame.size, sizeb);
- writeBytes(sizeb, 4, file);
- writeBytes(frame.flags, 2, file);
- enc[0] = frame.enc;
- writeBytes(enc, 1, file);
- writeBytes(frame.content, frame.size - 1, file);
- }
- int checkName(char *name) {
- for (int i = 0; i < strlen(name); i++) {
- if ((name[i] < 60 | name[i] > 90) & (name[i] > 57 | name[i] < 48)) {
- return 0;
- }
- }
- return 1;
- }
- struct oframe readoframe(FILE *file, int readedBytes) {
- struct oframe frame;
- unsigned char sizeb[4]; // tag size in bytes
- readBytes(frame.name, 4, file);
- readBytes(sizeb, 4, file);
- frame.size = buffToIntegerForFrame(sizeb);
- if (frame.size + 10 > readedBytes | frame.size == 0 | frame.size > 134 * pow(10, 5) | checkName(frame.name) == 0) {
- fseek(file, frame.size + 2, SEEK_CUR);
- frame.size = 0;
- return frame;
- }
- frame.content = malloc(frame.size);
- readBytes(frame.flags, 2, file);
- unsigned char enc[1];
- readBytes(enc, 1, file);
- frame.enc = enc[0];
- readBytes(frame.content, frame.size - 1, file);
- return frame;
- }
- void set(char *filepath, char *framename, char *value) {
- FILE *fp = fopen(filepath, "rb");
- struct tagHeader tag = readTagHeader(fp);
- int old_size = tag.size;
- tag.framesCount = 0;
- //END OF TAG HEADER
- int diff = 0;
- int bytesReaded = 10;
- struct oframe frames[tag.size / 11 + 1];
- int i = 0;
- while (tag.size > bytesReaded) {
- frames[tag.framesCount] = readoframe(fp, tag.size - bytesReaded);
- if (frames[tag.framesCount].size == 0) {
- break;
- }
- bytesReaded += 10 + frames[tag.framesCount].size;
- tag.framesCount += 1;
- }
- //END OF READING METADATA FROM FILE
- //BEGIN OF WRITING NEW FILE
- remove("temp.mp3");
- FILE *outf = fopen("temp.mp3", "wb");
- writeTagHeader(outf, tag);
- for (int i = 0; i < tag.framesCount; i++) {
- if (strcmp(frames[i].name, framename) == 0) {
- diff = strlen(value) - strlen(frames[i].content);
- tag.size += diff;
- strcpy(frames[i].content, value);
- frames[i].size = strlen(value) + 1;
- }
- writeFrame(outf, frames[i]);
- /*printf("%s %d ", frames[i].name, frames[i].size);
- for (int j = 0; j < frames[i].size; j++) {
- printf("%c", frames[i].content[j]);
- }
- printf("\n");*/
- }
- int pos;
- pos = ftell(outf);
- int countzeros = 10 + tag.size - ((int) pos);
- unsigned char zeros[countzeros];
- for (int i = 0; i < countzeros; i++) {
- zeros[i] = 0;
- }
- writeBytes(zeros, countzeros, outf);
- char tmp;
- fseek(fp, old_size + 10, SEEK_SET);
- fseek(outf, tag.size + 10, SEEK_SET);
- tmp = fgetc(fp);
- while (!feof(fp)){
- fputc(tmp, outf);
- tmp = fgetc(fp);
- }
- fclose(outf);
- fclose(fp);
- }
- void get(char *filepath, char *framename) {
- FILE *fp = fopen(filepath, "rb");
- struct tagHeader tag = readTagHeader(fp);
- //END OF TAG HEADER
- int bytesReaded = 10;
- struct oframe frames[tag.size / 11 + 1];
- int i = 0;
- while (tag.size > bytesReaded) {
- struct oframe buff = readoframe(fp, tag.size - bytesReaded);
- if (buff.size == 0)
- break;
- frames[i] = buff;
- if (strcmp(frames[i].name, framename) == 0) {
- printf("%s data: ", framename);
- for (int j = 0; j < frames[i].size - 1; j++) {
- printf("%c", frames[i].content[j]);
- }
- i++;
- for (int j = 0; j < buff.size; ++j) //clearing buff container
- buff.content[j] = 0;
- printf("\n");
- break;
- }
- }
- }
- void show(char *filepath) {
- FILE *fp = fopen(filepath, "rb");
- struct tagHeader tag = readTagHeader(fp);
- printf("%s%s%d%d%s%d\n", tag.name, " : ", tag.version[0], tag.version[1], " : ", tag.size);
- //END OF TAG HEADER
- int bytesReaded = 10;
- struct oframe frames[tag.size / 11 + 1];
- int i = 0;
- while (tag.size > bytesReaded) {
- struct oframe buff = readoframe(fp, tag.size - bytesReaded);
- if (buff.size == 0)
- break;
- frames[i] = buff;
- printf("%s %d ", frames[i].name, frames[i].size);
- bytesReaded += 10 + frames[i].size;
- for (int j = 0; j < frames[i].size - 1; j++)
- printf("%c", frames[i].content[j]);
- i++;
- for (int j = 0; j < buff.size; ++j) //clearing buff container
- buff.content[j] = 0;
- printf("\n");
- }
- //END OF FRAME
- }
- int main(int argc, char *argv[]) {
- setlocale(LC_ALL, "Rus");
- char* filepath;
- filepath = strpbrk(argv[1],"=") + 1;
- for (int i = 2; i < argc; i++){
- if (strcmp(argv[i], "--show") == 0) {
- show(filepath);
- continue;
- }
- if (strcmp(argv[i], "--get") == 0) {
- get(filepath, argv[i+1]);
- continue;
- }
- if (strcmp(argv[i], "--set") == 0) {
- set(filepath, argv[i+1], argv[i+2]);
- continue;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement