Advertisement
Kryukov_And

Untitled

Dec 14th, 2018
399
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.58 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4.  
  5. const int SIZE_OF_FIELDS = 100;
  6. const int LENGTH_OF_PATH = 100;
  7. const char *FILEPATH = "--filepath=";
  8. const char *NO_INFORMATION = "no information";
  9.  
  10. char *all_file; //When we edit our file
  11. int size_file = 0;
  12.  
  13. char *new_all_file;
  14. char* EMPTY_STRING = ""; //For empty string in mp3 file
  15.  
  16. void reverse(char *str){
  17. int n = (int)strlen(str);
  18. for (int i = 0; i < n / 2; i++){
  19. char temp = str[i];
  20. str[i] = str[n - i - 1];
  21. str[n - i - 1] = temp;
  22. }
  23. }
  24.  
  25. char* value_in_string(char *str){ // return value after =
  26. int p = 0;
  27. int n = (int)strlen(str);
  28. char *result = calloc(LENGTH_OF_PATH, sizeof(char));
  29.  
  30. while (str[n - p - 1] != '='){
  31. result[p] = str[n - p - 1];
  32. p++;
  33. }
  34.  
  35. reverse(result);
  36. return result;
  37. }
  38.  
  39. int command_in_string(char **str, int argc){ // type of command
  40. if ((str[2][2] == 's') && (str[2][3] == 'e')) return 2;
  41. if (str[2][2] == 's') return 0;
  42. if (str[2][2] == 'g') return 1;
  43. }
  44.  
  45. long long atoin(const char *str, int n, int base){ //n first char in string -> long long
  46. long long res = 0, x = 1;
  47. for (int i = 0; i < n - 1; i++) x *= base;
  48. for (int i = 0; i < n; i++) {
  49. if (str[i] < 0) {
  50. return 0;
  51. }
  52. res += (long long) str[i] * x;
  53. x /= base;
  54. }
  55. return res;
  56. }
  57.  
  58. char* numtochar(int num, int base){
  59. static char* temp;
  60. temp = calloc(5, sizeof(char));
  61. temp[4] = '\0';
  62.  
  63. for (int i = 0; i < 4; i++){
  64. temp[3 - i] = num % base;
  65. num /= base;
  66. }
  67. return temp;
  68. }
  69.  
  70. struct Music{
  71. int version;
  72. int count_read;
  73. char *performer;
  74. char *title;
  75. char *album;
  76. char *composer;
  77. char *comment;
  78. char *genre;
  79. };
  80.  
  81. void init_music(struct Music *music){ // Constructor
  82. music -> performer = calloc(SIZE_OF_FIELDS, sizeof(char));
  83. music -> title = calloc(SIZE_OF_FIELDS, sizeof(char));
  84. music -> album = calloc(SIZE_OF_FIELDS, sizeof(char));
  85. music -> composer = calloc(SIZE_OF_FIELDS, sizeof(char));
  86. music -> comment = calloc(SIZE_OF_FIELDS, sizeof(char));
  87. music -> genre = calloc(SIZE_OF_FIELDS, sizeof(char));
  88. }
  89.  
  90. char** get_field_to_tag(const char *tag, struct Music *music){ //Get &on field in Music
  91. if (!strcmp(tag, "TPE1")) return &(music -> performer);
  92. if (!strcmp(tag, "TIT2")) return &(music -> title);
  93. if (!strcmp(tag, "TALB")) return &(music -> album);
  94. if (!strcmp(tag, "TCOM")) return &(music -> composer);
  95. if (!strcmp(tag, "COMM")) return &(music -> comment);
  96. if (!strcmp(tag, "TCON")) return &(music -> genre);
  97. return &EMPTY_STRING;
  98. }
  99.  
  100. char* get_name_to_tag(const char *tag){ //Get name field in Music
  101. if (!strcmp(tag, "TPE1")) return "Performer";
  102. if (!strcmp(tag, "TIT2")) return "Title of song";
  103. if (!strcmp(tag, "TALB")) return "Album";
  104. if (!strcmp(tag, "TCOM")) return "Composer";
  105. if (!strcmp(tag, "COMM")) return "Comment";
  106. if (!strcmp(tag, "TCON")) return "Genre";
  107. return EMPTY_STRING;
  108. }
  109.  
  110. void print_field(const char *tag, struct Music *music){ //Print filed from Music
  111. char **field = get_field_to_tag(tag, music);
  112. char *name = get_name_to_tag(tag);
  113. printf("%s = %s\n", name, ((*field)[0] == '\0' ? NO_INFORMATION : *field));
  114. }
  115.  
  116. void print_full_struct(struct Music *music){
  117. printf("\nVersion = ID3v%d\n", music -> version);
  118. print_field("TPE1", music);
  119. print_field("TIT2", music);
  120. print_field("TALB", music);
  121. print_field("TCOM", music);
  122. print_field("COMM", music);
  123. print_field("TCON", music);
  124. printf("\n");
  125. }
  126.  
  127. void set_field(const char *tag, const char *text, struct Music *music){ //Set field's value in stuct Music
  128. if (get_field_to_tag(tag, music) != &EMPTY_STRING) {
  129. strcpy(*get_field_to_tag(tag, music), text);
  130. }
  131. }
  132.  
  133. void input(FILE *fp, struct Music *music){ //Fill struct Music
  134. char temp[10];
  135.  
  136. ///----------Version---------------
  137. fseek(fp, 3, SEEK_SET);
  138. music -> version = (int)fgetc(fp);
  139.  
  140. ///----------Size of frames--------
  141. long long size_of_frames = 0;
  142. fseek(fp, 6, SEEK_SET);
  143. fgets(temp, 4 + 1, fp);
  144. size_of_frames = atoin(temp, 4, 1 << 7);
  145.  
  146. ///----------Work with frames------
  147. for (int i = 0; i < 15; i++) {
  148. ///Tag of frame
  149. char *tag = malloc(4 + 1);
  150. fgets(tag, 4 + 1, fp);
  151.  
  152. ///Size of frame
  153. fgets(temp, 4 + 1, fp);
  154. const long long size_of_frame = atoin(temp, 4, 1 << 8);
  155.  
  156.  
  157. ///Text of frame
  158. fseek(fp, 3, SEEK_CUR);
  159. char *text = malloc(size_of_frame);
  160. fgets(text, (int)size_of_frame, fp);
  161. set_field(tag, text, music);
  162.  
  163. music -> count_read += 10 + strlen(text);
  164. free(tag); free(text);
  165. }
  166. }
  167.  
  168. void read_all_file(FILE *fp){
  169. fseek(fp, 0, SEEK_END);
  170. size_file = ftell(fp);
  171. fseek(fp, 0, SEEK_SET);
  172.  
  173. all_file = (char *)malloc(size_file * sizeof(char));
  174. fread(all_file, size_file + 1, sizeof(char), fp);
  175. }
  176.  
  177. void output(FILE *fp, char *tag, char *value, struct Music *music){
  178. if (strcmp(*(get_field_to_tag(tag, music)), EMPTY_STRING)) {
  179. for (int i = 0; i < size_file; i++) {
  180. if (strncmp(all_file + i, tag, 4) == 0 && i < music -> count_read) {
  181. ///Tag
  182. for (int j = 0; j < 4; j++) {
  183. fputc(all_file[i + j], fp);
  184. }
  185.  
  186. ///Size
  187. char *temp = numtochar(strlen(value) + 1, 1 << 8);
  188. for (int j = 0; j < 4; j++) {
  189. fputc(temp[j], fp);
  190. }
  191.  
  192. ///Flags
  193. for (int j = 0; j < 3; j++) {
  194. fputc(all_file[i + 8 + j], fp);
  195. }
  196.  
  197. ///Text
  198. int temp_n = strlen(value);
  199. for (int j = 0; j < temp_n; j++) {
  200. fputc(value[j], fp);
  201. }
  202.  
  203. temp_n = (int) strlen(*get_field_to_tag(tag, music));
  204. i += 10 + temp_n;
  205. } else {
  206. fputc(all_file[i], fp);
  207. }
  208. }
  209. } else {
  210. char *empty_string = calloc(5, sizeof(char));
  211. int help_p = 10;
  212.  
  213. for (int i = 0; i < size_file; i++) {
  214. if (i == help_p && strncmp(all_file + i, empty_string, 4) == 0) {
  215.  
  216. ///Tag
  217. for (int j = 0; j < 4; j++) {
  218. fputc(tag[j], fp);
  219. }
  220.  
  221. ///Size
  222. char *temp = numtochar(strlen(value) + 1, 1 << 8);
  223. for (int j = 0; j < 4; j++) {
  224. fputc(temp[j], fp);
  225. }
  226.  
  227. ///Flags
  228. for (int j = 0; j < 3; j++) {
  229. fputc(all_file[i + 8 + j], fp);
  230. }
  231.  
  232. ///Text
  233. int temp_n = strlen(value);
  234. for (int j = 0; j < temp_n; j++) {
  235. fputc(value[j], fp);
  236. }
  237.  
  238. i += 10;
  239. } else {
  240. if (help_p == i) {
  241. char temp_tag[] = {all_file[i], all_file[i + 1], all_file[i + 2], all_file[i + 3]};
  242. help_p += 11 + strlen(*get_field_to_tag(temp_tag, music));
  243. }
  244.  
  245. fputc(all_file[i], fp);
  246. }
  247. }
  248. }
  249. }
  250.  
  251. int main(int argc, char **argv){
  252. if (!strncmp(argv[1], FILEPATH, (int)strlen(FILEPATH))){
  253.  
  254. char *path = value_in_string(argv[1]);
  255. int type_of_command = command_in_string(argv, argc);
  256.  
  257. FILE *fp = NULL;
  258.  
  259. ///Init Music
  260. struct Music music;
  261. init_music(&music);
  262.  
  263. ///Open file for read and fill struct Music
  264. if ((fp = fopen(path, "r")) == NULL){
  265. printf("ERROR, file not open");
  266. return 1;
  267. }
  268. input(fp, &music);
  269.  
  270. if (type_of_command == 0) {
  271. print_full_struct(&music);
  272. }
  273. if (type_of_command == 1){
  274. print_field(value_in_string(argv[2]), &music);
  275. }
  276. if (type_of_command == 2){
  277. read_all_file(fp);
  278.  
  279. fclose(fp);
  280. if ((fp = fopen(path, "w")) == NULL){
  281. printf("ERROR, file not open");
  282. return 1;
  283. }
  284.  
  285. output(fp, value_in_string(argv[2]), value_in_string(argv[3]), &music);
  286. }
  287.  
  288. fclose(fp);
  289. } else {
  290. printf("Incorrect flag");
  291. }
  292. return 0;
  293. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement