#include "episode.h" #include "stringutils.h" #include #include static int string_find(const char *str, int len, int offset, char char_to_find) { for(int i = offset; i < len; ++i) { if(str[i] == char_to_find) return i; } return -1; } static int string_rfind(const char *str, int len, int offset, char char_to_find) { for(int i = offset - 1; i >= 0; --i) { if(str[i] == char_to_find) return i + (len - offset); } return -1; } int episode_info_create_from_episode_name(EpisodeInfo *self, const char *episode_name) { self->episode_name[0] = '\0'; self->group_name = NULL; self->anime_name = NULL; self->episode = NULL; self->resolution = NULL; self->extension = NULL; int episode_name_len = strlen(episode_name); if(episode_name_len > 500) { fprintf(stderr, "Episode name is too long! it can't be more than 500 characters\n"); return -1; } char episode_name_s[512]; strcpy(episode_name_s, episode_name); char *episode_name_stripped = strip(episode_name_s); int episode_name_stripped_len = strlen(episode_name_stripped); int episode_name_offset = 0; if(episode_name_stripped_len == 0) return -1; int extension_index = string_rfind(episode_name_stripped, episode_name_stripped_len, episode_name_stripped_len, '.'); if(extension_index != -1) { int extension_len = episode_name_stripped_len - extension_index; self->extension = self->episode_name + episode_name_offset; memcpy(self->extension, episode_name_stripped + extension_index, extension_len); self->extension[extension_len] = '\0'; episode_name_offset += extension_len + 1; episode_name_stripped_len = extension_index; } if(episode_name_stripped[0] != '[') return -1; int group_name_end = string_find(episode_name_stripped, episode_name_stripped_len, 0, ']'); if(group_name_end == -1) return -1; int group_name_len = group_name_end - 1; self->group_name = self->episode_name + episode_name_offset; memcpy(self->group_name, episode_name_stripped + 1, group_name_len); self->group_name[group_name_len] = '\0'; self->group_name = strip(self->group_name); episode_name_offset += group_name_len + 1; int last_dash = string_rfind(episode_name_stripped, episode_name_stripped_len, episode_name_stripped_len, '-'); if(last_dash == -1) return -1; int anime_name_len = last_dash - 1 - group_name_end; self->anime_name = self->episode_name + episode_name_offset; memcpy(self->anime_name, episode_name_stripped + group_name_end + 1, anime_name_len); self->anime_name[anime_name_len] = '\0'; self->anime_name = strip(self->anime_name); episode_name_offset += anime_name_len + 1; int resolution_index_bracket = string_find(episode_name_stripped, episode_name_stripped_len, last_dash + 1, '['); int resolution_index_parentheses = string_find(episode_name_stripped, episode_name_stripped_len, last_dash + 1, '('); char resolution_end_char = ']'; int resolution_index = resolution_index_bracket; self->resolution_in_brackets = 1; if(resolution_index_parentheses != -1 && resolution_index_parentheses < resolution_index_bracket) { resolution_index = resolution_index_parentheses; resolution_end_char = ')'; self->resolution_in_brackets = 0; } if(resolution_index == -1) { /* TODO: Test if this works */ int episode_len = episode_name_stripped_len - (last_dash + 1); self->episode = self->episode_name + episode_name_offset; memcpy(self->episode, episode_name_stripped + last_dash + 1, episode_len); self->episode[episode_len] = '\0'; self->episode = strip(self->episode); } else { int episode_len = resolution_index - (last_dash + 1); self->episode = self->episode_name + episode_name_offset; memcpy(self->episode, episode_name_stripped + last_dash + 1, episode_len); self->episode[episode_len] = '\0'; self->episode = strip(self->episode); episode_name_offset += episode_len + 1; int resolution_end = string_find(episode_name_stripped, episode_name_stripped_len, resolution_index + 1, resolution_end_char); if(resolution_end != -1) { int resolution_len = resolution_end - (resolution_index + 1); if(resolution_len != 8 && episode_name_stripped[resolution_end - 1] == 'p') { // resolution_len is 8 when [] is a CRC and not resolution self->resolution = self->episode_name + episode_name_offset; memcpy(self->resolution, episode_name_stripped + resolution_index + 1, resolution_len); self->resolution[resolution_len] = '\0'; self->resolution = strip(self->resolution); } } } return 0; } int episode_info_get_generic_name(EpisodeInfo *self, char *output_buffer, int output_buffer_size) { if(!self->group_name || !self->anime_name) return -1; int bytes_written = 0; if(self->resolution) { char res_start_symbol = (self->resolution_in_brackets ? '[' : '('); char res_end_symbol = (self->resolution_in_brackets ? ']' : ')'); if(self->extension) bytes_written = snprintf(output_buffer, output_buffer_size, "[%s] %s %c%s%c%s", self->group_name, self->anime_name, res_start_symbol, self->resolution, res_end_symbol, self->extension); else bytes_written = snprintf(output_buffer, output_buffer_size, "[%s] %s %c%s%c", self->group_name, self->anime_name, res_start_symbol, self->resolution, res_end_symbol); } else { if(self->extension) bytes_written = snprintf(output_buffer, output_buffer_size, "[%s] %s%s", self->group_name, self->anime_name, self->extension); else bytes_written = snprintf(output_buffer, output_buffer_size, "[%s] %s", self->group_name, self->anime_name); } if(bytes_written >= output_buffer_size) { fprintf(stderr, "Failed to write generic name to buffer\n"); return -1; } return 0; }