int DataFileManager::openFile(std::string _filename, DatumFileOptions opt) { // first we need to format the file name with the correct path and // extension std::string _ext_(appendDataFileExtension( prependDataFilePath(_filename.c_str()).string())); filename = _ext_; // form the scarab uri std::string prefix = "ldobinary:file://"; std::string uri = prefix + filename; if(opt == M_NO_OVERWRITE) { FILE *fd = fopen(filename.c_str(), "r"); if(fd != 0) { // badness....don't overwrite my file! fclose(fd); merror(M_FILE_MESSAGE_DOMAIN, "Can't overwrite existing file: %s", filename.c_str()); global_outgoing_event_buffer->putEvent(SystemEventFactory::dataFileOpenedResponse(filename.c_str(), M_COMMAND_FAILURE)); return -1; } } // Ensure that the destination directory exists try { boost::filesystem::create_directories(boost::filesystem::path(filename).parent_path()); } catch (const std::exception &e) { merror(M_FILE_MESSAGE_DOMAIN, "Could not create data file destination directory: %s", e.what()); global_outgoing_event_buffer->putEvent(SystemEventFactory::dataFileOpenedResponse(filename.c_str(), M_COMMAND_FAILURE)); return -1; } if(scarab_create_file(filename.c_str()) != 0){ merror(M_FILE_MESSAGE_DOMAIN, "Could not create file: %s", filename.c_str()); global_outgoing_event_buffer->putEvent(SystemEventFactory::dataFileOpenedResponse(filename.c_str(), M_COMMAND_FAILURE)); return -1; } // Generate list of excluded event codes std::unordered_set<int> excludedEventCodes; for (auto &var : global_variable_registry->getGlobalVariables()) { if (var->getProperties()->getExcludeFromDataFile()) { excludedEventCodes.insert(var->getCodecCode()); } } scarab_connection = shared_ptr<ScarabWriteConnection>(new ScarabWriteConnection(global_outgoing_event_buffer, uri, excludedEventCodes)); scarab_connection->connect(); if(scarab_connection->isConnected()) { scarab_connection->startThread(M_DATAFILE_SERVICE_INTERVAL_US); file_open = true; // write out the event-code to name/description mapping // this is an essential part of the self-describing nature of the // MWorks/Scarab format global_outgoing_event_buffer->putEvent(SystemEventFactory::componentCodecPackage()); global_outgoing_event_buffer->putEvent(SystemEventFactory::codecPackage()); global_outgoing_event_buffer->putEvent(SystemEventFactory::currentExperimentState()); global_variable_registry->announceAll(); } else { merror(M_FILE_MESSAGE_DOMAIN, "Failed to open file: %s", uri.c_str()); global_outgoing_event_buffer->putEvent(SystemEventFactory::dataFileOpenedResponse(filename.c_str(), M_COMMAND_FAILURE)); return -1; } mprintf(M_FILE_MESSAGE_DOMAIN, "Opening data file: %s", filename.c_str()); // everything went ok so issue the success event global_outgoing_event_buffer->putEvent(SystemEventFactory::dataFileOpenedResponse(filename.c_str(), M_COMMAND_SUCCESS)); return 0; }
int DataFileManager::openFile(std::string _filename, DatumFileOptions opt) { if (isFileOpen()) { mwarning(M_FILE_MESSAGE_DOMAIN, "Data file already open at \"%s\"", filename.c_str()); return -1; } // first we need to format the file name with the correct path and // extension filename = appendDataFileExtension(prependDataFilePath(_filename).string()); const auto filepath = boost::filesystem::path(filename); if (boost::filesystem::exists(filepath)) { if (opt == M_NO_OVERWRITE) { merror(M_FILE_MESSAGE_DOMAIN, "Can't overwrite existing file \"%s\"", filename.c_str()); global_outgoing_event_buffer->putEvent(SystemEventFactory::dataFileOpenedResponse(filename.c_str(), M_COMMAND_FAILURE)); return -1; } try { boost::filesystem::remove(filepath); } catch (const std::exception &e) { merror(M_FILE_MESSAGE_DOMAIN, "Can't remove existing file \"%s\": %s", filename.c_str(), e.what()); global_outgoing_event_buffer->putEvent(SystemEventFactory::dataFileOpenedResponse(filename.c_str(), M_COMMAND_FAILURE)); return -1; } } // Ensure that the destination directory exists try { boost::filesystem::create_directories(filepath.parent_path()); } catch (const std::exception &e) { merror(M_FILE_MESSAGE_DOMAIN, "Could not create data file destination directory: %s", e.what()); global_outgoing_event_buffer->putEvent(SystemEventFactory::dataFileOpenedResponse(filename.c_str(), M_COMMAND_FAILURE)); return -1; } // Create the file try { mwk2Writer.reset(new MWK2Writer(filename)); } catch (const SimpleException &e) { merror(M_FILE_MESSAGE_DOMAIN, "Could not create file \"%s\": %s", filename.c_str(), e.what()); global_outgoing_event_buffer->putEvent(SystemEventFactory::dataFileOpenedResponse(filename.c_str(), M_COMMAND_FAILURE)); return -1; } // Generate list of excluded event codes excludedEventCodes.clear(); for (auto &var : global_variable_registry->getGlobalVariables()) { if (var->getProperties()->getExcludeFromDataFile()) { excludedEventCodes.insert(var->getCodecCode()); } } // Create the event buffer reader eventBufferReader.reset(new EventBufferReader(global_outgoing_event_buffer)); // Start the event handler thread running = true; eventHandlerThread = std::thread([this]() { handleEvents(); }); // Announce component codec, variable codec, experiment state, and all current // variable values global_outgoing_event_buffer->putEvent(SystemEventFactory::componentCodecPackage()); global_outgoing_event_buffer->putEvent(SystemEventFactory::codecPackage()); global_outgoing_event_buffer->putEvent(SystemEventFactory::currentExperimentState()); global_variable_registry->announceAll(); mprintf(M_FILE_MESSAGE_DOMAIN, "Opened data file: %s", filename.c_str()); // everything went ok so issue the success event global_outgoing_event_buffer->putEvent(SystemEventFactory::dataFileOpenedResponse(filename.c_str(), M_COMMAND_SUCCESS)); return 0; }