Esempio n. 1
0
// -------------------------------------------------------------------
bool
PosixRegEx::execute(MatchArray &sub, const String &str,
               size_t index, size_t count, int eflags)
{
	if( !compiled)
	{
		BLOCXX_THROW(RegExCompileException,
			"Regular expression is not compiled");
	}

	if( index > str.length())
	{
		BLOCXX_THROW(OutOfBoundsException,
			Format("String index out of bounds ("
			       "length = %1, index = %2).",
			       str.length(), index
			).c_str());
	}

	if( count == 0)
	{
		count = m_regex.re_nsub + 1;
	}
	AutoPtrVec<regmatch_t> rsub(new regmatch_t[count]);
	rsub[0].rm_so = -1;
	rsub[0].rm_eo = -1;

	sub.clear();
	m_ecode = ::regexec(&m_regex, str.c_str() + index,
	                    count, rsub.get(), eflags);
	if( m_ecode == REG_NOERROR)
	{
		m_error.erase();
		if( m_flags & REG_NOSUB)
		{
			return true;
		}

		sub.resize(count);
		for(size_t n = 0; n < count; n++)
		{
			if( rsub[n].rm_so < 0 || rsub[n].rm_eo < 0)
			{
				sub[n] = rsub[n];
			}
			else
			{
				rsub[n].rm_so += index;
				rsub[n].rm_eo += index;
				sub[n] = rsub[n];
			}
		}
		return true;
	}
	else
	{
		m_error = getError(&m_regex, m_ecode);
		return false;
	}
}
Esempio n. 2
0
// -------------------------------------------------------------------
StringArray
PosixRegEx::split(const String &str, bool empty, int eflags)
{
	if( !compiled)
	{
		BLOCXX_THROW(RegExCompileException,
			"Regular expression is not compiled");
	}

	MatchArray  rsub;
	StringArray ssub;
	bool        match;
	size_t      off = 0;
	size_t      len = str.length();

	do
	{
		match = execute(rsub, str, off, 1, eflags);
		if( match)
		{
			if( rsub.empty()      ||
			    rsub[0].rm_so < 0 ||
			    rsub[0].rm_eo < 0)
			{
				BLOCXX_THROW(RegExCompileException,
					"Non-capturing regular expression");
			}

			if( empty || ((size_t)rsub[0].rm_so > off))
			{
				ssub.push_back(str.substring(off,
				                   rsub[0].rm_so - off));
			}
			off = rsub[0].rm_eo;
		}
		else if(m_ecode == REG_NOMATCH)
		{
			String tmp = str.substring(off);
			if( empty || !tmp.empty())
			{
				ssub.push_back(tmp);
			}
			m_ecode = REG_NOERROR;
			m_error.erase();
		}
		else
		{
			BLOCXX_THROW_ERR(RegExExecuteException,
				errorString().c_str(), m_ecode);
		}
	} while(match && len > off);

	return ssub;
}
Esempio n. 3
0
// -------------------------------------------------------------------
blocxx::String
PosixRegEx::replace(const String &str, const String &rep,
                    bool global, int eflags)
{
	if( !compiled)
	{
		BLOCXX_THROW(RegExCompileException,
			"Regular expression is not compiled");
	}

	MatchArray  rsub;
	bool        match;
	size_t      off = 0;
	String      out = str;

	do
	{
		match = execute(rsub, out, off, 0, eflags);
		if( match)
		{
			if( rsub.empty()      ||
			    rsub[0].rm_so < 0 ||
			    rsub[0].rm_eo < 0)
			{
				// only if empty (missused as guard).
				BLOCXX_THROW(RegExCompileException,
					"Non-capturing regular expression");
			}

			String res = substitute_caps(rsub, out, rep);

			out = out.substring(0, rsub[0].rm_so) +
			      res + out.substring(rsub[0].rm_eo);

			off = rsub[0].rm_so + res.length();
		}
		else if(m_ecode == REG_NOMATCH)
		{
			m_ecode = REG_NOERROR;
			m_error.erase();
		}
		else
		{
			BLOCXX_THROW_ERR(RegExExecuteException,
				errorString().c_str(), m_ecode);
		}
	} while(global && match && out.length() > off);

	return out;
}
void
GenericRWLockImpl<IdT, CompareT>::acquireReadLock(const IdT id, const Timeout& timeout)
{
	TimeoutTimer timer(timeout);

	NonRecursiveMutexLock l(m_guard);
	typename IdMap::iterator info = m_lockerInfo.find(id);

	if (info != m_lockerInfo.end())
	{
		LockerInfo& ti(info->second);
		// id already have a read or write lock, so just increment.
		BLOCXX_ASSERT(ti.isReader() || ti.isWriter());
		++ti.readCount;
		return;
	}

	// id is a new reader
	while (!m_canRead || m_numWriters > 0)
	{
		if (!m_waiting_readers.timedWait(l, timer.asAbsoluteTimeout()))
		{
			BLOCXX_THROW(TimeoutException, "Timeout while waiting for read lock.");
		}
	}

	// Increase the reader count
	LockerInfo lockerInfo;
	lockerInfo.readCount = 1;
	lockerInfo.writeCount = 0;
	m_lockerInfo.insert(typename IdMap::value_type(id, lockerInfo));

	++m_numReaders;
}
void throwNULLException()
{
#ifdef BLOCXX_DEBUG
	abort(); // segfault so we can get a core
#endif
	BLOCXX_THROW(NULLReferenceException, "NULL Reference dereferenced");
}
void
GenericRWLockImpl<IdT, CompareT>::releaseReadLock(const IdT id)
{
	NonRecursiveMutexLock l(m_guard);

	typename IdMap::iterator pInfo = m_lockerInfo.find(id);

	if (pInfo == m_lockerInfo.end() || !pInfo->second.isReader())
	{
		BLOCXX_THROW(GenericRWLockImplException, "Cannot release a read lock when no read lock is held");
	}

	LockerInfo& info(pInfo->second);
	--info.readCount;

	if (!info.isWriter() && !info.isReader())
	{
		--m_numReaders;
		if (m_numReaders == 0)
		{
			// This needs to wake them all up. In the case where one thread is waiting to upgrade a read to a write lock
			// and others are waiting to get a write lock, we have to wake up the thread trying to upgrade.
			m_waiting_writers.notifyAll();
		}
		m_lockerInfo.erase(pInfo);
	}
}
Esempio n. 7
0
// -------------------------------------------------------------------
StringArray
PosixRegEx::capture(const String &str, size_t index, size_t count, int eflags)
{
	if( !compiled)
	{
		BLOCXX_THROW(RegExCompileException,
			"Regular expression is not compiled");
	}

	MatchArray  rsub;
	StringArray ssub;

	bool match = execute(rsub, str, index, count, eflags);
	if( match)
	{
		if( rsub.empty())
		{
			BLOCXX_THROW(RegExCompileException,
				"Non-capturing regular expression");
		}

		MatchArray::const_iterator i=rsub.begin();
		for( ; i != rsub.end(); ++i)
		{
			if( i->rm_so >= 0 && i->rm_eo >= 0)
			{
				ssub.push_back(str.substring(i->rm_so,
			                       i->rm_eo - i->rm_so));
			}
			else
			{
				ssub.push_back(String(""));
			}
		}
	}
	else if(m_ecode != REG_NOMATCH)
	{
		BLOCXX_THROW_ERR(RegExExecuteException,
			errorString().c_str(), m_ecode);
	}
	return ssub;
}
Esempio n. 8
0
AutoDescriptor receiveDescriptor(Descriptor streamPipe)
{
	size_t const BUFSZ = 512;
	char errbuf[BUFSZ];
	AutoDescriptor d = receiveDescriptor(streamPipe, errbuf, BUFSZ);
	if (d.get() < 0)
	{
		BLOCXX_THROW(IOException, errbuf);
	}
	return d;
}
//////////////////////////////////////////////////////////////////////////////
// STATIC
void
verifySignature(std::streambuf & istrm, UInt8 validSig)
{
	UInt8 val;
	read(istrm, val);
	if (val != validSig)
	{
		BLOCXX_THROW(BadSignatureException,
			Format("Received invalid signature. Got: %1 Expected: %2", Int32(val),
				Int32(validSig)).c_str());
	}
}
Esempio n. 10
0
// -------------------------------------------------------------------
bool
PosixRegEx::match(const String &str, size_t index, int eflags) const
{
	if( !compiled)
	{
		BLOCXX_THROW(RegExCompileException,
			"Regular expression is not compiled");
	}

	if( index > str.length())
	{
		BLOCXX_THROW(OutOfBoundsException,
			Format("String index out of bounds ("
			       "length = %1, index = %2).",
			       str.length(), index
			).c_str());
	}

	m_ecode = ::regexec(&m_regex, str.c_str() + index,
	                    0, NULL, eflags);

	if( m_ecode == REG_NOERROR)
	{
		m_error.erase();
		return true;
	}
	else if(m_ecode == REG_NOMATCH)
	{
		m_error = getError(&m_regex, m_ecode);
		return false;
	}
	else
	{
		m_error = getError(&m_regex, m_ecode);
		BLOCXX_THROW_ERR(RegExExecuteException,
			errorString().c_str(), m_ecode);
	}
}
//////////////////////////////////////////////////////////////////////////////
// STATIC
void
read(std::streambuf & istrm, void * dataIn, size_t dataInLen)
{
	std::streamsize cnt = dataInLen;
#ifdef BLOCXX_WIN32
// VC10 warns that sgetn is unsafe.
#pragma warning(push)
#pragma warning(disable:4996)
#endif
	if (istrm.sgetn(static_cast<char *>(dataIn), cnt) != cnt)
#ifdef BLOCXX_WIN32
#pragma warning(pop)
#endif
	{
		BLOCXX_THROW(IOException, "Failed reading data");
	}
}
Esempio n. 12
0
IPCMutex::IPCMutex(int semKey)
{
	m_sbuf.sem_num = 0;
	m_sbuf.sem_flg = 0;
	m_semid = semget((key_t)semKey, 1, 0666);
	if (m_semid == -1)
	{
		m_semid = semget((key_t)semKey, 1, IPC_CREAT | 0666);
		if (m_semid == -1)
		{
			BLOCXX_THROW(IPCMutexException,
						 "Unable to create semaphore");
			return;
		}
		m_arg.val = 1;
		if (semctl(m_semid, 0, SETVAL, m_arg) != 0)
		{
			BLOCXX_THROW_ERRNO_MSG(IPCMutexException,
				"semctl() failed");
		}
	}
}
Esempio n. 13
0
void
GenericRWLockImpl<IdT, CompareT>::releaseWriteLock(const IdT id)
{
	NonRecursiveMutexLock l(m_guard);

	typename IdMap::iterator pInfo = m_lockerInfo.find(id);

	if (pInfo == m_lockerInfo.end() || !pInfo->second.isWriter())
	{
		BLOCXX_THROW(GenericRWLockImplException, "Cannot release a write lock when no write lock is held");
	}

	LockerInfo& ti(pInfo->second);

	BLOCXX_ASSERT(ti.isWriter());

	--ti.writeCount;

	if (!ti.isWriter())
	{
		--m_numWriters;

		BLOCXX_ASSERT(m_numWriters == 0);

		m_canRead = true;
		if (ti.isReader())
		{
			// restore reader status
			++m_numReaders;
		}
		else
		{
			// This id no longer holds locks.
			m_waiting_writers.notifyOne();
			m_lockerInfo.erase(pInfo);
		}
		m_waiting_readers.notifyAll();
	}
}
Esempio n. 14
0
// -------------------------------------------------------------------
StringArray
PosixRegEx::grep(const StringArray &src, int eflags)
{
	if( !compiled)
	{
		BLOCXX_THROW(RegExCompileException,
			"Regular expression is not compiled");
	}

	m_ecode = REG_NOERROR;
	m_error.erase();

	StringArray out;
	if( !src.empty())
	{
		StringArray::const_iterator i=src.begin();
		for( ; i != src.end(); ++i)
		{
			int ret = ::regexec(&m_regex, i->c_str(),
			                    0, NULL, eflags);
			if( ret == REG_NOERROR)
			{
				out.push_back(*i);
			}
			else if(ret != REG_NOMATCH)
			{
				m_ecode = ret;
				m_error = getError(&m_regex, m_ecode);
				BLOCXX_THROW_ERR(RegExExecuteException,
					errorString().c_str(), m_ecode);
			}
		}
	}

	return out;
}
Esempio n. 15
0
size_t Format::process(String& str, size_t minArg, size_t maxArg, FormatFlags& flags, FormatErrorHandling errortype)
{
	size_t len(str.length());
	size_t c = static_cast<size_t>(-1);
	bool err = false;
	size_t i = 0;
	size_t percentStart = 0;
	for (; (i < len) && (c == size_t(-1)) && !err; ++i)
	{
		if( str[i] == '%' )
		{
			percentStart = i;
			if (i + 1 < len)
			{
				++i;

				if( str[i] == '%' )
				{
					oss.append('%');
				}
				else if( str[i] == BRACE_OPEN )
				{
					if( !processFormatSpecifier(str, i, c, flags) )
					{
						// No close brace or some other error.
						err = true;
					}
					else
					{
						// Incremented next loop.
						--i;
					}
				}
				else if( isdigit(str[i]) )
				{
					c = str[i] - '0';
				}
				else
				{
					// Random junk after '%'
					err = true;
				}
			}
			else
			{
				err = true;
			}
		}
		else // anything other than a '%'
		{
			oss.append(str[i]);
		}
	} // for
	if ( (i <= len) && (c != size_t(-1)))
	{
		if( c > maxArg )
		{
			String error = String("Parameter specifier ") + c + " is too large (>" + maxArg + ")";

			if( errortype == E_FORMAT_EXCEPTION )
			{
				BLOCXX_THROW(FormatException, error.c_str());
			}
			oss.append("\n*** " + error);
			err = true;
		}
		else if( c < minArg )
		{
			String error = String("Parameter specifier ") + c + " must be >= " + minArg;
			if( errortype == E_FORMAT_EXCEPTION )
			{
				BLOCXX_THROW(FormatException, error.c_str());
			}
			oss.append("\n*** " + error);

			err = true;
		}
	}
	if (err)
	{
		// Print the percent and all of the text causing the error.
		size_t textlength = std::max(i, percentStart + 1) - percentStart;

		String error = "Error in format string at \"" + str.substring(percentStart, textlength) + "\"";

		if( errortype == E_FORMAT_EXCEPTION )
		{
			BLOCXX_THROW(FormatException, error.c_str());
		}
		oss.append("\n*** " + error + "\n");
		str.erase();
		return '0';
	}
	str.erase(0, i);

	return c;
} // process
Esempio n. 16
0
static inline void
throwStringConversion(const char* str, const char* type)
{
	BLOCXX_THROW(StringConversionException, Format("Unable to convert \"%1\" into %2", str, type).c_str());
}
Esempio n. 17
0
static inline void
throwStringConversion(const String::buf_t& m_buf, const char* type)
{
	BLOCXX_THROW(StringConversionException, Format("Unable to convert \"%1\" into %2", m_buf->data(), type).c_str());
}
Esempio n. 18
0
void
GenericRWLockImpl<IdT, CompareT>::acquireWriteLock(const IdT id, const Timeout& timeout)
{
	// 7 cases:
	// 1. No id has the lock
	//   Get the lock
	// 2. This id has the write lock
	//   Increment the lock count
	// 3. Another id has the write lock & other ids may be waiting for read and/or write locks.
	//   Block until the lock is acquired.
	// 4. Only this id has a read lock
	//   Increment the write lock count .
	// 5. >0 other ids have the read lock & other ids may be waiting for write locks.
	//   Block until the write lock is acquired.
	// 6. This id and other ids have the read lock
	//   Block new readers and writers and wait until existing readers finish.
	// 7. This id and other ids have the read lock and one of the other ids has requested a write lock.
	//   Throw an exception.

	TimeoutTimer timer(timeout);

	NonRecursiveMutexLock l(m_guard);

	typename IdMap::iterator pInfo = m_lockerInfo.find(id);
	if (pInfo != m_lockerInfo.end())
	{
		// This id already has some sort of lock
		LockerInfo& ti(pInfo->second);
		BLOCXX_ASSERT(ti.isReader() || ti.isWriter());

		if (!ti.isWriter())
		{
			// The id is upgrading

			BLOCXX_ASSERT(m_numWriters == 0 || m_numWriters == 1);
			if (m_numWriters == 1)
			{
				// another id beat us to upgrading the write lock.  Throw an exception.
				BLOCXX_THROW(DeadlockException, "Upgrading read lock to a write lock failed, another upgrade is already in progress.");
			}

			// switch from being a reader to a writer
			--m_numReaders;
			// mark us as a writer, this will prevent other ids from becoming a writer
			++m_numWriters;

			// This thread isn't the only reader. Wait for others to finish.
			while (m_numReaders != 0)
			{
				// stop new readers - inside while loop, because it may get reset by other ids releasing locks.
				m_canRead = false;

				if (!m_waiting_writers.timedWait(l, timer.asAbsoluteTimeout()))
				{
					// undo changes
					++m_numReaders;
					--m_numWriters;
					m_canRead = true;
					if (m_numWriters == 0)
					{
						m_waiting_readers.notifyAll();
					}
					BLOCXX_THROW(TimeoutException, "Timeout while waiting for write lock.");
				}
			}
		}
		++ti.writeCount;

	}
	else
	{
		// This id doesn't have any lock

		while (m_numReaders != 0 || m_numWriters != 0)
		{
			// stop new readers
			m_canRead = false;

			if (!m_waiting_writers.timedWait(l, timer.asAbsoluteTimeout()))
			{
				m_canRead = true;
				if (m_numWriters == 0)
				{
					m_waiting_readers.notifyAll();
				}
				BLOCXX_THROW(TimeoutException, "Timeout while waiting for write lock.");
			}
		}

		LockerInfo ti;
		ti.readCount = 0;
		ti.writeCount = 1;
		m_lockerInfo.insert(typename IdMap::value_type(id, ti));
		++m_numWriters;
		m_canRead = false;
	}

}