Esempio n. 1
0
void ScanThread::saveChangesToDB()
{
    for (RecordData& data : changes_.added)
    {
        if (shouldBreak()) break;
        
        RecordID id = db_.add(std::move(data));
        eventSink_.push(ScanEvent{ ScanEvent::ADDED, std::move(id) });
    }
    
    for (Record& record : changes_.changed)
    {
        if (shouldBreak()) break;
        
        db_.replace(record.first, std::move(record.second));
        eventSink_.push(ScanEvent{ ScanEvent::UPDATED, std::move(record.first) });
    }
    
    for (RecordID& id : changes_.deleted)
    {
        if (shouldBreak()) break;
        
        db_.del(id);
    	eventSink_.push(ScanEvent{ ScanEvent::DELETED, std::move(id) });
    }
    
    if (shouldBreak()) return;
    
    changes_.clear();
    
    if (!eventSink_.empty())
    {
        onChangedDisp_();
    }
}
Esempio n. 2
0
void ScanThread::scanDirs()
{
    db_iterator const itDirsEnd = db_.dirs_end();
        
    for (db_iterator itDir = db_.dirs_begin(); 
         itDir != itDirsEnd && !shouldBreak(); 
                                      ++itDir)
    {
        checkDir(*itDir);
    }
}
Esempio n. 3
0
void ScanThread::scanDir(
            const RecordID& dirId, 
            EntriesIt itEntriesBegin, 
            EntriesIt itEntriesEnd)
{
	if (shouldBreak())
	{
		return;
	}
	
	Records oldRecords = db_.children(dirId);
	std::sort(oldRecords.begin(), oldRecords.end(), CmpByPath());
		
	auto entriesRange = boost::make_iterator_range(itEntriesBegin, itEntriesEnd);
	
	for (const auto& entry : entriesRange)
	{
		scanEntry(getPath(entry), dirId, oldRecords, isRecursive(entry));
		
		if (shouldBreak())
		{
			return;
		}
	}
	
	for (const Record& missing : oldRecords)
	{
		try
		{
            delEntry(missing.first);
		}
		catch(std::exception const& ex)
		{
			std::cerr << "Failed to delete DB record for '" 
					<< missing.second.header.fileName << "' entry: " 
					<< ex.what() << std::endl;
		}
	}
}
Esempio n. 4
0
int main(int argc, char* argv[]) {

	unsigned char ret;
	char c;
	char len;
	char i;
	char* annoyname = "Annoy_Light";
	char* stairname = "Stair_Light";

	DDRC = 0;
	PORTC = 0x7;
	unsigned char did = 1;

	// define direction of inputs and outputs
	// 1 for output, 0 for input
	// | for output, & for input
	DDRD = (1<<RELAY_STAIRS);
	DDRD |= (1<<RELAY_ANNOY);


	did = PINC & 0x7;

	serial_init();

	buf_index = 0;	
	transmit_flag = 0;	

//	FILE s=FDEV_SETUP_STREAM(send_char_serial,NULL,_FDEV_SETUP_WRITE);
//	stdout=&s;

//	sei();

	Device* annoydevice = createDevice(annoyname, 1, buffered_send_char);
	Device* stairdevice = createDevice(stairname, 1, buffered_send_char);
	
	setDeviceCName("Annoying Light", annoydevice);
	setDeviceCName("Stairs Light", stairdevice);
	setDeviceLocation(0, 0, 0, 0, annoydevice);
	setDeviceLocation(0, 0, 0, 0, stairdevice);
	
	addField(BOOL, "Light Status", 0, 1, 0, annoydevice);
	addField(BOOL, "Light Status", 0, 1, 0, stairdevice);

	while (1) {
		c = receive_char_serial();
		if (c == '\0') {
			if (receive_char_serial() == did) {
				serial_tx_enable();
				if (transmit_flag) {
					len = buf[0] + 1;
//					printf("sending packet %d\n", buf[3]);
					for (i = 0; i < len; i++) {
						send_char_serial(buf[i]);
					}
//					printf("bi:%d %d %d\n", buf_index, len, buf[3]);
					for (i = len; i < buf_index; i++) {
						buf[i-len] = buf[i];
					}
					buf_index -= len;
					if (buf_index == 0) {
						transmit_flag = 0;
					}
				} else {
					send_char_serial('\0');
				}
				serial_tx_disable();
			}
		} else {
			len = c;
			recvChar(len, annoydevice);
			recvChar(len, stairdevice);
			for (i = 0; i < len; i++) {
				c = receive_char_serial();
				recvChar(c, annoydevice);
				recvChar(c, stairdevice);
				if (shouldBreak(annoydevice)) break;
				if (shouldBreak(stairdevice)) break;
			}
		}
/*
		if (((r_front + 1) % MAX_LEN) != r_back) {
			r_front++;
			if (r_front == MAX_LEN) {
				r_front = 0;
			}
			recvChar(r_buf[r_front], device);
		}
*/

		if (hasChanged(0, annoydevice)) {
			ret = getBoolVal(0, annoydevice);
			if (ret) {
				RELAY_ANNOY_ON();
			} else {
				RELAY_ANNOY_OFF();
			}
		}
		if (hasChanged(0, stairdevice)) {
			ret = getBoolVal(0, stairdevice);
			if (ret) {
				RELAY_STAIRS_ON();
			} else {
				RELAY_STAIRS_OFF();
			}
		}
	}

	return 0;
}
Esempio n. 5
0
void lineBreakUtf8( const char *line, const std::function<bool(const char *, size_t)> &measureFn, std::function<void(const char *,size_t)> lineProcessFn )
{
	const size_t lengthInBytes = strlen( line );
	shared_ptr<char> brks = shared_ptr<char>( (char*)malloc( lengthInBytes ), free );
	
	set_linebreaks_utf8( (const uint8_t*)line, lengthInBytes, NULL, brks.get() );

	// Byte-suffixed variables correspond to a byte in the UTF8 string, as opposed to the character
	// binary search for the threshold where measureFn() returns false; emerges as curChar
	size_t charLen = stringLengthUtf8( line, lengthInBytes );
	size_t lineStartByte = 0, lineEndByte = 0;
	size_t lineStartChar = 0;
	while( lineStartChar < charLen ) {
		int minChar = 0, maxChar = charLen - lineStartChar /*[minChar,maxChar)*/, curChar = 0;
		
		// test to see if we're already on a mustbreak
		if( brks.get()[lineStartByte] != 0 ) {
			// update our maxChar to reflect any MUSTBREAKS
			int maxCharWithMustBreaks = minChar;
			size_t maxCharByte = lineStartByte;

			while( maxCharWithMustBreaks < maxChar ) {
				nextCharUtf8( line, &maxCharByte, lengthInBytes );
				if( brks.get()[maxCharByte] == 0 ) {
					maxCharWithMustBreaks++;
					break;
				}
				else
					++maxCharWithMustBreaks;
			}
			maxChar = maxCharWithMustBreaks + 1;
		
			while( minChar < maxChar ) {
				curChar = minChar + (maxChar-minChar+1)/2;
				size_t newByte = advanceCharUtf8( line + lineStartByte, curChar, lengthInBytes );
				if( ! measureFn( line + lineStartByte, newByte ) )
					maxChar = curChar - 1;
				else
					minChar = curChar;
			}
			curChar = minChar;
		}
		else { // we started at a mustbreak
			curChar = 1;
		}

		// find ideal place to perform the break, either at curChar or before depending on breaks
		size_t lineEndByteAfterBreaking = lineEndByte = advanceCharUtf8( line + lineStartByte, curChar ) + lineStartByte;
		if( ( lineEndByteAfterBreaking < lengthInBytes ) /*&& ( ! shouldBreak( brks.get()[lineEndByteAfterBreaking] ) )*/ ) {
			while( (lineEndByteAfterBreaking > lineStartByte) && ( ! shouldBreak( brks.get()[lineEndByteAfterBreaking-1] ) ) )
				lineEndByteAfterBreaking--;
			if( lineEndByteAfterBreaking == lineStartByte ) // there's no good breakpoint; just break where we would have
				lineEndByteAfterBreaking = lineEndByte;
		}
		lineProcessFn( line + lineStartByte, lineEndByteAfterBreaking - lineStartByte );
		lineStartChar += stringLengthUtf8( line + lineStartByte, lineEndByteAfterBreaking - lineStartByte );
		lineStartByte = lineEndByteAfterBreaking;
		// eat any spaces we'd start on on the next line
		size_t tempByte = lineStartByte;
		while( nextCharUtf8( line, &tempByte, lengthInBytes ) == (uint32_t)' ') {
			lineStartByte = tempByte;
			++lineStartChar;
		}
	}
}
Esempio n. 6
0
void ScanThread::scanEntry(
			const fs::path& path, 
			const RecordID& parentID, 
			Records& oldRecords,
			bool recursive)
