/* * Copyright (C) 2004-2005 Vadim Berezniker * http://www.kryptolus.com * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This Program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * http://www.gnu.org/copyleft/gpl.html * */ #include "stdafx.h" #include "common.h" #include "kryTextFileReader.h" #include "krySubReader.h" #include krySubReader::krySubReader(char *filename) : kryTextFileReader(filename) { this->m_filename = kry_strdup(filename); this->m_errors = NULL; this->m_style_iconv = new kryHash(g_str_hash, g_str_equal, kry_free_minimal, (GDestroyNotify) sabbu_style_iconv_map_free); } krySubReader::~krySubReader() { kry_free(this->m_filename); delete this->m_style_iconv; } void krySubReader::AddError(kryTextParseError *error) { if(this->m_errors) this->m_errors->Append(error); } void krySubReader::AddEvent(kryEventDetailed *event) { struct style_iconv_map *map; if(!sabbu_iconv_get_mapping(this->m_script, event, this->m_style_iconv, &map, FALSE)) this->AddError(new kryTextParseError(this->GetLineNumber(), _("The style referenced by this line uses an unsupported encoding. Please inform the author."))); if(map->present && this->GetEncoding() == ENCODING_ASCII) { #ifdef ICONV_CONST_INBUFFER const char *in_buffer = event->GetText(); #else char *in_buffer = event->GetText(); #endif char *out_buffer = (char *) kry_malloc(strlen(in_buffer) * 2 + 1); char *out_buffer_orig = out_buffer; size_t in_bytes_left = strlen(in_buffer) + 1, out_bytes_left = strlen(in_buffer) * 2 + 1; size_t rv = iconv(map->iconv_h, &in_buffer, &in_bytes_left, &out_buffer, &out_bytes_left); if(rv == 0) { event->SetText(out_buffer_orig); } else { this->AddError(new kryTextParseError(this->GetLineNumber(), _("Error converting line from '%s' to UTF-8 encoding"), map->src_encoding)); } kry_free(out_buffer_orig); } const char *invalid_start = NULL; if(!g_utf8_validate(event->GetText(), -1, &invalid_start)) { g_warning("text: %s", event->GetText()); char *text = event->GetText(); char *text_copy = g_strdup(text); char *ptr = text_copy; char *ptr_prev = ptr; GList *chunks = NULL; while(ptr[0] != 0) { gunichar chr = g_utf8_get_char_validated(ptr, -1); if(chr == (gunichar) -1 || chr == (gunichar) -2) { if(ptr > ptr_prev) { char *str = (char *) kry_malloc(ptr - ptr_prev + 1); memcpy(str, ptr_prev, ptr - ptr_prev); str[ptr - ptr_prev] = 0; chunks = g_list_append(chunks, str); } chunks = g_list_append(chunks, (void *)"[?]"); ptr[0] = '?'; ptr++; ptr_prev = ptr; } else { ptr = g_utf8_next_char(ptr); if(ptr[0] == 0) { chunks = g_list_append(chunks, kry_strdup(ptr_prev)); } } } kry_free(text_copy); int len = 0; for(GList *lst = chunks; lst; lst = lst->next) { len += strlen((char *) lst->data); } int offset = 0; char *str_final = (char *) kry_malloc(len + 1); str_final[len] = 0; for(GList *lst = chunks; lst; lst = lst->next) { strcpy(str_final + offset, (char *) lst->data); offset += strlen((char *) lst->data); } char *errmsg = _("This line contains non-ASCII characters and is not UTF8. Please remove the offending characters or convert the file to Unicode (UTF8/UTF16)."); char *msg = g_strdup_printf("%s\n(%s)", errmsg, str_final); AddError(new kryTextParseError(this->GetLineNumber(), msg)); kry_free(str_final); kry_free(msg); } this->m_script->AddEvent(event); }