Make codecs able to tell their name
authorMikko Rasa <tdb@tdb.fi>
Thu, 25 Dec 2008 08:57:28 +0000 (08:57 +0000)
committerMikko Rasa <tdb@tdb.fi>
Thu, 25 Dec 2008 08:57:28 +0000 (08:57 +0000)
Support autodetecting the correct codec for a string

source/ascii.h
source/codec.cpp
source/codec.h
source/iso2022jp.h
source/iso646fi.h
source/iso88591.h
source/iso885915.h
source/jisx0201.h
source/jisx0208.h
source/utf8.h
source/windows1252.h

index 7dc8762980c10a0553cc42054a546a5a6e1811f2..ecff0dbf96e31bc3aaa6801716323142a9418faf 100644 (file)
@@ -32,8 +32,10 @@ public:
                virtual UnicodeChar decode_char(const std::string &, std::string::const_iterator &);
        };
 
-       Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
-       Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
+       virtual const char *get_name() const { return "ASCII"; }
+
+       virtual Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
+       virtual Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
 };
 
 } // namespace Codecs
index 865176edf2a8cb5223e721cdb6040a0511b4acd3..521dfea2094c3eb2c8a0cffe96eca98c54fb4c70 100644 (file)
@@ -102,9 +102,53 @@ Codec *create_codec(const string &n)
        if(name=="jisx0201") return new JisX0201;
        if(name=="jisx0208") return new JisX0208;
        if(name=="utf8") return new Utf8;
-       if(name=="windows1252") return new Windows1252;
+       if(name=="windows1252" || name=="cp1252") return new Windows1252;
        throw InvalidParameterValue("Unknown string codec");
 }
 
+Codec *detect_codec(const string &str)
+{
+       bool is_utf8=true;
+       bool is_ascii=true;
+       bool is_latin1=true;
+       unsigned utf8_mb=0;
+
+       for(string::const_iterator i=str.begin(); i!=str.end(); ++i)
+       {
+               unsigned char c=*i;
+               if(c&0x80)
+               {
+                       is_ascii=false;
+                       if((c&0xC0)==0x80)
+                       {
+                               if((c&0xE0)==0x80)
+                                       is_latin1=false;
+                               if(utf8_mb)
+                                       --utf8_mb;
+                               else
+                                       is_utf8=false;
+                       }
+                       else if((c&0xC0)==0xC0)
+                       {
+                               if(utf8_mb)
+                                       is_utf8=false;
+                               else
+                               {
+                                       for(utf8_mb=1; (c>>(6-utf8_mb))&1; ++utf8_mb) ;
+                               }
+                       }
+               }
+       }
+
+       if(is_ascii)
+               return new Ascii;
+       else if(is_utf8)
+               return new Utf8;
+       else if(is_latin1)
+               return new Iso88591;
+       else
+               return new Windows1252;
+}
+
 } // namespace Codecs
 } // namespace Msp
index bb35b0b43528ca4eba14dc66682f43ae26bca651..d3737400803b700a8dd325cf5283e9adb660422d 100644 (file)
@@ -160,6 +160,11 @@ public:
 
        virtual ~Codec() { }
 
+       /**
+       Returns the name of the encoding handled by this codec.
+       */
+       virtual const char *get_name() const =0;
+
        /**
        Creates an encoder for this codec.
        */
@@ -231,6 +236,12 @@ deleting the codec when it's no longer needed.
 */
 Codec *create_codec(const std::string &);
 
+/**
+Automatically detects the encoding of a string and creates a codec for it.
+The codec must be deleted when it's no longer needed.
+*/
+Codec *detect_codec(const std::string &);
+
 } // namespace Codecs
 } // namespace Msp
 
index f3c273669a67f62ffe24af0c13128fdaa3022a44..4a452d46d4bc04c5f384e12403381d1e29db39d5 100644 (file)
@@ -50,8 +50,10 @@ public:
                virtual void switch_mode(Mode);
        };
 
-       Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
-       Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
+       virtual const char *get_name() const { return "ISO-2022-JP"; }
+
+       virtual Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
+       virtual Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
 };
 
 } // namespace Codecs
index 8f38a29d5b399ccd2bd30d9079d91420869e46e7..3047edff021d030e0f655a3cc4d825050e736332 100644 (file)
@@ -32,8 +32,10 @@ public:
                virtual UnicodeChar decode_char(const std::string &, std::string::const_iterator &);
        };
 
-       Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
-       Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
+       virtual const char *get_name() const { return "ISO-646-FI"; }
+
+       virtual Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
+       virtual Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
 };
 
 } // namespace Codecs
index 1adf605fce3e040176f469871b100e601a91b1e7..80c706be25211b8814f645347c54135925f8a8c9 100644 (file)
@@ -32,8 +32,10 @@ public:
                virtual UnicodeChar decode_char(const std::string &, std::string::const_iterator &);
        };
 
-       Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
-       Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
+       virtual const char *get_name() const { return "ISO-8859-1"; }
+
+       virtual Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
+       virtual Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
 };
 
 } // namespace Codecs
index da2692263c8839acbc15a534eb6391a52eaad6fa..c42ad195bb3958c9318f5b94f4ec0a920958368e 100644 (file)
@@ -32,8 +32,10 @@ public:
                virtual UnicodeChar decode_char(const std::string &, std::string::const_iterator &);
        };
 
-       Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
-       Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
+       virtual const char *get_name() const { return "ISO-8859-15"; }
+
+       virtual Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
+       virtual Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
 };
 
 } // namespace Codecs
index 1c502f9da1516007882bd1f8f8c4c7dd3cb95fe8..180f710f3d87d1234ff3c129310032435ad4c8a0 100644 (file)
@@ -32,8 +32,10 @@ public:
                virtual UnicodeChar decode_char(const std::string &, std::string::const_iterator &);
        };
 
-       Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
-       Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
+       virtual const char *get_name() const { return "JIS X 0201"; }
+
+       virtual Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
+       virtual Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
 };
 
 } // namespace Codecs
index 9e9ff9bc97a6544061bc6b4b47ca0f0b1600ecdd..27609e619ddc1dcd3e0669e98f0cd26090b18548 100644 (file)
@@ -37,8 +37,10 @@ public:
                virtual UnicodeChar decode_char(const std::string &, std::string::const_iterator &);
        };
 
-       Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
-       Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
+       virtual const char *get_name() const { return "JIS X 0208"; }
+
+       virtual Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
+       virtual Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
 };
 
 struct Kuten
index 70d44b00840b3d29f39d651e652388c1466b4bfc..0e5e0689cea37fae94670d6747b11a23103f44db 100644 (file)
@@ -32,8 +32,10 @@ public:
                virtual UnicodeChar decode_char(const std::string &, std::string::const_iterator &);
        };
 
-       Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
-       Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
+       virtual const char *get_name() const { return "UTF-8"; }
+
+       virtual Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
+       virtual Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
 };
 
 } // namespace Codecs
index 9f0fe0b447809deb0fcb601dff48117164491805..f817a0d2e10c68cb577a074d3645bce2ae3d84d7 100644 (file)
@@ -32,8 +32,10 @@ public:
                virtual UnicodeChar decode_char(const std::string &, std::string::const_iterator &);
        };
 
-       Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
-       Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
+       virtual const char *get_name() const { return "Windows-1252"; }
+
+       virtual Encoder *create_encoder(ErrorMode em=THROW_ON_ERROR) const { return new Encoder(em); }
+       virtual Decoder *create_decoder(ErrorMode em=THROW_ON_ERROR) const { return new Decoder(em); }
 };
 
 } // namespace Codecs