Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- const int SIZE_OF_FIELDS = 100;
- const int LENGTH_OF_PATH = 100;
- const char *FILEPATH = "--filepath=";
- const char *NO_INFORMATION = "no information";
- char *all_file; //When we edit our file
- int size_file = 0;
- char *new_all_file;
- char* EMPTY_STRING = ""; //For empty string in mp3 file
- void reverse(char *str){
- int n = (int)strlen(str);
- for (int i = 0; i < n / 2; i++){
- char temp = str[i];
- str[i] = str[n - i - 1];
- str[n - i - 1] = temp;
- }
- }
- char* value_in_string(char *str){ // return value after =
- int p = 0;
- int n = (int)strlen(str);
- char *result = calloc(LENGTH_OF_PATH, sizeof(char));
- while (str[n - p - 1] != '='){
- result[p] = str[n - p - 1];
- p++;
- }
- reverse(result);
- return result;
- }
- int command_in_string(char **str, int argc){ // type of command
- if ((str[2][2] == 's') && (str[2][3] == 'e')) return 2;
- if (str[2][2] == 's') return 0;
- if (str[2][2] == 'g') return 1;
- }
- long long atoin(const char *str, int n, int base){ //n first char in string -> long long
- long long res = 0, x = 1;
- for (int i = 0; i < n - 1; i++) x *= base;
- for (int i = 0; i < n; i++) {
- if (str[i] < 0) {
- return 0;
- }
- res += (long long) str[i] * x;
- x /= base;
- }
- return res;
- }
- char* numtochar(int num, int base){
- static char* temp;
- temp = calloc(5, sizeof(char));
- temp[4] = '\0';
- for (int i = 0; i < 4; i++){
- temp[3 - i] = num % base;
- num /= base;
- }
- return temp;
- }
- struct Music{
- int version;
- int count_read;
- char *performer;
- char *title;
- char *album;
- char *composer;
- char *comment;
- char *genre;
- };
- void init_music(struct Music *music){ // Constructor
- music -> performer = calloc(SIZE_OF_FIELDS, sizeof(char));
- music -> title = calloc(SIZE_OF_FIELDS, sizeof(char));
- music -> album = calloc(SIZE_OF_FIELDS, sizeof(char));
- music -> composer = calloc(SIZE_OF_FIELDS, sizeof(char));
- music -> comment = calloc(SIZE_OF_FIELDS, sizeof(char));
- music -> genre = calloc(SIZE_OF_FIELDS, sizeof(char));
- }
- char** get_field_to_tag(const char *tag, struct Music *music){ //Get &on field in Music
- if (!strcmp(tag, "TPE1")) return &(music -> performer);
- if (!strcmp(tag, "TIT2")) return &(music -> title);
- if (!strcmp(tag, "TALB")) return &(music -> album);
- if (!strcmp(tag, "TCOM")) return &(music -> composer);
- if (!strcmp(tag, "COMM")) return &(music -> comment);
- if (!strcmp(tag, "TCON")) return &(music -> genre);
- return &EMPTY_STRING;
- }
- char* get_name_to_tag(const char *tag){ //Get name field in Music
- if (!strcmp(tag, "TPE1")) return "Performer";
- if (!strcmp(tag, "TIT2")) return "Title of song";
- if (!strcmp(tag, "TALB")) return "Album";
- if (!strcmp(tag, "TCOM")) return "Composer";
- if (!strcmp(tag, "COMM")) return "Comment";
- if (!strcmp(tag, "TCON")) return "Genre";
- return EMPTY_STRING;
- }
- void print_field(const char *tag, struct Music *music){ //Print filed from Music
- char **field = get_field_to_tag(tag, music);
- char *name = get_name_to_tag(tag);
- printf("%s = %s\n", name, ((*field)[0] == '\0' ? NO_INFORMATION : *field));
- }
- void print_full_struct(struct Music *music){
- printf("\nVersion = ID3v%d\n", music -> version);
- print_field("TPE1", music);
- print_field("TIT2", music);
- print_field("TALB", music);
- print_field("TCOM", music);
- print_field("COMM", music);
- print_field("TCON", music);
- printf("\n");
- }
- void set_field(const char *tag, const char *text, struct Music *music){ //Set field's value in stuct Music
- if (get_field_to_tag(tag, music) != &EMPTY_STRING) {
- strcpy(*get_field_to_tag(tag, music), text);
- }
- }
- void input(FILE *fp, struct Music *music){ //Fill struct Music
- char temp[10];
- ///----------Version---------------
- fseek(fp, 3, SEEK_SET);
- music -> version = (int)fgetc(fp);
- ///----------Size of frames--------
- long long size_of_frames = 0;
- fseek(fp, 6, SEEK_SET);
- fgets(temp, 4 + 1, fp);
- size_of_frames = atoin(temp, 4, 1 << 7);
- ///----------Work with frames------
- for (int i = 0; i < 15; i++) {
- ///Tag of frame
- char *tag = malloc(4 + 1);
- fgets(tag, 4 + 1, fp);
- ///Size of frame
- fgets(temp, 4 + 1, fp);
- const long long size_of_frame = atoin(temp, 4, 1 << 8);
- ///Text of frame
- fseek(fp, 3, SEEK_CUR);
- char *text = malloc(size_of_frame);
- fgets(text, (int)size_of_frame, fp);
- set_field(tag, text, music);
- music -> count_read += 10 + strlen(text);
- free(tag); free(text);
- }
- }
- void read_all_file(FILE *fp){
- fseek(fp, 0, SEEK_END);
- size_file = ftell(fp);
- fseek(fp, 0, SEEK_SET);
- all_file = (char *)malloc(size_file * sizeof(char));
- fread(all_file, size_file + 1, sizeof(char), fp);
- }
- void output(FILE *fp, char *tag, char *value, struct Music *music){
- if (strcmp(*(get_field_to_tag(tag, music)), EMPTY_STRING)) {
- for (int i = 0; i < size_file; i++) {
- if (strncmp(all_file + i, tag, 4) == 0 && i < music -> count_read) {
- ///Tag
- for (int j = 0; j < 4; j++) {
- fputc(all_file[i + j], fp);
- }
- ///Size
- char *temp = numtochar(strlen(value) + 1, 1 << 8);
- for (int j = 0; j < 4; j++) {
- fputc(temp[j], fp);
- }
- ///Flags
- for (int j = 0; j < 3; j++) {
- fputc(all_file[i + 8 + j], fp);
- }
- ///Text
- int temp_n = strlen(value);
- for (int j = 0; j < temp_n; j++) {
- fputc(value[j], fp);
- }
- temp_n = (int) strlen(*get_field_to_tag(tag, music));
- i += 10 + temp_n;
- } else {
- fputc(all_file[i], fp);
- }
- }
- } else {
- char *empty_string = calloc(5, sizeof(char));
- int help_p = 10;
- for (int i = 0; i < size_file; i++) {
- if (i == help_p && strncmp(all_file + i, empty_string, 4) == 0) {
- ///Tag
- for (int j = 0; j < 4; j++) {
- fputc(tag[j], fp);
- }
- ///Size
- char *temp = numtochar(strlen(value) + 1, 1 << 8);
- for (int j = 0; j < 4; j++) {
- fputc(temp[j], fp);
- }
- ///Flags
- for (int j = 0; j < 3; j++) {
- fputc(all_file[i + 8 + j], fp);
- }
- ///Text
- int temp_n = strlen(value);
- for (int j = 0; j < temp_n; j++) {
- fputc(value[j], fp);
- }
- i += 10;
- } else {
- if (help_p == i) {
- char temp_tag[] = {all_file[i], all_file[i + 1], all_file[i + 2], all_file[i + 3]};
- help_p += 11 + strlen(*get_field_to_tag(temp_tag, music));
- }
- fputc(all_file[i], fp);
- }
- }
- }
- }
- int main(int argc, char **argv){
- if (!strncmp(argv[1], FILEPATH, (int)strlen(FILEPATH))){
- char *path = value_in_string(argv[1]);
- int type_of_command = command_in_string(argv, argc);
- FILE *fp = NULL;
- ///Init Music
- struct Music music;
- init_music(&music);
- ///Open file for read and fill struct Music
- if ((fp = fopen(path, "r")) == NULL){
- printf("ERROR, file not open");
- return 1;
- }
- input(fp, &music);
- if (type_of_command == 0) {
- print_full_struct(&music);
- }
- if (type_of_command == 1){
- print_field(value_in_string(argv[2]), &music);
- }
- if (type_of_command == 2){
- read_all_file(fp);
- fclose(fp);
- if ((fp = fopen(path, "w")) == NULL){
- printf("ERROR, file not open");
- return 1;
- }
- output(fp, value_in_string(argv[2]), value_in_string(argv[3]), &music);
- }
- fclose(fp);
- } else {
- printf("Incorrect flag");
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement