/* * vislib::sys::Path::IsRelative */ bool vislib::sys::Path::IsRelative(const StringA& path) { #ifdef _WIN32 return (::PathIsRelativeA(path.PeekBuffer()) != FALSE) || path.IsEmpty() || ((path.PeekBuffer()[0] == SEPARATOR_A) && (path.PeekBuffer()[1] != SEPARATOR_A)); #else /* _WIN32 */ return !path.StartsWith(SEPARATOR_A); #endif /* _WIN32 */ }
/* * vislib::net::Socket::BindToDevice */ void vislib::net::Socket::BindToDevice(const StringA& name) { #ifndef _WIN32 struct ifreq interface; ::strncpy(interface.ifr_ifrn.ifrn_name, name.PeekBuffer(), name.Length() + 1); if (::setsockopt(this->handle, SOL_SOCKET, SO_BINDTODEVICE, &interface, sizeof(interface)) == -1) { throw SocketException(__FILE__, __LINE__); } #endif /* !_WIN32 */ }
/* * vislib::sys::Path::Concatenate */ vislib::StringA vislib::sys::Path::Concatenate(const StringA& lhs, const StringA& rhs, const bool canonicalise) { StringA retval(lhs); if (lhs.EndsWith(SEPARATOR_A) && rhs.StartsWith(SEPARATOR_A)) { retval.Append(rhs.PeekBuffer() + 1); } else if (!lhs.EndsWith(SEPARATOR_A) && !rhs.StartsWith(SEPARATOR_A)) { retval.Append(SEPARATOR_A); retval.Append(rhs); } else { retval.Append(rhs); } return canonicalise ? Path::Canonicalise(retval) : retval; }
/* * vislib::sys::Path::Canonicalise */ vislib::StringA vislib::sys::Path::Canonicalise(const StringA& path) { const StringA DOUBLE_SEPARATOR(Path::SEPARATOR_A, 2); #ifdef _WIN32 StringA retval; if (::PathCanonicalizeA(retval.AllocateBuffer(MAX_PATH), path) != TRUE) { throw SystemException(__FILE__, __LINE__); } retval.Replace(DOUBLE_SEPARATOR.PeekBuffer(), SEPARATOR_A); retval.Replace(DOUBLE_SEPARATOR.PeekBuffer(), SEPARATOR_A); /* Ensure that a UNC path remains a UNC path. */ if (path.StartsWith(DOUBLE_SEPARATOR)) { // Note: Double separator replacement above leaves at least one // separator, so we must only prepend one additional one. retval.Prepend(SEPARATOR_A); } return retval; #else /* _WIN32 */ const char *BACK_REF = "/.."; const char *CUR_REF = "/."; // Note: "./" does not work StringA::Size BACK_REF_LEN = ::strlen(BACK_REF); StringA::Size bwRefPos = 0; // Position of back reference. StringA::Size remDirPos = 0; // Position of directory to erase. StringA retval(path); /* Remove backward references, first. */ while ((bwRefPos = retval.Find(BACK_REF)) != StringA::INVALID_POS) { if ((bwRefPos > 0) && (remDirPos = retval.FindLast(SEPARATOR_A, bwRefPos - 1)) != StringA::INVALID_POS) { /* Found inner backward reference, so remove some parts. */ retval.Remove(remDirPos, bwRefPos - remDirPos + BACK_REF_LEN); } else { /* * No other path separator is before this one, so we can remove * everything before 'bwRefPos'. */ retval.Remove(0, bwRefPos + BACK_REF_LEN); } } /* * Remove references to the current directory. This must be done after * removing backward references. */ retval.Remove(CUR_REF); /* Remove odd and even number of repeated path separators. */ retval.Replace(DOUBLE_SEPARATOR.PeekBuffer(), SEPARATOR_A); retval.Replace(DOUBLE_SEPARATOR.PeekBuffer(), SEPARATOR_A); return retval; #endif /* _WIN32 */ }