]> git.tdb.fi Git - libs/core.git/blobdiff - source/iso2022jp.cpp
More sophisticated error handling
[libs/core.git] / source / iso2022jp.cpp
index 6f83bd95645ae543117dee6146c5e8b6a3bcf7bc..5a51a648b3e9e5012154aa6195ebda2cb95412b1 100644 (file)
@@ -7,8 +7,11 @@ using namespace std;
 
 namespace Msp {
 
-void Iso2022Jp::Encoder::encode_char(wchar_t c)
+void Iso2022Jp::Encoder::encode_char(wchar_t c_)
 {
+       // Win32 has typedef unsigned short wchar_t
+       int c=c_;
+
        if(c>=0 && c<=0x7F && c!=0x5C && c!=0x7E)
        {
                if(mode!=ASCII && mode!=JISX0201)
@@ -34,12 +37,24 @@ void Iso2022Jp::Encoder::encode_char(wchar_t c)
        {
                unsigned short jis=ucs_to_jisx0208(c);
                if(!jis)
-                       throw CodecError("Can't express character in ISO-2022-JP");
-               if(mode!=JISX0208)
-                       switch_mode(JISX0208);
+                       error("Can't express character in ISO-2022-JP");
+               else
+               {
+                       if(mode!=JISX0208)
+                               switch_mode(JISX0208);
+
+                       char buf[2]={jis>>8, jis};
+                       append(buf, 2);
+               }
        }
 }
 
+void Iso2022Jp::Encoder::sync()
+{
+       if(mode!=ASCII)
+               switch_mode(ASCII);
+}
+
 void Iso2022Jp::Encoder::switch_mode(Mode m)
 {
        mode=m;
@@ -51,7 +66,15 @@ void Iso2022Jp::Encoder::switch_mode(Mode m)
        }
 }
 
-Iso2022Jp::Decoder::Decoder():
+void Iso2022Jp::Encoder::append_replacement()
+{
+       if(mode!=ASCII)
+               switch_mode(ASCII);
+       append(032);
+}
+
+Iso2022Jp::Decoder::Decoder(ErrorMode em):
+       StringCodec::Decoder(em),
        mode(ASCII),
        dec(new Ascii::Decoder),
        escape(0)
@@ -63,7 +86,7 @@ void Iso2022Jp::Decoder::decode_char(const string &str, string::const_iterator &
        {
                if(escape)
                {
-                       escape=escape<<8 | (unsigned char)*i;
+                       escape=escape<<8 | static_cast<unsigned char>(*i);
                        if(*i>='@' && *i<='Z')
                        {
                                switch(escape)
@@ -72,7 +95,7 @@ void Iso2022Jp::Decoder::decode_char(const string &str, string::const_iterator &
                                case 0x1B284A: switch_mode(JISX0201); break; // ESC ( J
                                case 0x1B2440:                               // ESC $ @
                                case 0x1B2442: switch_mode(JISX0208); break; // ESC $ B
-                               default: throw CodecError("Invalid ISO-2022-JP escape sequence");
+                               default: error("Invalid ISO-2022-JP escape sequence");
                                }
                                escape=0;
                        }
@@ -94,11 +117,21 @@ void Iso2022Jp::Decoder::decode_char(const string &str, string::const_iterator &
 void Iso2022Jp::Decoder::sync()
 {
        if(escape)
-               throw CodecError("Sync in middle of ISO-2022-JP escape sequence");
+       {
+               error("Sync in middle of ISO-2022-JP escape sequence");
+               escape=0;
+       }
+       
        if(mode!=ASCII)
-               throw CodecError("Sync while not in ASCII mode");
-       append(dec->get());
-       dec->flush();
+       {
+               error("Sync while not in ASCII mode");
+               switch_mode(ASCII);
+       }
+       else
+       {
+               append(dec->get());
+               dec->flush();
+       }
 }
 
 void Iso2022Jp::Decoder::switch_mode(Mode m)