blob: 9f6850e5508c71ea919acc0d63a103bf13f9544f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cctype>
#include <algorithm>
#include <sstream>
#include <ignite/binary/binary.h>
#include <ignite/common/utils.h>
#include "impl/utility.h"
namespace ignite
{
namespace impl
{
namespace thin
{
namespace utility
{
bool ParseSingleAddress(const std::string& value, network::TcpRange& tcpRange, uint16_t dfltPort)
{
int64_t colonNum = std::count(value.begin(), value.end(), ':');
if (colonNum == 0)
{
tcpRange.host = value;
tcpRange.port = dfltPort;
tcpRange.range = 0;
return true;
}
if (colonNum != 1)
return false;
size_t colonPos = value.find(':');
tcpRange.host = value.substr(0, colonPos);
if (colonPos == value.size() - 1)
return false;
std::string portRange = value.substr(colonPos + 1);
return ParsePortRange(portRange, tcpRange.port, tcpRange.range);
}
void ParseAddress(
const std::string& value,
std::vector<network::TcpRange>& endPoints,
uint16_t dfltPort)
{
size_t addrNum = std::count(value.begin(), value.end(), ',') + 1;
endPoints.reserve(endPoints.size() + addrNum);
std::string parsedAddr(value);
while (!parsedAddr.empty())
{
size_t addrBeginPos = parsedAddr.rfind(',');
if (addrBeginPos == std::string::npos)
addrBeginPos = 0;
else
++addrBeginPos;
const char* addrBegin = parsedAddr.data() + addrBeginPos;
const char* addrEnd = parsedAddr.data() + parsedAddr.size();
std::string addr = common::StripSurroundingWhitespaces(addrBegin, addrEnd);
if (!addr.empty())
{
network::TcpRange tcpRange;
bool success = ParseSingleAddress(addr, tcpRange, dfltPort);
if (success)
endPoints.push_back(tcpRange);
}
if (!addrBeginPos)
break;
parsedAddr.erase(addrBeginPos - 1);
}
}
bool ParsePortRange(const std::string& value, uint16_t& port, uint16_t& range)
{
size_t sepPos = value.find('.');
if (sepPos == std::string::npos)
{
range = 0;
port = ParsePort(value);
return port != 0;
}
if (sepPos + 2 > value.size() || value[sepPos + 1] != '.')
return false;
uint16_t rangeBegin = ParsePort(value.substr(0, sepPos));
if (!rangeBegin)
return false;
uint16_t rangeEnd = ParsePort(value.substr(sepPos + 2));
if (!rangeEnd)
return false;
if (rangeEnd < rangeBegin)
return false;
port = rangeBegin;
range = rangeEnd - rangeBegin;
return true;
}
uint16_t ParsePort(const std::string& value)
{
std::string port = common::StripSurroundingWhitespaces(value.begin(), value.end());
if (!common::AllDigits(port))
return 0;
if (port.size() >= sizeof("65535"))
return 0;
int32_t intPort = 0;
std::stringstream conv;
conv << port;
conv >> intPort;
if (intPort <= 0 || intPort > 0xFFFF)
return 0;
return static_cast<uint16_t>(intPort);
}
IGNORE_SIGNED_OVERFLOW
int32_t GetCacheId(const char* cacheName)
{
if (!cacheName)
return 0;
int32_t hash = 0;
int i = 0;
while (cacheName[i])
{
hash = 31 * hash + cacheName[i];
++i;
}
return hash;
}
}
}
}
}