#include "ValidationUtils.h"
#include <ctype.h>
#include <UnicodeChar.h>
#define MIN_LENGTH_NICKNAME 4
#define MAX_LENGTH_NICKNAME 32
#define MIN_LENGTH_PASSWORD_CLEAR 8
#define MIN_UPPER_PASSWORD_CLEAR 1
#define MIN_DIGITS_PASSWORD_CLEAR 2
static int
hd_is_email_domain_or_mailbox_part(int c)
{
if (0 == isspace(c) && c != 0x40)
return 1;
return 0;
}
static int
hd_is_lower_alnum(int c)
{
if ((c >= 0x30 && c <= 0x39) || (c >= 0x60 && c <= 0x7a))
return 1;
return 0;
}
static bool
hd_str_all_matches_fn(const BString& string, int (*hd_match_c)(int c))
{
const char* c = string.String();
for (int32 i = 0; i < string.CountChars(); i++) {
if (0 == hd_match_c(c[i]))
return false;
}
return true;
}
static int32
hd_str_count_upper_case(const BString& string)
{
int32 upperCaseLetters = 0;
const char* c = string.String();
for (int32 i = 0; i < string.CountChars(); i++) {
uint32 unicodeChar = BUnicodeChar::FromUTF8(&c);
if (BUnicodeChar::IsUpper(unicodeChar))
upperCaseLetters++;
}
return upperCaseLetters;
}
static int32
hd_str_count_digit(const BString& string)
{
int32 digits = 0;
const char* c = string.String();
for (int32 i = 0; i < string.CountChars(); i++) {
uint32 unicodeChar = BUnicodeChar::FromUTF8(&c);
if (BUnicodeChar::IsDigit(unicodeChar))
digits++;
}
return digits;
}
bool
ValidationUtils::IsValidNickname(const BString& value)
{
return hd_str_all_matches_fn(value, &hd_is_lower_alnum)
&& value.CountChars() >= MIN_LENGTH_NICKNAME
&& value.CountChars() <= MAX_LENGTH_NICKNAME;
}
bool
ValidationUtils::IsValidEmail(const BString& value)
{
const char* c = value.String();
size_t len = strlen(c);
bool foundAt = false;
for (size_t i = 0; i < len; i++) {
if (c[i] == 0x40 && !foundAt) {
if (i == 0 || i == len - 1)
return false;
foundAt = true;
}
else {
if (0 == hd_is_email_domain_or_mailbox_part(c[i]))
return false;
}
}
return foundAt;
}
bool
ValidationUtils::IsValidPasswordClear(const BString& value)
{
return value.Length() >= MIN_LENGTH_PASSWORD_CLEAR
&& hd_str_count_digit(value) >= MIN_DIGITS_PASSWORD_CLEAR
&& hd_str_count_upper_case(value) >= MIN_UPPER_PASSWORD_CLEAR;
}