GradleでGoogleCodeプロジェクトを作ってみる – その2

2021-02-24Gradle,Groovy

はじめに

前回に引き続き、空のプロジェクトができたところからスタート。文字コード変換用のライブラリだが、判定ロジックなど僕のスキルでは書くことができないので以下のプロジェクトのリソースを拝借した。

こちらを、javaフォルダに配置。

gconv
   `-- src
   `-- main
   `-- java

次にjuniversalchardetのクラスのラッパーを作成。これでいかにも自分が作成したっぽくなる。バイト配列をもらって、それがどの文字コードであるかを自動判定する。(ただし、半角英数字のみの場合、うまく判定ができない。juniversalchardetの仕様の模様)

gconv
   `-- src
   `-- main
   `-- groovy
   `-- com
   `-- gmail
   `-- genzouw
   `-- gconv
   `-- Gconv.groovy

コーディング

Gconv.groovy

package com.gmail.genzouw.gconv
import org.mozilla.universalchardet.Constants

class Gconv{
    private detector = nullclass Charset{
        private Charset(){}
        static final String ISO_2022_JP = Constants.CHARSET_ISO_2022_JP
            static final String ISO_2022_CN = Constants.CHARSET_ISO_2022_CN
            static final String ISO_2022_KR = Constants.CHARSET_ISO_2022_KR
            static final String ISO_8859_5 = Constants.CHARSET_ISO_8859_5
            static final String ISO_8859_7 = Constants.CHARSET_ISO_8859_7
            static final String ISO_8859_8 = Constants.CHARSET_ISO_8859_8
            static final String BIG5 = Constants.CHARSET_BIG5
            static final String GB18030 = Constants.CHARSET_GB18030
            static final String EUC_JP = Constants.CHARSET_EUC_JP
            static final String EUC_KR = Constants.CHARSET_EUC_KR
            static final String EUC_TW = Constants.CHARSET_EUC_TW
            static final String SHIFT_JIS = Constants.CHARSET_SHIFT_JIS
            static final String IBM855 = Constants.CHARSET_IBM855
            static final String IBM866 = Constants.CHARSET_IBM866
            static final String KOI8_R = Constants.CHARSET_KOI8_R
            static final String MACCYRILLIC = Constants.CHARSET_MACCYRILLIC
            static final String WINDOWS_1251 = Constants.CHARSET_WINDOWS_1251
            static final String WINDOWS_1252 = Constants.CHARSET_WINDOWS_1252
            static final String WINDOWS_1253 = Constants.CHARSET_WINDOWS_1253
            static final String WINDOWS_1255 = Constants.CHARSET_WINDOWS_1255
            static final String UTF_8 = Constants.CHARSET_UTF_8
            static final String UTF_16BE = Constants.CHARSET_UTF_16BE
            static final String UTF_16LE = Constants.CHARSET_UTF_16LE
            static final String UTF_32BE = Constants.CHARSET_UTF_32BE
            static final String UTF_32LE    = Constants.CHARSET_UTF_32LE
    }
    private static Gconv SELF = new Gconv()
        private Gconv(){
            detector = new org.mozilla.universalchardet.UniversalDetector()
        }
    static Gconv getInstance(){
        SELF
    }
    String guess(byte[] bytes){
        detector.with{
            reset()
                handleData(bytes as byte[], 0, bytes.size())
                dataEnd()
        }
        detector.detectedCharset
    }
    byte[] gconv(byte[] bytes, outCode, inCode=null){
        if( !inCode ) {
            inCode = this.guess(bytes)
        }
        inCode ? new String(bytes, inCode).getBytes(outCode) : bytes
    }
    byte[] toEuc(byte[] bytes){
        this.gconv(bytes, Charset.EUC_JP)
    }
    byte[] toSjis(byte[] bytes){
        this.gconv(bytes, Charset.SHIFT_JIS)
    }
    byte[] toUtf8(byte[] bytes){
        this.gconv(bytes, Charset.UTF_8)
    }
    boolean isEuc(byte[] bytes){
        this.guess(bytes) == Charset.EUC_JP
    }
    boolean isSjis(byte[] bytes){
        this.guess(bytes) == Charset.SHIFT_JIS
    }
    boolean isUtf8(byte[] bytes){
        this.guess(bytes) == Charset.UTF_8
    }
}

テスト

testフォルダ以下にテストコードとテストに使用するリソースファイルを配置。

gconv
   `-- src
   |
   `-- test
   |-- groovy
   |   `-- com
   |       `-- gmail
   |           `-- genzouw
   |               `-- gconv
   |                   `-- GconvTest.groovy
   `-- resources
   `-- txt
   |-- euc.txt
   |-- iso2022jp.txt
   |-- shiftjis.txt
   |-- utf16le.txt
   |-- utf8.txt
   `-- utf8n.txt

GconvTest.groovy

package com.gmail.genzouw.gconv
import groovy.util.GroovyTestCase

class GconvTest extends GroovyTestCase {
    def gconv = nullvoid setUp(){
        gconv = Gconv.instance
    }
    void test_guess_utf8(){
        def utf8bytes = new File("src/test/resources/txt/utf8.txt").bytes
            assertEquals(Gconv.Charset.UTF_8, gconv.guess(utf8bytes))
    }
    void test_guess_euc(){
        def eucbytes = new File("src/test/resources/txt/euc.txt").bytes
            assertEquals(Gconv.Charset.EUC_JP, gconv.guess(eucbytes))
    }
    void test_guess_sjis(){
        def sjisbytes = new File("src/test/resources/txt/shiftjis.txt").bytes
            assertEquals(Gconv.Charset.SHIFT_JIS, gconv.guess(sjisbytes))
    }
    void test_isUtf8(){
        def bytes = new File("src/test/resources/txt/utf8.txt").bytes
            assertTrue(gconv.isUtf8(bytes))
            assertFalse(gconv.isEuc(bytes))
            assertFalse(gconv.isSjis(bytes))
    }
    void test_isEuc(){
        def bytes = new File("src/test/resources/txt/euc.txt").bytes
            assertFalse(gconv.isUtf8(bytes))
            assertTrue(gconv.isEuc(bytes))
            assertFalse(gconv.isSjis(bytes))
    }
    void test_isSjis(){
        def bytes = new File("src/test/resources/txt/shiftjis.txt").bytes
            assertFalse(gconv.isUtf8(bytes))
            assertFalse(gconv.isEuc(bytes))
            assertTrue(gconv.isSjis(bytes))
    }
    void test_fromEucToSjis_size(){
        def sjisbytes = new File("src/test/resources/txt/shiftjis.txt").bytes
            def eucbytes = new File("src/test/resources/txt/euc.txt").bytes
            assertEquals(sjisbytes, gconv.toSjis(eucbytes))
    }
    void test_resourcesValid(){
        def sjisbytes = new File("src/test/resources/txt/shiftjis.txt").bytes.toList()
            def eucbytes = new File("src/test/resources/txt/euc.txt").bytes.toList()
            def utf8bytes = new File("src/test/resources/txt/utf8.txt").bytes.toList()
            def utf8nbytes = new File("src/test/resources/txt/utf8n.txt").bytes.toList()
            assertFalse(sjisbytes == eucbytes)
            assertFalse(sjisbytes == utf8bytes)
            assertFalse(sjisbytes == utf8nbytes)
            assertFalse(utf8nbytes == eucbytes)
            assertFalse(utf8nbytes == utf8bytes)
            assertFalse(eucbytes == utf8bytes)
    }
}

ビルド

ビルドはGradleで行う。

以下のコマンドを実行。

$ gradle build
:compileJava
:compileGroovy
:processResources
:classes
:jar
:assemble
:compileTestJava
:compileTestGroovy
:processTestResources
:testClasses
:test
:check
:build
BUILD SUCCESSFUL

JUnitがインストールされていなくても動作はする。

Subversionへのコミット

変更内容をローカルGitへコミット。

$ git add .
$ git commit -m "文字コード判定、変換クラスGconvを追加。"

これをGoogle Code Subversionリポジトリへコミット。

$ git svn dcommit

無事コミットできた。今日はここまで。この後、Google Code上にGrapeを作ってgconvを利用できるように公開してみる。



2021-02-24Gradle,Groovy