private void WorkerThread() { if (Interlocked.Exchange(ref state, 1L) == 0) { try { SimpleDictionary.Section firstResult; try { WireEvents(first); firstResult = first.Import(firstPath, out sectionInfo); } finally { UnwireEvents(first); } if (Interlocked.Read(ref state) == 2) { throw new OperationCanceledException(); } SimpleDictionary.Section secondResult = null; if (second != null) { try { WireEvents(second); SectionInfo unused; secondResult = second.Import(secondPath, out unused); } finally { UnwireEvents(second); } } if (secondResult == null) { secondResult = new SimpleDictionary.Section(new List <Entry>(), true, null); } Finish(firstResult, secondResult); } catch (OperationCanceledException ex) { OnCompleted(null, ex, true, null); } catch (NotSupportedException ex) { OnCompleted(null, ex, false, null); } catch (InvalidOperationException ex) { OnCompleted(null, ex, false, null); } catch (ImportException ex) { OnCompleted(null, ex, false, null); } finally { // Set the state back to 0 (Ready) // Don't need to check the return value. Interlocked.Exchange(ref state, 0L); } } else { // Already importing! OnCompleted(null, new InvalidOperationException(), false, null); } }
private void Finish(SimpleDictionary.Section firstSection, SimpleDictionary.Section secondSection) { if (shouldGenerateSecondHalf) { secondSection = GenerateSecondHalf(firstSection); } var dict = new SimpleDictionary(firstSection, secondSection); firstSection.Sort(); secondSection.Sort(); /*var dict = SqliteDictionary.FromPath(System.IO.Path.GetTempFileName()); * try { * dict.AddEntries( * System.Linq.Enumerable.ToArray(firstSection), * System.Linq.Enumerable.ToArray(secondSection), * delegate(int i, int n) { * if (Interlocked.Read(ref state) == 2) * throw new OperationCanceledException(); * OnProgressChanged(string.Format("Writing file: {0} of {1}", i, n), i * 100 / (n != 0 ? n : 1)); * }); * } catch (OperationCanceledException ex) { * OnCompleted(null, ex, true, null); * return; * }*/ // It only has to be a guess, because the user can override it. if (sectionInfo != null) { dict.Name = sectionInfo.Name; // Attempt to guess at the names of the languages. foreach (char delim in new char[] { '\u21d4', '\u2194', '\u2014', '-' }) { string[] bits = dict.Name.Split(new char[] { delim }, 2); if (bits.Length == 2) { dict.FirstLanguage = bits[0]; dict.SecondLanguage = bits[1]; break; } } } OnCompleted(dict, null, false, null); }
public SimpleDictionary.Section Import(string path, out SectionInfo info) { var entries = new SortedDictionary <string, List <Translation> >(); string fromName, toName; using (var conn = Connect(path)) { int rows = 0; using (var getRowCount = conn.CreateCommand()) { getRowCount.CommandText = "SELECT COUNT(*) FROM SZOTAR;"; rows = Convert.ToInt32(getRowCount.ExecuteScalar()); } int row = 0, lastPercent = -1; using (var cmd = conn.CreateCommand()) { cmd.CommandText = "SELECT * FROM " + System.IO.Path.GetFileNameWithoutExtension(path) + ";"; using (var reader = cmd.ExecuteReader()) { fromName = reader.GetName(0); toName = reader.GetName(1); while (reader.Read()) { row++; if (Interlocked.Read(ref shouldCancel) > 0) { throw new OperationCanceledException(); } var key = reader.GetString(0); var data = reader.GetString(1); int percent = row * 100 / (rows != 0 ? rows : 1); if (percent > lastPercent) { OnProgressChanged(string.Format("Row {0} of {1}", row, rows), percent); lastPercent = percent; } List <Translation> translations; if (entries.TryGetValue(key, out translations)) { translations.Add(new Translation(data)); } else { entries.Add(key, new List <Translation>(new Translation[] { new Translation(data) })); } } } } } var actualEntries = new List <Entry>(); foreach (var kv in entries) { actualEntries.Add(new Entry(kv.Key, kv.Value)); } var section = new SimpleDictionary.Section(actualEntries, true, null); foreach (var e in actualEntries) { e.Tag = new EntryTag(section, null); } info = new SectionInfo { Date = DateTime.Now, ItemCount = actualEntries.Count, Size = 0, Name = fromName + "-" + toName }; return(section); }
public SimpleDictionary.Section Import(string path, out SectionInfo info) { List <Entry> entries = new List <Entry>(); using (Stream fileStream = File.OpenRead(path)) { using (GZipStream stream = new GZipStream(fileStream, System.IO.Compression.CompressionMode.Decompress, false)) { using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) { info = ReadInfoFromStream(reader); if (reader.EndOfStream) { throw new ImportException("The file has no entries or is not a Zbedic dictionary."); } int percentage = 0, lastPercentage = 0; long compressedSize = new FileInfo(path).Length; string phrase = reader.ReadLine(); while (true) { { if (Interlocked.CompareExchange(ref shouldCancel, 0L, 1L) > 0) { throw new OperationCanceledException(); } } string line = reader.ReadLine(); string[] bits = line.Split(new char[] { '\0' }, 2, StringSplitOptions.RemoveEmptyEntries); List <Entry> senses; try { senses = ParseSenses(bits[0], phrase); } catch (InvalidDataException) { ProgramLog.Default.AddMessage(LogType.Error, "Invalid word sense for phrase \"{0}\" in {1}: {2}", phrase, path, bits[0]); continue; } if (bits.Length > 1) { entries.AddRange(senses); string suffix = string.Empty; int n, max; if (info.ItemCount.HasValue) { suffix = " entries"; max = info.ItemCount.Value; n = entries.Count; } else { suffix = " bytes"; // This won't be perfect due to buffering, but it doesn't have to be. max = (int)compressedSize; n = (int)fileStream.Position; } percentage = 100 * n / max; if (percentage > lastPercentage) { OnProgressChanged(string.Format("{0}% completed ({1} of {2}{3})", percentage, n, max, suffix), percentage); } lastPercentage = percentage; phrase = bits[1].Normalize(); // Set phrase for next entry } else { break; } } } } } // This sort is needed because of the {hw} tag which can change the entry's headword. entries.Sort((a, b) => a.Phrase.CompareTo(b.Phrase)); var section = new SimpleDictionary.Section(entries, true, null); foreach (var e in entries) { e.Tag = new EntryTag(section, null); } return(section); }
protected SimpleDictionary.Section GenerateSecondHalf(IDictionarySection firstSection) { Dictionary <string, List <string> > entries = new Dictionary <string, List <string> >(); StringPool pool = new StringPool(); // Normalize all translations (and entries, for good measure). // Also, pool them so that the "Contains" method of the List<string> works. foreach (Entry entry in firstSection) { entry.Phrase = pool.Pool(entry.Phrase.Normalize()); foreach (Translation t in entry.Translations) { t.Value = pool.Pool(t.Value.Normalize()); } } // Perform the actual reversion. foreach (Entry entry in firstSection) { foreach (Translation t in entry.Translations) { List <string> reverse; if (entries.TryGetValue(t.Value, out reverse)) { if (!reverse.Contains(entry.Phrase)) { reverse.Add(entry.Phrase); } } else { reverse = new List <string>(); entries.Add(t.Value, reverse); if (!reverse.Contains(entry.Phrase)) { reverse.Add(entry.Phrase); } } } } // Convert it into a list. List <Entry> list = new List <Entry>(); foreach (KeyValuePair <string, List <string> > kv in entries) { var translations = new List <Translation>(); Entry e = new Entry(kv.Key, translations); foreach (string t in kv.Value) { translations.Add(new Translation(t)); } // Sort the list of translations in each entry. translations.Sort((a, b) => a.Value.CompareTo(b.Value)); list.Add(e); } // Sort the list of entries. list.Sort((a, b) => (a.Phrase.CompareTo(b.Phrase))); SimpleDictionary.Section section = new SimpleDictionary.Section(list, true, null); foreach (var e in list) { e.Tag = new EntryTag(section, null); } return(section); }