1
0
mirror of https://github.com/azure-rtos/guix.git synced 2025-02-04 07:13:17 +08:00
guix/guix_studio/csv_read_write.cpp

380 lines
9.8 KiB
C++

#include "studiox_includes.h"
#include "xml_writer.h"
#include "xml_reader.h"
#include "csv_read_write.h"
#include "config_languages_dlg.h"
///////////////////////////////////////////////////////////////////////////////
csv_read_write::csv_read_write()
{
mpLine = NULL;
mpBuffer = NULL;
}
///////////////////////////////////////////////////////////////////////////////
BOOL csv_read_write::ExportLanguage(studiox_project *project)
{
int index;
int src_language = project->mHeader.string_export_src;
int target_language = project->mHeader.string_export_target;
CString tag_data;
CString src_data;
CString pathname = project->mHeader.string_export_path;
pathname += "\\";
pathname += project->mHeader.string_export_filename;
GotoProjectDirectory();
CStdioFile file;
if (!file.Open(pathname, CFile::modeCreate | CFile::modeWrite))
{
return FALSE;
}
int display = GetProjectView()->GetActiveDisplay();
string_table *table = project->mDisplays[display].stable;
tag_data.Format(_T("name,%s,%s\n"),
config_languages_dlg::GetLanguageId(src_language),
config_languages_dlg::GetLanguageId(target_language));
//write BOM mark
unsigned char BOM_mark[] = { 0xef, 0xbb, 0xbf };
file.Write(BOM_mark, 3);
//write header line
WriteString(&file, tag_data);
src_language = config_languages_dlg::GetStringTableIndexFromLanguageIndex(project, src_language);
target_language = config_languages_dlg::GetStringTableIndexFromLanguageIndex(project, target_language);
if (src_language == -1)
{
return FALSE;
}
CString csv_line;
for (index = 0; index < table->CountStrings(); index++)
{
src_data = table->GetString(index, src_language);
if (!src_data.IsEmpty())
{
//string id
csv_line = table->GetStringId(index);
csv_line.Append(_T(","));
//source language string
src_data = MakeCsvFormatValue(src_data);
csv_line.Append(src_data);
//target language string
if (target_language >= 0)
{
csv_line.Append(_T(","));
tag_data = table->GetString(index, target_language);
tag_data = MakeCsvFormatValue(tag_data);
csv_line.Append(tag_data);
}
csv_line.Append(_T("\n"));
WriteString(&file, csv_line);
}
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
BOOL csv_read_write::ImportCsvFile(studiox_project *project, CString &pathname)
{
CString src_language;
CString target_language;
CString string_id;
CString src_string;
CString target_string;
CString notes("");
BOOL status = TRUE;
int language_index;
int target_table_column;
int src_table_column;
int display = GetProjectView()->GetActiveDisplay();
string_table *table = project->mDisplays[display].stable;
ReadFile(pathname);
CString line;
CStringArray header_array;
GotoProjectDirectory();
ReadLine(line);
SplitString(line, ',', &header_array);
// Get the version information
if (header_array.GetCount() >= 3)
{
//there should be at lease 3 columns
int col, index;
CStringArray string_array;
src_language = header_array.GetAt(1);
language_index = config_languages_dlg::GetLanguageIdIndex(src_language);
src_table_column = config_languages_dlg::GetStringTableIndexFromLanguageIndex(project, language_index);
if (src_table_column == -1)
{
delete[]mpBuffer;
mpBuffer = NULL;
mpLine = NULL;
return FALSE;
}
while (ReadLine(line))
{
index = 0;
string_array.RemoveAll();
SplitCsvLine(line, string_array);
if (string_array.GetCount() < 2)
{
//string id and source language should be valid
status = FALSE;
break;
}
string_id = string_array.GetAt(0);
src_string = string_array.GetAt(1);
for (col = 2; col < header_array.GetCount(); col++)
{
target_language = header_array.GetAt(col);
language_index = config_languages_dlg::GetLanguageIdIndex(target_language);
target_table_column = config_languages_dlg::GetStringTableIndexFromLanguageIndex(project, language_index);
if (target_table_column == -1)
{
// the translation language doesn't exist in our project, so add it
//target_table_column = AddNewLanguage(language_index);
target_table_column = project->AddLanguage(language_index);
}
if (col < string_array.GetCount())
{
target_string = string_array.GetAt(col);
}
else
{
target_string = _T("");
}
table->ImportString(string_id, src_string, target_string, notes, src_table_column, target_table_column);
}
}
}
else
{
status = FALSE;
}
delete[]mpBuffer;
mpBuffer = NULL;
mpLine = NULL;
table->Sort();
table->UpdateGuixLanguageTable();
return status;
}
///////////////////////////////////////////////////////////////////////////////
CString csv_read_write::MakeCsvFormatValue(CString string)
{
int index;
CString format_string;
BOOL embedded_special_character = FALSE;
for (index = 0; index < string.GetLength(); index++)
{
switch (string.GetAt(index))
{
case '\"':
case '\r':
case '\n':
case ',':
embedded_special_character = TRUE;
break;
}
}
//replace single double quotation with a pair of consecutive double quotes
string.Replace(_T("\""), _T("\"\""));
if (embedded_special_character)
{
//put double quotation around string
string.Insert(0, '\"');
string.Append(_T("\""));
}
return string;
}
///////////////////////////////////////////////////////////////////////////////
void csv_read_write::WriteString(CStdioFile *file, CString string)
{
// The maximun UTF8 character is 6 bytes, calculate the maximun utf8 buffer size needed for the string.
int char_count = _tcslen(string) * 6 + 1;
char *utf8buf = new char[char_count];
strcpy_s(utf8buf, char_count, CT2A(string, CP_UTF8));
file->Write(utf8buf, strlen(utf8buf));
delete utf8buf;
}
///////////////////////////////////////////////////////////////////////////////
int csv_read_write::FindDelimiterIndex(CString line, int start_index)
{
int quatation_mark_count = 0;
while (start_index < line.GetLength())
{
switch (line.GetAt(start_index))
{
case '\"':
quatation_mark_count++;
break;
case ',':
if (!(quatation_mark_count & 0x1))
{
//quotation mark should be paired
return start_index;
}
break;
}
start_index++;
}
if (!(quatation_mark_count & 0x1))
{
//quotation mark should be paired
return start_index;
}
return -1;
}
///////////////////////////////////////////////////////////////////////////////
void csv_read_write::SplitCsvLine(CString &line, CStringArray &line_array)
{
int index = 0;
int length = line.GetLength();
int start, end;
CString string;
while (index < length)
{
start = index;
end = FindDelimiterIndex(line, start) - 1;
if (end < 0)
{
//should not happen
return;
}
index = end + 2;
if (line.GetAt(start) == '\"')
{
//remove double quotation mark around the string
start += 1;
end -= 1;
}
string = line.Mid(start, end - start + 1);
//replace 2 double colon to 1 double colon
string.Replace(_T("\"\""), _T("\""));
line_array.Add(string);
}
}
///////////////////////////////////////////////////////////////////////////////
BOOL csv_read_write::ReadLine(CString &line)
{
int double_quotation_count = 0;
if (!mpLine)
{
return FALSE;
}
while (mpLine[0] && ((mpLine[0] == '\r') || (mpLine[0] == '\n')))
{
mpLine++;
}
int line_end = 0;
while (mpLine[line_end])
{
if ((mpLine[line_end] == '\r') || (mpLine[line_end] == '\n'))
{
if (!(double_quotation_count & 0x01))
{
//double quotation mark should be paired
break;
}
}
else if (mpLine[line_end] == '\"')
{
double_quotation_count++;
}
line_end++;
}
if (line_end)
{
char *buf = new char[line_end + 1];
strncpy(buf, mpLine, line_end);
buf[line_end] = '\0';
line = CA2T(buf, CP_UTF8);
mpLine += line_end + 1;
delete[] buf;
return TRUE;
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
void csv_read_write::ReadFile(CString pathname)
{
CStdioFile file(pathname, CStdioFile::modeRead | CFile::shareExclusive);
ULONG size = (ULONG)file.GetLength();
mpBuffer = new char[size + 1];
memset(mpBuffer, 0, size + 1);
file.Read(mpBuffer, size);
mpLine = mpBuffer;
if (size >= 3)
{
if ((unsigned char)mpLine[0] == 0xef &&
(unsigned char)mpLine[1] == 0xbb &&
(unsigned char)mpLine[2] == 0xbf)
{
//skip BOM mark
mpLine += 3;
}
}
}