VOID CALLBACK file_system_watcher::path_watcher::completion( 
	DWORD dwErrorCode, 
	DWORD dwNumberOfBytesTransfered, 
	LPOVERLAPPED lpOverlapped )
{
	// Retrieve the path_watcher pointer (essentially making this function pseudo-non-static)
	auto pw = static_cast<path_watcher*>(lpOverlapped->hEvent);

	// The watch is over...
	if (ERROR_OPERATION_ABORTED == dwErrorCode) {
		// ...so signal that the completion routine has been called the last time.
		pw->terminated = true;
		return;
	}

	// Any error (including buffer overflows) are silently ignored
	if (dwErrorCode || 0 == dwNumberOfBytesTransfered) return;

	// Process the linked list of notifications
	auto fni = static_cast<FILE_NOTIFY_INFORMATION*>(pw->buffer);
	do 
	{
		static_assert(sizeof(wchar_t) == sizeof(WCHAR), "size of wchar_t does not equal size of WCHAR");

		auto size = WideCharToMultiByte(CP_UTF8, 0, fni->FileName, fni->FileNameLength / sizeof(WCHAR), NULL, 0, 0, 0);
		auto string_buffer = std::make_unique<char[]>(size);
		WideCharToMultiByte(CP_UTF8, 0, fni->FileName, fni->FileNameLength / sizeof(WCHAR), string_buffer.get(), size, 0, 0);
		pw->fsw->modified_paths.push(path(string_buffer.get(), &string_buffer[size]));

		fni = reinterpret_cast<FILE_NOTIFY_INFORMATION*>(reinterpret_cast<char*>(fni) + fni->NextEntryOffset);
	} while (0 < fni->NextEntryOffset);

	// Reissue the watcher
	pw->read_changes();
}
////////////////////////////////////////////////////////////////////////////////
/// Path Watcher
////////////////////////////////////////////////////////////////////////////////
file_system_watcher::path_watcher::path_watcher( 
	file_system_watcher* fsw,
	const path& path_,
	const filter filter_ )
	: fsw{fsw}
	, filter_{filter_}
	, win_filters{0}
{
	if (INVALID_HANDLE_VALUE == (directory_or_file_handle = CreateFile(
		path_.string().c_str(),
		FILE_LIST_DIRECTORY,
		FILE_SHARE_READ	| FILE_SHARE_WRITE | FILE_SHARE_DELETE,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
		NULL)))
		throw std::system_error(
			GetLastError(), 
			std::system_category(), 
			error_message{last});

	buffer = _aligned_malloc(buffer_size, sizeof(DWORD));

	std::fill_n(reinterpret_cast<char*>(&over), sizeof(OVERLAPPED), 0);
	over.hEvent = static_cast<HANDLE>(this);

	if (filter::write & filter_) win_filters |= FILE_NOTIFY_CHANGE_LAST_WRITE;
	if (filter::access & filter_) win_filters |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
	if (filter::file_name & filter_) win_filters |= FILE_NOTIFY_CHANGE_FILE_NAME;

	read_changes();
}
Example #3
0
int main()
{
    string s;
    char c;
    int nlines;
    int i, j;
    int pos;

    read_changes();
    scanf("%d\n", &nlines);
    for (i = 1; i <= nlines; i++) {
        j = 0;
        while ((c = getchar()) != '\n') {
            s[j] = c;
            j++;
        }
        s[j] = '\0';

        for (j = 0; j < nmergers; j++)
            while ((pos = findmatch(mergers[j][0], s)) != -1) {
                replace_x_with_y(s, pos,
                        strlen(mergers[j][0]), mergers[j][1]);
            }
        printf("%s\n", s);
    }

    return 0;
}