// Saves catalog to file. //FIXME: escape all the values that the parser unescapes //FIXME: use a StreamWriter instead of a StringBuilder public bool Save(string poFile) { StringBuilder sb = new StringBuilder(); // Update information about last modification time: RevisionDate = Catalog.GetDateTimeRfc822Format(); // Save .po file if (String.IsNullOrEmpty(Charset) || Charset == "CHARSET") { Charset = "utf-8"; } if (!CanEncodeToCharset(Charset)) { // TODO: log that we don't support such encoding, utf-8 would be used Charset = "utf-8"; } Encoding encoding = Catalog.GetEncoding(Charset); if (!String.IsNullOrEmpty(Comment)) { Catalog.SaveMultiLines(sb, Comment, originalNewLine); } sb.AppendFormat("msgid \"\"{0}", originalNewLine); sb.AppendFormat("msgstr \"\"{0}", originalNewLine); string pohdr = GetHeaderString(originalNewLine); pohdr = pohdr.Substring(0, pohdr.Length - 1); Catalog.SaveMultiLines(sb, pohdr, originalNewLine); sb.Append(originalNewLine); foreach (CatalogEntry data in entriesList) { if (data.Comment != String.Empty) { SaveMultiLines(sb, data.Comment, originalNewLine); } foreach (string autoComment in data.AutoComments) { if (String.IsNullOrEmpty(autoComment)) { sb.AppendFormat("#.{0}", originalNewLine); } else { sb.AppendFormat("#. {0}{1}", autoComment, originalNewLine); } } foreach (string reference in data.References) { //store paths as Unix-type paths, but internally use native style string r = reference; if (Platform.IsWindows) { r = r.Replace('\\', '/'); } sb.AppendFormat("#: {0}{1}", r, originalNewLine); } if (!String.IsNullOrEmpty(data.Flags)) { sb.Append(data.Flags); sb.Append(originalNewLine); } FormatMessageForFile(sb, "msgid", data.String, originalNewLine); if (data.HasPlural) { FormatMessageForFile(sb, "msgid_plural", data.PluralString, originalNewLine); for (int n = 0; n < data.NumberOfTranslations; n++) { string hdr = String.Format("msgstr[{0}]", n); FormatMessageForFile(sb, hdr, EnsureCorrectEndings(data.String, data.GetTranslation(n)), originalNewLine); } } else { FormatMessageForFile(sb, "msgstr", EnsureCorrectEndings(data.String, data.GetTranslation(0)), originalNewLine); } sb.Append(originalNewLine); } // Write back deleted items in the file so that they're not lost foreach (CatalogDeletedEntry deletedItem in deletedEntriesList) { if (deletedItem.Comment != String.Empty) { SaveMultiLines(sb, deletedItem.Comment, originalNewLine); } foreach (string autoComment in deletedItem.AutoComments) { sb.AppendFormat("#. {0}{1}", autoComment, originalNewLine); } foreach (string reference in deletedItem.References) { sb.AppendFormat("#: {0}{1}", reference, originalNewLine); } string flags = deletedItem.Flags; if (!String.IsNullOrEmpty(flags)) { sb.Append(flags); sb.Append(originalNewLine); } foreach (string deletedLine in deletedItem.DeletedLines) { sb.AppendFormat("{0}{1}", deletedLine, originalNewLine); } sb.Append(originalNewLine); } bool saved = false; try { //FIXME: use a safe write, i.e. write to another file and move over the original one // Write it as bytes, text writer includes BOF for utf-8, // gettext utils are refusing to work with this byte[] content = encoding.GetBytes(sb.ToString()); File.WriteAllBytes(poFile, content); saved = true; } catch (Exception ex) { LoggingService.LogError("Unhandled error saving Gettext Catalog '{0}': {1}", fileName, ex); } if (!saved) { return(false); } fileName = poFile; IsDirty = false; return(true); }
// Saves catalog to file. //FIXME: escape all the values that the parser unescapes public bool Save(string poFile) { StreamWriter sw; // Update information about last modification time: RevisionDate = Catalog.GetDateTimeRfc822Format(); // Save .po file if (String.IsNullOrEmpty(Charset) || Charset == "CHARSET") { Charset = "utf-8"; } if (!CanEncodeToCharset(Charset)) { // TODO: log that we don't support such encoding, utf-8 would be used Charset = "utf-8"; } Encoding encoding = Catalog.GetNoBOMEncoding(Charset); int fileCounter = 0; string tempFileName = ""; // get a temp file in same directory as original try { do { fileCounter++; tempFileName = poFile + fileCounter.ToString(); } while (File.Exists(tempFileName)); sw = new StreamWriter(tempFileName, false, encoding); } catch (Exception ex) { LoggingService.LogError("Unhandled error creating temp file while saving Gettext catalog '{0}': {1}", tempFileName, ex); return(false); } using (sw) // careful not to use sw outside using block { sw.NewLine = originalNewLine; if (!String.IsNullOrEmpty(Comment)) { Catalog.SaveMultiLines(sw, Comment); } sw.WriteLine("msgid \"\""); sw.WriteLine("msgstr \"\""); string pohdr = GetHeaderString(originalNewLine); pohdr = pohdr.Substring(0, pohdr.Length - 1); Catalog.SaveMultiLines(sw, pohdr); sw.WriteLine(); foreach (CatalogEntry data in entriesList) { if (data.Comment != String.Empty) { SaveMultiLines(sw, data.Comment); } foreach (string autoComment in data.AutoComments) { if (String.IsNullOrEmpty(autoComment)) { sw.WriteLine("#."); } else { sw.WriteLine("#. {0}", autoComment); } } foreach (string reference in data.References) { //store paths as Unix-type paths, but internally use native style string r = reference; if (Platform.IsWindows) { r = r.Replace('\\', '/'); } sw.WriteLine("#: {0}", r); } if (!String.IsNullOrEmpty(data.Flags)) { sw.WriteLine(data.Flags); } FormatMessageForFile(sw, "msgid", data.String); if (data.HasPlural) { FormatMessageForFile(sw, "msgid_plural", data.PluralString); for (int n = 0; n < data.NumberOfTranslations; n++) { string hdr = String.Format("msgstr[{0}]", n); FormatMessageForFile(sw, hdr, EnsureCorrectEndings(data.String, data.GetTranslation(n))); } } else { FormatMessageForFile(sw, "msgstr", EnsureCorrectEndings(data.String, data.GetTranslation(0))); } sw.WriteLine(); } // Write back deleted items in the file so that they're not lost foreach (CatalogDeletedEntry deletedItem in deletedEntriesList) { if (deletedItem.Comment != String.Empty) { SaveMultiLines(sw, deletedItem.Comment); } foreach (string autoComment in deletedItem.AutoComments) { sw.WriteLine("#. {0}", autoComment); } foreach (string reference in deletedItem.References) // note references arnt read in during parse { sw.WriteLine("#: {0}", reference); } string flags = deletedItem.Flags; if (!String.IsNullOrEmpty(flags)) { sw.WriteLine(flags); } foreach (string deletedLine in deletedItem.DeletedLines) { sw.WriteLine("{0}", deletedLine); } sw.WriteLine(); } } //try to replace original file bool saved = false; try { File.Copy(tempFileName, poFile, true); saved = true; } catch (Exception ex) { LoggingService.LogError("Unhandled error saving Gettext Catalog to '{0}': {1}", poFile, ex); saved = false; } finally { File.Delete(tempFileName); } if (!saved) { return(false); } fileName = poFile; IsDirty = false; return(true); }