1 /*
2   KeePass Password Safe - The Open-Source Password Manager
3   Copyright (C) 2003-2021 Dominik Reichl <dominik.reichl@t-online.de>
4 
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9 
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14 
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19 
20 using System;
21 using System.Collections.Generic;
22 using System.Diagnostics;
23 using System.IO;
24 using System.Text;
25 
26 using KeePassLib.Translation;
27 using KeePassLib.Utility;
28 
29 namespace TrlUtil
30 {
31 	public static class TrlImport
32 	{
Import1xLng(KPTranslation kpInto, string strFile)33 		public static void Import1xLng(KPTranslation kpInto, string strFile)
34 		{
35 			if((strFile == null) || (strFile.Length == 0)) { Debug.Assert(false); return; }
36 
37 			string strData = File.ReadAllText(strFile, StrUtil.Utf8);
38 
39 			Dictionary<string, string> dict = new Dictionary<string, string>();
40 
41 			const int nStatePreEn = 0;
42 			const int nStateInEn = 1;
43 			const int nStateBetween = 2;
44 			const int nStateInTrl = 3;
45 
46 			StringBuilder sbEn = new StringBuilder();
47 			StringBuilder sbTrl = new StringBuilder();
48 			int nState = nStatePreEn;
49 
50 			for(int i = 0; i < strData.Length; ++i)
51 			{
52 				char ch = strData[i];
53 
54 				if(ch == '|')
55 				{
56 					if(nState == nStatePreEn) nState = nStateInEn;
57 					else if(nState == nStateInEn) nState = nStateBetween;
58 					else if(nState == nStateBetween) nState = nStateInTrl;
59 					else if(nState == nStateInTrl)
60 					{
61 						dict[sbEn.ToString()] = sbTrl.ToString();
62 
63 						sbEn = new StringBuilder();
64 						sbTrl = new StringBuilder();
65 
66 						nState = nStatePreEn;
67 					}
68 				}
69 				else if(nState == nStateInEn) sbEn.Append(ch);
70 				else if(nState == nStateInTrl) sbTrl.Append(ch);
71 			}
72 
73 			Debug.Assert(nState == nStatePreEn);
74 
75 			dict[string.Empty] = string.Empty;
76 
77 			MergeDict(kpInto, dict);
78 		}
79 
MergeDict(KPTranslation kpInto, Dictionary<string, string> dict)80 		private static void MergeDict(KPTranslation kpInto, Dictionary<string, string> dict)
81 		{
82 			if(kpInto == null) { Debug.Assert(false); return; }
83 			if(dict == null) { Debug.Assert(false); return; }
84 
85 			foreach(KPStringTable kpst in kpInto.StringTables)
86 			{
87 				foreach(KPStringTableItem kpsti in kpst.Strings)
88 				{
89 					string strTrl;
90 					if(dict.TryGetValue(kpsti.ValueEnglish, out strTrl))
91 						kpsti.Value = strTrl;
92 				}
93 			}
94 
95 			foreach(KPFormCustomization kpfc in kpInto.Forms)
96 			{
97 				string strTrlWnd;
98 				if(dict.TryGetValue(kpfc.Window.TextEnglish, out strTrlWnd))
99 					kpfc.Window.Text = strTrlWnd;
100 
101 				foreach(KPControlCustomization kpcc in kpfc.Controls)
102 				{
103 					string strTrlCtrl;
104 					if(dict.TryGetValue(kpcc.TextEnglish, out strTrlCtrl))
105 						kpcc.Text = strTrlCtrl;
106 				}
107 			}
108 		}
109 
ImportPo(KPTranslation kpInto, string strFile)110 		public static void ImportPo(KPTranslation kpInto, string strFile)
111 		{
112 			if((strFile == null) || (strFile.Length == 0)) { Debug.Assert(false); return; }
113 
114 			string strData = File.ReadAllText(strFile, StrUtil.Utf8);
115 			strData = StrUtil.NormalizeNewLines(strData, false);
116 			string[] vData = strData.Split('\n');
117 
118 			Dictionary<string, string> dict = new Dictionary<string, string>();
119 			string strID = string.Empty;
120 			foreach(string strLine in vData)
121 			{
122 				string str = strLine.Trim();
123 				if(str.StartsWith("msgid ", StrUtil.CaseIgnoreCmp))
124 					strID = FilterPoValue(str.Substring(6));
125 				else if(str.StartsWith("msgstr ", StrUtil.CaseIgnoreCmp))
126 				{
127 					if(strID.Length > 0)
128 					{
129 						dict[strID] = FilterPoValue(str.Substring(7));
130 						strID = string.Empty;
131 					}
132 				}
133 			}
134 
135 			MergeDict(kpInto, dict);
136 		}
137 
FilterPoValue(string str)138 		private static string FilterPoValue(string str)
139 		{
140 			if(str == null) { Debug.Assert(false); return string.Empty; }
141 
142 			if(str.StartsWith("\"") && str.EndsWith("\"") && (str.Length >= 2))
143 				str = str.Substring(1, str.Length - 2);
144 			else { Debug.Assert(false); }
145 
146 			str = str.Replace("\\\"", "\"");
147 
148 			return str;
149 		}
150 	}
151 }
152