bool ConditionVariable::timed_wait(Mutex::UniqueLock &lock, unsigned long long ms){ assert(lock.m_locked); ::timespec tp; if(::clock_gettime(CLOCK_MONOTONIC, &tp) != 0){ const int err = errno; LOG_POSEIDON_ERROR("::clock_gettime() failed with error code ", err); DEBUG_THROW(SystemException, err); } tp.tv_sec += static_cast<std::time_t>(ms / 1000); tp.tv_nsec += static_cast<long>(ms % 1000 * 1000000); if(tp.tv_nsec >= 1000000000){ ++tp.tv_sec; tp.tv_nsec -= 1000000000; } const int err = ::pthread_cond_timedwait(&(m_impl->cond), reinterpret_cast< ::pthread_mutex_t *>(lock.m_owner->m_impl.get()), &tp); if(err != 0){ if(err == ETIMEDOUT){ return false; } LOG_POSEIDON_ERROR("::pthread_cond_timedwait() failed with error code ", err); DEBUG_THROW(SystemException, err); } return true; }
int SockAddr::getFamily() const { const AUTO(p, reinterpret_cast<const ::sockaddr *>(m_data)); if(m_size < sizeof(p->sa_family)){ LOG_POSEIDON_ERROR("Invalid SockAddr: size = ", m_size); DEBUG_THROW(Exception, sslit("Invalid SockAddr")); } return p->sa_family; }
SocketServerBase::SocketServerBase(UniqueFile socket) : m_socket(STD_MOVE(socket)), m_local_info(get_local_ip_port_from_fd(m_socket.get())) { const int flags = ::fcntl(m_socket.get(), F_GETFL); if(flags == -1){ const int code = errno; LOG_POSEIDON_ERROR("Could not get fcntl flags on socket."); DEBUG_THROW(SystemException, code); } if(::fcntl(m_socket.get(), F_SETFL, flags | O_NONBLOCK) != 0){ const int code = errno; LOG_POSEIDON_ERROR("Could not set fcntl flags on socket."); DEBUG_THROW(SystemException, code); } LOG_POSEIDON_INFO("Created socket server, local = ", m_local_info); }
SockAddr::SockAddr(const void *data, unsigned size){ if(size > sizeof(m_data)){ LOG_POSEIDON_ERROR("SockAddr size too large: ", size); DEBUG_THROW(Exception, sslit("SockAddr size too large")); } m_size = size; std::memcpy(m_data, data, size); }
bool CsvParser::loadNoThrow(const char *file){ try { load(file); return true; } catch(std::exception &e){ LOG_POSEIDON_ERROR("Error loading CSV file: ", e.what()); return false; } }
long ClientWriter::put_chunk(StreamBuffer entity){ PROFILE_ME; if(entity.empty()){ LOG_POSEIDON_ERROR("You are not allowed to send an empty chunk"); DEBUG_THROW(BasicException, sslit("You are not allowed to send an empty chunk")); } StreamBuffer chunk; char temp[64]; unsigned len = (unsigned)std::sprintf(temp, "%llx\r\n", (unsigned long long)entity.size()); chunk.put(temp, len); chunk.splice(entity); chunk.put("\r\n"); return on_encoded_data_avail(STD_MOVE(chunk)); }
SockAddr getSockAddrFromIpPort(const IpPort &addr){ ::sockaddr_in sin; if(::inet_pton(AF_INET, addr.ip.get(), &sin.sin_addr) == 1){ sin.sin_family = AF_INET; storeBe(sin.sin_port, addr.port); return SockAddr(&sin, sizeof(sin)); } ::sockaddr_in6 sin6; if(::inet_pton(AF_INET6, addr.ip.get(), &sin6.sin6_addr) == 1){ sin6.sin6_family = AF_INET6; storeBe(sin6.sin6_port, addr.port); return SockAddr(&sin6, sizeof(sin6)); } LOG_POSEIDON_ERROR("Unknown address format: ", addr.ip); DEBUG_THROW(Exception, sslit("Unknown address format")); }
void CsvParser::load(const char *file){ LOG_POSEIDON_DEBUG("Loading CSV file: ", file); StreamBuffer buffer; fileGetContents(buffer, file); buffer.put('\n'); std::vector<OptionalMap> data; std::vector<std::vector<std::string> > rows; { std::vector<std::string> row; std::string token; bool first = true; bool inQuote = false; do { char ch = buffer.get(); if(ch == '\r'){ if(buffer.peek() == '\n'){ buffer.get(); } ch = '\n'; } if(first){ first = false; if(ch == '\"'){ inQuote = true; continue; } } if(ch == '\"'){ if(inQuote){ if(buffer.peek() == '\"'){ buffer.get(); token.push_back('\"'); } else { inQuote = false; } continue; } } if(!inQuote){ if((ch == ',') || (ch == '\n')){ std::string trimmed; const std::size_t begin = token.find_first_not_of(" \t\r\n"); if(begin != std::string::npos){ const std::size_t end = token.find_last_not_of(" \t\r\n") + 1; trimmed = token.substr(begin, end - begin); } row.push_back(STD_MOVE(trimmed)); token.clear(); first = true; if(ch == '\n'){ rows.push_back(STD_MOVE(row)); row.clear(); } continue; } } token.push_back(ch); } while(!buffer.empty()); } if(rows.empty() || rows.front().empty()){ LOG_POSEIDON_ERROR("The first line of a CSV file may not be empty."); DEBUG_THROW(Exception, sslit("Bad CSV header")); } const std::size_t columnCount = rows.front().size(); std::vector<SharedNts> keys(columnCount); for(std::size_t i = 0; i < columnCount; ++i){ AUTO_REF(key, rows.front().at(i)); for(std::size_t j = 0; j < i; ++j){ if(keys.at(j) == key){ LOG_POSEIDON_ERROR("Duplicate key: ", key); DEBUG_THROW(Exception, sslit("Duplicate key")); } } keys.at(i).assign(key.c_str()); } for(std::size_t i = 1; i < rows.size(); ++i){ rows.at(i - 1).swap(rows.at(i)); } rows.pop_back(); { std::size_t line = 1; std::size_t i = 0; while(i < rows.size()){ AUTO_REF(row, rows.at(i)); ++line; if((row.size() == 1) && row.front().empty()){ for(std::size_t j = i + 1; j < rows.size(); ++j){ rows.at(j - 1).swap(rows.at(j)); } rows.pop_back(); continue; } if(row.size() != columnCount){ LOG_POSEIDON_ERROR("There are ", row.size(), " column(s) on line ", line, " but there are ", columnCount, " in the header"); DEBUG_THROW(Exception, sslit("Inconsistent CSV column numbers")); } ++i; } } const std::size_t rowCount = rows.size(); data.resize(rowCount); for(std::size_t i = 0; i < rowCount; ++i){ AUTO_REF(row, rows.at(i)); AUTO_REF(map, data.at(i)); for(std::size_t j = 0; j < columnCount; ++j){ map.create(keys.at(j))->second.swap(row.at(j)); } } LOG_POSEIDON_DEBUG("Done loading CSV file: ", file); m_data.swap(data); m_row = static_cast<std::size_t>(-1); }