幾つかメソッドを追加してみた

Javaの標準にあるInetAddressクラスの中で利用できるメソッドの幾つかをAddrInfoクラスに実装してみました。
実装したのは、

getAllByName(String hostname)
パラメータで渡したホスト名(hostname)からIPアドレスリストを取得する。
getByName(String hostname)
パラメータで渡したホスト名(hostname)からIPアドレスを取得する。
getNetworkAddress(String hostaddr, String netmask)
パラメータで渡したホストアドレス(hostaddr)とネットマスク(netmask)からネットワークアドレスを計算する。
isAddrInNetwork(String base, String mask, String target)
パラメータで渡したホストアドレスorネットワークアドレス(base)とネットマスク(mask)と同じネットワークに指定したIPアドレス(target)が含まれるか計算する。

の、4つのメソッドです。


以前のAddrInfoクラスは、IfInfo用のJNIからデータを格納するためだけのクラスとして用意されていたため、時にAddrInfoクラスとしてのJNIの実装がかかれていなかったので、
AddrInfo.javaに初期化の処理を追加すると共に、次のようにスタティックメソッドを追加しました。

    static {
        System.loadLibrary("jninet");
        init();
    }

    private static native void init();
    public static native String[] getAllByName(String hostname);
    public static native String getByName(String hostname);
    public static native String getNetworkAddress(String hostaddr, String netmask);
    public static native boolean isAddrInNetwork(String base, String mask, String target);

何時もの様にコンパイル後、ヘッダファイルを作成。
それで前には必要なかったJNIの実装を追加します。
AddrInfo.hと

#ifndef _JNI_ADDRINFO_CALL
#define _JNI_ADDRINFO_CALL

#include <windows.h>

#include "addrinfo.h"
using namespace penguin;

#include "net_AddrInfo.h"

jclass      str_class;          /* String */

#endif  //  _JNI_ADDRINFO_CALL

AddrInfo.cppを

#include "jniaddrinfo.h"

String jStringToString(JNIEnv *env, jstring j_string) {
    const jchar *words = env->GetStringChars(j_string, NULL);
    _bstr_t orginal = _bstr_t((wchar_t *)words);
    env->ReleaseStringChars(j_string, words);
    String c_string = String((_TCHAR *)orginal);
    return c_string;
}

JNIEXPORT void JNICALL Java_net_AddrInfo_init(JNIEnv *env, jclass cls) {
    jclass c = env->FindClass("java/lang/String");
    str_class = (jclass)env->NewGlobalRef(c);
    env->DeleteLocalRef(c);
}

JNIEXPORT jobjectArray JNICALL Java_net_AddrInfo_getAllByName(JNIEnv *env, jclass cls, jstring hostname) {
    jobjectArray ai_list = NULL;

    String hostname_value = jStringToString(hostname);
    address_list list = AddrInfo::getAllByName(hostname_value);
    if (!list.empty()) {
        jsize ai_count = (jsize)list.size();
        if (ai_count > 0) {
            ai_list = env->NewObjectArray(ai_count, str_class, NULL);
            for (jsize i = 0; i < ai_count; i++) {
                AddrInfo addr = list.at(i);
                String address_value = addr.getIpAddress();
                _bstr_t address_str = _bstr_t((_TCHAR *)address_value.c_str());
                jobject address = env->NewString((const jchar *)((wchar_t *)address_str), (jsize)address_str.length());
                env->SetObjectArrayElement(ai_list, i, address);
            }
        }
        list.clear();
    }
    return ai_list;
}

JNIEXPORT jstring JNICALL Java_net_AddrInfo_getByName(JNIEnv *env, jclass cls, jstring hostname) {
    jstring one_address = NULL;

    String hostname_value = jStringToString(hostname);
    String address_value = AddrInfo::getByName(hostname_value);
    _bstr_t address_str = _bstr_t((_TCHAR *)address_value.c_str());
    one_address = env->NewString((const jchar *)((wchar_t *)address_str), (jsize)address_str.length());
    return one_address;
}

JNIEXPORT jstring JNICALL Java_net_AddrInfo_getNetworkAddress (JNIEnv *env, jclass cls, jstring hostaddr, jstring netmask) {
    jstring one_address = NULL;

    String hostaddr_value = jStringToString(hostaddr);
    String netmask_value = jStringToString(netmask);
    String address_value = AddrInfo::getNetworkAddress(hostaddr_value, netmask_value);
    _bstr_t address_str = _bstr_t((_TCHAR *)address_value.c_str());
    one_address = env->NewString((const jchar *)((wchar_t *)address_str), (jsize)address_str.length());
    return one_address;
}

JNIEXPORT jboolean JNICALL Java_net_AddrInfo_isAddrInNetwork(JNIEnv *env, jclass cls, jstring base, jstring mask, jstring target) {

    String base_value = jStringToString(base);
    String mask_value = jStringToString(mask);
    String target_value = jStringToString(target);
    return (jboolean)AddrInfo::isAddrInNetwork(base_value, mask_value, target_value);
}

実装しました。


後はJavaからのテストで

    String[] addrs = AddrInfo.getAllByName("www.google.co.jp");
    for (int i = 0; i < addrs.length; i++) {
        System.out.println("Google addrs "+i+" = "+addrs[i]);
    }
    
    String netAddr = AddrInfo.getNetworkAddress("172.16.255.1", "255.255.255.0");
    System.out.println("Network address = "+netAddr);
    
    if (AddrInfo.isAddrInNetwork("172.16.255.0", "255.255.255.0", "172.16.255.1"))
        System.out.println("Network address is local");
    else
        System.out.println("Network address is not local");

で確認してOkでした。