try
{
	if (shouldBreak())
	{
		return;
	}
	
	const bool isDir = fs::is_directory(path);	
	Record newRecord = make_Record(
		NULL_RECORD_ID, 
		RecordData(parentID, /*last write time*/0, isDir, path.string()));

	const std::pair<Records::iterator, Records::iterator> oldRange = 
		std::equal_range(oldRecords.begin(), oldRecords.end(), newRecord, CmpByPath());
	assert(std::distance(oldRange.first, oldRange.second) <= 1);
	
	const Records::iterator itOldRecord = oldRange.first != oldRange.second ?
		oldRange.first : oldRecords.end();

	if (isDir && recursive)
	{
		// if new entry
		if (itOldRecord == oldRecords.end())
		{
            addEntry(std::move(newRecord.second));
		}
	}
	else // file
	{
		if (!isSupportedExtension(path))
		{
			return; // unsupported extension
		}
				
        newRecord.second.header.lastWriteTime = fs::last_write_time(path);
        
		if (itOldRecord == oldRecords.end())
		{
            addEntry(std::move(newRecord.second));
		}
		else if(newRecord.second.header.lastWriteTime != 
				itOldRecord->second.header.lastWriteTime)
		{
			newRecord.first = itOldRecord->first;
            replaceEntry(std::move(newRecord));
		}
	}
	
	// record was processed, so removing from the list
	if (oldRecords.end() != itOldRecord)
	{
		oldRecords.erase(itOldRecord);
	}
}
catch(const fs::filesystem_error& ex)
{
	std::cerr << "Failed to process filesystem element " 
			<< path << ": " << ex.what() << std::endl;
	
	// if the entry is inaccessible due to network resource down
	// it shouldn't be deleted from the database
	if (ex.code().value() != ENOENT)
	{
		const Record fakeRecord = make_Record(NULL_RECORD_ID, 
						RecordData(NULL_RECORD_ID, 0, false, path.string()));
		const Records::iterator itOldRecord = std::lower_bound(
			oldRecords.begin(), oldRecords.end(), fakeRecord, CmpByPath());
		
		// prevent record from deletion
		if (oldRecords.end() != itOldRecord)
		{
			oldRecords.erase(itOldRecord);
		}
	}
}
catch(const std::exception& ex)
{
	std::cerr << "Failed to process filesystem element " 
			<< path << ": " << ex.what() << std::endl;
}