diff --git a/src/net/i2p/android/i2ptunnel/activity/TunnelWizardModel.java b/src/net/i2p/android/i2ptunnel/activity/TunnelWizardModel.java index 0f2651a722905032f12eeaa52ae25a51252d9169..27abeaf4ac5d11146287845408126e5e20b45023 100644 --- a/src/net/i2p/android/i2ptunnel/activity/TunnelWizardModel.java +++ b/src/net/i2p/android/i2ptunnel/activity/TunnelWizardModel.java @@ -6,6 +6,7 @@ import net.i2p.android.router.R; import net.i2p.android.wizard.model.AbstractWizardModel; import net.i2p.android.wizard.model.BranchPage; import net.i2p.android.wizard.model.Conditional; +import net.i2p.android.wizard.model.I2PDestinationPage; import net.i2p.android.wizard.model.PageList; import net.i2p.android.wizard.model.SingleFixedBooleanPage; import net.i2p.android.wizard.model.SingleFixedChoicePage; @@ -57,7 +58,7 @@ public class TunnelWizardModel extends AbstractWizardModel { new SingleTextFieldPage(this, res.getString(R.string.i2ptunnel_wizard_k_desc)) .setDescription(res.getString(R.string.i2ptunnel_wizard_desc_desc)), - new SingleTextFieldPage(this, res.getString(R.string.i2ptunnel_wizard_k_dest)) + new I2PDestinationPage(this, res.getString(R.string.i2ptunnel_wizard_k_dest)) .setDescription(res.getString(R.string.i2ptunnel_wizard_desc_dest)) .setRequired(true) .setEqualAnyCondition(cClientType, diff --git a/src/net/i2p/android/wizard/model/I2PDestinationPage.java b/src/net/i2p/android/wizard/model/I2PDestinationPage.java new file mode 100644 index 0000000000000000000000000000000000000000..4ca8e0b5bc7ec900e778a02266d21be751733c60 --- /dev/null +++ b/src/net/i2p/android/wizard/model/I2PDestinationPage.java @@ -0,0 +1,54 @@ +package net.i2p.android.wizard.model; + +import java.util.Locale; + +import net.i2p.data.DataFormatException; +import net.i2p.data.Destination; + +/** + * A page asking for an I2P Destination. + * This could be a B64, B32 or Addressbook domain. + */ +public class I2PDestinationPage extends SingleTextFieldPage { + private static final int BASE32_HASH_LENGTH = 52; // 1 + Hash.HASH_LENGTH * 8 / 5 + private String mFeedback; + + public I2PDestinationPage(ModelCallbacks callbacks, String title) { + super(callbacks, title); + } + + @Override + public boolean isValid() { + String data = mData.getString(SIMPLE_DATA_KEY); + if (data.toLowerCase(Locale.US).endsWith(".b32.i2p")) { /* B32 */ + if (data.length() != BASE32_HASH_LENGTH + 8) { + mFeedback = "Invalid B32"; + return false; + } + } else if (data.endsWith(".i2p")) { /* Domain */ + // Valid + } else if (data.length() >= 516) { /* B64 */ + try { + new Destination().fromBase64(data); + } catch (DataFormatException dfe) { + mFeedback = "Invalid B64"; + return false; + } + } else { + mFeedback = "Not a valid I2P Destination"; + return false; + } + mFeedback = ""; + return true; + } + + @Override + public boolean showFeedback() { + return true; + } + + @Override + public String getFeedback() { + return mFeedback; + } +}