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_(); } }
void ScanThread::scanDirs() { db_iterator const itDirsEnd = db_.dirs_end(); for (db_iterator itDir = db_.dirs_begin(); itDir != itDirsEnd && !shouldBreak(); ++itDir) { checkDir(*itDir); } }
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; } } }
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; }
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; } } }
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; }