lipsync/trunk/Boare.Lib.AppUtil/MessageBody.cs

203 lines
8.4 KiB
C#

/*
* MessageBody.cs
* Copyright (c) 2008-2009 kbinani
*
* This file is part of Boare.Lib.AppUtil.
*
* Boare.Lib.AppUtil is free software; you can redistribute it and/or
* modify it under the terms of the BSD License.
*
* Boare.Lib.AppUtil 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace Boare.Lib.AppUtil {
public class MessageBody {
public string lang;
public string po_header = "";
public Dictionary<string, MessageBodyEntry> list = new Dictionary<string, MessageBodyEntry>();
public MessageBody( string lang_ ) {
lang = lang_;
}
public MessageBody( string lang, string[] ids, string[] messages ) {
this.lang = lang;
list = new Dictionary<string, MessageBodyEntry>();
for( int i = 0; i < ids.Length; i++ ) {
list.Add( ids[i], new MessageBodyEntry( messages[i], new string[] { } ) );
}
}
public MessageBody( string lang_, string file ) {
lang = lang_;
po_header = "";
using ( StreamReader sr = new StreamReader( file ) ) {
while ( sr.Peek() >= 0 ) {
string msgid;
string first_line = sr.ReadLine();
string[] location;
string last_line = ReadTillMessageEnd( sr, first_line, "msgid", out msgid, out location );
string msgstr;
string[] location_dumy;
last_line = ReadTillMessageEnd( sr, last_line, "msgstr", out msgstr, out location_dumy );
if ( msgid.Length > 0 ) {
if ( list.ContainsKey( msgid ) ) {
list[msgid] = new MessageBodyEntry( msgstr, location );
} else {
list.Add( msgid, new MessageBodyEntry( msgstr, location ) );
}
} else {
po_header = msgstr;
string[] spl = po_header.Split( new char[] { (char)0x0d, (char)0x0a }, StringSplitOptions.RemoveEmptyEntries );
po_header = "";
int count = 0;
foreach ( string line in spl ) {
string[] spl2 = line.Split( new char[] { ':' }, 2 );
if ( spl2.Length == 2 ) {
string name = spl2[0].Trim();
if ( name.ToLower() == "Content-Type".ToLower() ) {
po_header += (count == 0 ? "" : "\n") + "Content-Type: text/plain; charset=UTF-8";
} else if ( name.ToLower() == "Content-Transfer-Encoding".ToLower() ) {
po_header += (count == 0 ? "" : "\n") + "Content-Transfer-Encoding: 8bit";
} else {
po_header += (count == 0 ? "" : "\n") + line;
}
} else {
po_header += (count == 0 ? "" : "\n") + line;
}
count++;
}
}
}
}
#if DEBUG
Console.WriteLine( "MessageBody..ctor; po_header=" + po_header );
#endif
}
public string GetMessage( string id ) {
if ( list.ContainsKey( id ) ) {
string ret = list[id].Message;
if ( ret == "" ) {
return id;
} else {
return list[id].Message;
}
}
return id;
}
public MessageBodyEntry GetMessageDetail( string id ) {
if ( list.ContainsKey( id ) ) {
string ret = list[id].Message;
if ( ret == "" ) {
return new MessageBodyEntry( id, new string[] { } );
} else {
return list[id];
}
}
return new MessageBodyEntry( id, new string[] { } );
}
public void Write( string file ) {
using ( StreamWriter sw = new StreamWriter( file ) ) {
if ( po_header != "" ) {
sw.WriteLine( "msgid \"\"" );
sw.WriteLine( "msgstr \"\"" );
string[] spl = po_header.Split( new char[] { (char)0x0d, (char)0x0a }, StringSplitOptions.RemoveEmptyEntries );
foreach ( string line in spl ) {
sw.WriteLine( "\"" + line + "\\" + "n\"" );
}
sw.WriteLine();
} else {
sw.WriteLine( "msgid \"\"" );
sw.WriteLine( "msgstr \"\"" );
sw.WriteLine( "\"Content-Type: text/plain; charset=UTF-8\\" + "n\"" );
sw.WriteLine( "\"Content-Transfer-Encoding: 8bit\\" + "n\"" );
sw.WriteLine();
}
foreach ( string key in list.Keys ) {
string skey = key.Replace( "\n", "\\n\"\n\"" );
string s = list[key].Message;
List<string> location = list[key].Location;
for ( int i = 0; i < location.Count; i++ ) {
sw.WriteLine( "#: " + location[i] );
}
sw.WriteLine( "msgid \"" + skey + "\"" );
s = s.Replace( "\n", "\\n\"\n\"" );
sw.WriteLine( "msgstr \"" + s + "\"" );
sw.WriteLine();
}
}
}
private static void SeparateEntryAndMessage( string source, out string entry, out string message ) {
string line = source.Trim();
entry = "";
message = "";
if ( line.Length <= 0 ) {
return;
}
int index_space = line.IndexOf( ' ' );
int index_dquoter = line.IndexOf( '"' );
int index = Math.Min( index_dquoter, index_space );
entry = line.Substring( 0, index );
message = line.Substring( index_dquoter + 1 );
message = message.Substring( 0, message.Length - 1 );
}
private static string ReadTillMessageEnd( StreamReader sr, string first_line, string entry, out string msg, out string[] locations ) {
msg = "";
string line = first_line;
List<string> location = new List<string>();
bool entry_found = false;
if ( line.StartsWith( entry ) ) {
// 1行目がすでに"entry"の行だった場合
string dum, dum2;
SeparateEntryAndMessage( line, out dum, out dum2 );
msg += dum2;
} else {
while ( true ) {
if ( line.StartsWith( "#:" ) ) {
line = line.Substring( 2 ).Trim();
location.Add( line );
} else if ( line.StartsWith( entry ) ) {
string dum, dum2;
SeparateEntryAndMessage( line, out dum, out dum2 );
msg += dum2;
break;
}
if ( sr.Peek() >= 0 ) {
line = sr.ReadLine();
} else {
break;
}
}
}
locations = location.ToArray();
string ret = "";
while ( sr.Peek() >= 0 ) {
line = sr.ReadLine();
if ( !line.StartsWith( "\"" ) ) {
msg = msg.Replace( "\\\"", "\"" );
msg = msg.Replace( "\\n", "\n" );
return line;
}
int index = line.LastIndexOf( "\"" );
msg += line.Substring( 1, index - 1 );
}
msg = msg.Replace( "\\\"", "\"" );
msg = msg.Replace( "\\n", "\n" );
return line;
}
}
}