瀏覽代碼

Implemented readDelimited.


git-svn-id: https://svn.microneil.com/svn/CodeDweller/branches/adeniz_1@86 d34b734f-a00e-4b39-a726-e4eeb87269ab
adeniz_1
adeniz 9 年之前
父節點
當前提交
fc9f4057e6
共有 1 個文件被更改,包括 173 次插入43 次删除
  1. 173
    43
      child.hpp

+ 173
- 43
child.hpp 查看文件

@@ -473,25 +473,6 @@ namespace CodeDweller {
*/
void put(char const *ptr, size_t nBytes);

/** Check whether specified data is present in the buffer.

This method check whether the specified data is present in
the buffer, and provides the number of characters before the
specified data.

@param[in] delimiter is the specified data.

@param[out] nBytesBefore is the number of bytes before the
specified data.

@returns true if the delimiter is present in the buffer,
false otherwise.

*/
template<type U>
bool checkForDelimiter(U &delimiter, size_t &nbytesBefore) {
}

/** Get bytes from the buffer.

This method gets the specified number of bytes from the
@@ -539,6 +520,58 @@ namespace CodeDweller {

}

/** Check whether specified data is present in the buffer.

This method check whether the specified data is present in
the buffer, and provides the number of characters before the
specified data.

The type U must have the following methods:

<ol>

<li>Methods required by CircularBuffer::match().</li>

<li>size().</li>

</ol>

Both std::vector<char> and std::string can be used for T.

@param[in] data is the specified data.

@param[out] nBytesBefore is the number of bytes before the
specified data.

@returns true if the data is present in the buffer, false
otherwise.

@see CircularBuffer::match().

*/
template<typename U>
bool dataIsPresent(U const &data, size_t &nBytesBefore) const {

size_t iLocalBegin = iBegin;

if (nUsed() < data.size()) {
return false;
}

size_t nToCheck = nUsed() - data.size() + 1;
for (nBytesBefore = 0; nBytesBefore < nToCheck; nBytesBefore++) {

if (match(data, iLocalBegin)) {
return true;
}

nextIndex(iLocalBegin);
}

return false;

}

private:

/** Increment the index.
@@ -552,6 +585,50 @@ namespace CodeDweller {
index = 0;
}


/** Check whether the specified data is in the buffer.

This method checks whether the specified data is present in
the buffer starting at the specified location.

The type U must have the following methods:

<ol>

<li>operator[].</li>

<li>size().</li>

</ol>

@param[in] data is the specified data.

@param[in] index is the index of the buffer to start
checking for the specified data.

@returns true if the specified data is in the buffer, false
otherwise.

*/
template<typename U>
bool match(U &data, size_t indx) const {

for (size_t i = 0; i < data.size(); i++) {

if (iEnd == indx) {
return false;
}
if (data[i] != buffer[indx]) {
return false;
}
nextIndex(indx);

}

return true;

}

/// Buffer to hold data.
std::vector<char> buffer;

@@ -950,6 +1027,20 @@ namespace CodeDweller {

<li>size().</li>

<li>clear().</li>

</ol>

The type U must have the following methods:

<ol>

<li>Methods required by CircularBuffer::dataIsPresent().</li>

<li>size().</li>

<li>empty().</li>

</ol>

Both std::vector<char> and std::string can be used for T and U.
@@ -962,9 +1053,11 @@ namespace CodeDweller {

@see CircularBuffer::getAndErase().

@see CircularBuffer::dataIsPresent().

*/
template<typename T, typename U>
bool readDelimited(T &data, U &delimiter) {
bool readDelimited(T &data, U const &delimiter) {

if (!isRunning()) {
throw std::logic_error("No child process is running.");
@@ -977,20 +1070,74 @@ namespace CodeDweller {
return false;
}

// Empty delimiter always matches.
if (delimiter.empty()) {
return true;
}

std::lock_guard<std::mutex> lock(readBufferMutex);

size_t nBytesToRead = nBytes;
size_t nBytesToRead;

if (nBytesToRead > readBuffer.nUsed()) {
nBytesToRead = readBuffer.nUsed();
// Check for the presence of the delimiter.
if (!readBuffer.dataIsPresent(delimiter, nBytesToRead)) {
return false;
}
readBuffer.getAndErase(data, nBytesToRead);

return data.size();
// Read the data.
if (nBytesToRead > 0) {
readBuffer.getAndErase(data, nBytesToRead);
}

// Discard the delimiter.
T temp;

readBuffer.getAndErase(temp, delimiter.size());

return true;

}


/** Non-blocking request to get data up to a delimiter read from
the child.

This method check whether the specified delimiter is in the
data received from the child.

This method attempts to get data up to and not including a
specified delimiter from the input buffer containing data
received from the child. The data that is provided and the
delimiter are erased from the input buffer.

The type T must have the following methods:

<ol>

<li>Methods required by CircularBuffer::getAndErase().</li>

<li>size().</li>

<li>clear().</li>

</ol>

Both std::vector<char> and std::string can be used for T.

@param[out] data contains the copied data.

@param[in] delimiter contains the delimiter.

@returns the number of bytes copied.

@see CircularBuffer::getAndErase().

*/
template<typename T>
bool readDelimited(T &data, char const *delimiter) {
return readDelimited(data, std::string(delimiter));
}

/** Check whether the child process is running.

\returns True if the child process is running, false
@@ -1064,23 +1211,6 @@ namespace CodeDweller {
*/
void run();

/** Non-blocking request to get data read from the child.

This method attempts to get up to a specified number of bytes
of data from the input buffer containing data received from
the child. The data that is provided is erased from the input
buffer.

@param[in, out] dataPtr points to the memory that receives the
data.

@param[in] nBytes is the number of bytes to attempt to copy.

@returns the number of bytes copied.

*/
size_t read(char *const dataPtr, size_t nBytes);

/// Reader thread object.
std::thread readerThread;


Loading…
取消
儲存