void ApplicationLog::writeToStdout(QString message) { QString datetimeString = QDateTime::currentDateTime().toString(LOG_MESSAGE_DATETIME_PATTERN); QString formattedMessage = QString("%1 %2").arg(datetimeString, message); QTextStream stdoutStream(stdout); stdoutStream << formattedMessage << endl; stdoutStream.flush(); }
DiskDevice* addAdditionalInfo(DiskDevice* diskDevice) { QProcess process; QString diskPath = diskDevice->getDiskPath(); process.start("/usr/sbin/diskutil", QStringList() << "info" << diskPath, QIODevice::ReadWrite | QIODevice::Text); if (! process.waitForFinished()) utils::writeLog("Could not execute diskutil to check protocol for device " + diskPath); else { QTextStream stdoutStream(process.readAllStandardOutput()); QString line = stdoutStream.readLine(); bool isEjectable = false; bool isDmg = false; bool isReadOnly = false; while (!line.isNull()) { line = line.simplified(); /* Remove trailing and leading ws */ /* The line holding the device is the only line always starting with 0: */ if (line.simplified().startsWith("Ejectable:")) { QString ejectable = QString(line.split(":").at(1).simplified()); if (0 == QString("Yes").compare(ejectable, Qt::CaseInsensitive)) isEjectable = true; utils::writeLog("Determined " + ejectable + " as ejactableProperty for " + diskPath); } else if (line.simplified().startsWith("Protocol:")) { QString protocol = QString(line.split(":").at(1).simplified()); if (0 == QString("Disk Image").compare(protocol, Qt::CaseInsensitive)) isDmg = true; utils::writeLog("Determined " + protocol + " as protocol for " + diskPath); utils::writeLog("Decided to be a DMG? " + isDmg); } else if (line.simplified().startsWith("Read-Only Media:")) { QString readOnlyMedia = QString(line.split(":").at(1).simplified()); if (0 == QString("Yes").compare(readOnlyMedia, Qt::CaseInsensitive)) isReadOnly = true; utils::writeLog("Determined " + readOnlyMedia + " as readOnlyMedia for " + diskPath); utils::writeLog("Decided to be r/o? " + isReadOnly); } else if (line.simplified().contains("Media Name")) { QString label = QString(line.split(":").at(1).simplified()); diskDevice->setLabel(label); } if (isEjectable && (!isDmg && !isReadOnly)) diskDevice->setIsWritable(true); else utils::writeLog("Decided that " + diskPath + " is not writable to us"); /* advance to next line */ line = stdoutStream.readLine(); } } return diskDevice; }
QList<DiskDevice * > enumerateDevice() { updateKernelTable(); QList<DiskDevice *> devices; utils::writeLog("Enumerating imageable devices for Linux"); QProcess process; QStringList lines; //process.start("/usr/bin/gksudo", QStringList() << "/sbin/fdisk -l", QIODevice::ReadWrite | QIODevice::Text); /* To run in Qt */ process.setEnvironment(QStringList() << "LANG=C"); process.start("/sbin/fdisk", QStringList() << "-l", QIODevice::ReadOnly | QIODevice::Text); if (! process.waitForFinished()) utils::writeLog("Could not execute fdisk to enumerate devices"); else { QTextStream stdoutStream(process.readAllStandardOutput()); while (true) { QString line = stdoutStream.readLine(); if (line.isNull()) break; else lines << line << "\n"; } for (int i = 0; i < lines.count(); i++) { QString line = lines.at(i); if (line.startsWith("Disk /dev") && ! (line.startsWith("Disk /dev/sda") || line.startsWith("Disk /dev/hda") || line.startsWith("Disk /dev/xvda"))) { QStringList deviceAttr = line.split(" "); QString devicePath; QString deviceSpace; devicePath = deviceAttr.at(1); devicePath.remove(":"); deviceSpace = deviceAttr.at(2) + deviceAttr.at(3); deviceSpace.remove(","); DiskDevice *nd = new DiskDevice(i, devicePath, deviceSpace); devices.append(nd); } } } return devices; }
void ApplicationLog::write(QString message) { QString datetimeString = QDateTime::currentDateTime().toString(LOG_MESSAGE_DATETIME_PATTERN); QString formattedMessage = QString("%1 %2").arg(datetimeString, message); this -> logMutex -> lock(); // если новая дата if (this -> currentDate != QDate::currentDate()) { writeToStdout(QString("The current log file will be closed and a new file opened for the new date.")); this -> logFile -> close(); if (!this -> createLogFile()) { return; } } QTextStream stdoutStream(stdout); QTextStream logStream(logFile); stdoutStream << formattedMessage << endl; logStream << formattedMessage << endl; stdoutStream.flush(); logStream.flush(); logMutex -> unlock(); }
QList<DiskDevice *> enumerateDevice() { QList<DiskDevice *> devices; utils::writeLog("Enumerating imageable devices for OSX"); QProcess process; QStringList lines; process.setEnvironment(QStringList() << "LANG=C"); process.start("/usr/sbin/diskutil", QStringList() << "list", QIODevice::ReadWrite | QIODevice::Text); if (! process.waitForFinished()) utils::writeLog("Could not execute diskutil to enumerate devices"); else { QTextStream stdoutStream(process.readAllStandardOutput()); while (true) { QString line = stdoutStream.readLine().simplified(); /* Remove trailing and leading ws */ if (line.isNull()) break; /* The line holding the device is the only line always starting with 0: */ else if (line.startsWith("0:")) { lines << line; } } for (int i = 0; i < lines.count(); i++) { QString line = lines.at(i); QStringList deviceAttr = line.split(" "); /* * THE FOLLOWING LIST CHANGES IF THE DISK WAS NOT INITIALISED * In that case, <partition schema name> is missing and the * index for the following elements has to be adressed by n-1 * content is now: * [0] 0: * [1] <partition scheme name> * [2] <total_size> * [3] <size_unit> * [4] device name (disk0, disk1, etc) */ QString deviceSpace; QString devicePath("/dev/"); if (deviceAttr.at(1).startsWith("*")) { /* partition schema name was missing - uninitialised disk */ deviceSpace = deviceAttr.at(1) + " " + deviceAttr.at(2); devicePath += (new QString(deviceAttr.at(3)))->replace(0, 1, "rd"); } else { deviceSpace = deviceAttr.at(2) + " " + deviceAttr.at(3); QString deviceName(deviceAttr.at(4)); /* make the disk become a rdisk */ devicePath += deviceName.replace(0, 1, "rd"); } deviceSpace.remove("*"); DiskDevice *nd = new DiskDevice(i, devicePath, deviceSpace); utils::writeLog("================================================="); utils::writeLog("Starting to parse " + devicePath + " for additional info\n"); nd = addAdditionalInfo(nd); if (nd->getIsWritable()) { utils::writeLog("Parsed device as writable. Appending."); devices.append(nd); } else { utils::writeLog("Parsed device as NON-writable. NOT Appending."); } utils::writeLog("\n"); utils::writeLog("Finished parsing additional info for " + devicePath); utils::writeLog("=================================================\n"); } } return devices; }
int main( int argc, char **argv ) { char *name = nullptr; struct Option *map; struct Cell_head window; G_gisinit( argv[0] ); G_define_module(); map = G_define_standard_option( G_OPT_R_OUTPUT ); if ( G_parser( argc, argv ) ) exit( EXIT_FAILURE ); name = map->answer; #ifdef Q_OS_WIN _setmode( _fileno( stdin ), _O_BINARY ); _setmode( _fileno( stdout ), _O_BINARY ); //setvbuf( stdin, NULL, _IONBF, BUFSIZ ); // setting _IONBF on stdout works on windows correctly, data written immediately even without fflush(stdout) //setvbuf( stdout, NULL, _IONBF, BUFSIZ ); #endif QgsGrassDataFile stdinFile; stdinFile.open( stdin ); QDataStream stdinStream( &stdinFile ); QFile stdoutFile; stdoutFile.open( stdout, QIODevice::WriteOnly | QIODevice::Unbuffered ); QDataStream stdoutStream( &stdoutFile ); qint32 proj, zone; stdinStream >> proj >> zone; QgsRectangle extent; qint32 rows, cols; stdinStream >> extent >> cols >> rows; checkStream( stdinStream ); QString err = QgsGrass::setRegion( &window, extent, rows, cols ); if ( !err.isEmpty() ) { G_fatal_error( "Cannot set region: %s", err.toUtf8().constData() ); } window.proj = ( int ) proj; window.zone = ( int ) zone; G_set_window( &window ); Qgis::DataType qgis_type; qint32 type; stdinStream >> type; checkStream( stdinStream ); qgis_type = ( Qgis::DataType )type; RASTER_MAP_TYPE grass_type; switch ( qgis_type ) { case Qgis::Int32: grass_type = CELL_TYPE; break; case Qgis::Float32: grass_type = FCELL_TYPE; break; case Qgis::Float64: grass_type = DCELL_TYPE; break; default: G_fatal_error( "QGIS data type %d not supported", qgis_type ); return 1; } cf = Rast_open_new( name, grass_type ); if ( cf < 0 ) { G_fatal_error( "Unable to create raster map <%s>", name ); return 1; } void *buf = Rast_allocate_buf( grass_type ); int expectedSize = cols * QgsRasterBlock::typeSize( qgis_type ); bool isCanceled = false; QByteArray byteArray; for ( int row = 0; row < rows; row++ ) { stdinStream >> isCanceled; checkStream( stdinStream ); if ( isCanceled ) { break; } double noDataValue; stdinStream >> noDataValue; stdinStream >> byteArray; checkStream( stdinStream ); if ( byteArray.size() != expectedSize ) { G_fatal_error( "Wrong byte array size, expected %d bytes, got %d, row %d / %d", expectedSize, byteArray.size(), row, rows ); return 1; } qint32 *cell = nullptr; float *fcell = nullptr; double *dcell = nullptr; if ( grass_type == CELL_TYPE ) cell = ( qint32 * ) byteArray.data(); else if ( grass_type == FCELL_TYPE ) fcell = ( float * ) byteArray.data(); else if ( grass_type == DCELL_TYPE ) dcell = ( double * ) byteArray.data(); void *ptr = buf; for ( int col = 0; col < cols; col++ ) { if ( grass_type == CELL_TYPE ) { if ( ( CELL )cell[col] == ( CELL )noDataValue ) { Rast_set_c_null_value( ( CELL * )ptr, 1 ); } else { Rast_set_c_value( ptr, ( CELL )( cell[col] ), grass_type ); } } else if ( grass_type == FCELL_TYPE ) { if ( ( FCELL )fcell[col] == ( FCELL )noDataValue ) { Rast_set_f_null_value( ( FCELL * )ptr, 1 ); } else { Rast_set_f_value( ptr, ( FCELL )( fcell[col] ), grass_type ); } } else if ( grass_type == DCELL_TYPE ) { if ( ( DCELL )dcell[col] == ( DCELL )noDataValue ) { Rast_set_d_null_value( ( DCELL * )ptr, 1 ); } else { Rast_set_d_value( ptr, ( DCELL )dcell[col], grass_type ); } } ptr = G_incr_void_ptr( ptr, Rast_cell_size( grass_type ) ); } Rast_put_row( cf, buf, grass_type ); #ifndef Q_OS_WIN // Because stdin is somewhere buffered on Windows (not clear if in QProcess or by Windows) // we cannot in QgsGrassImport wait for this because it hangs. Setting _IONBF on stdin does not help // and there is no flush() on QProcess. // OTOH, smaller stdin buffer is probably blocking QgsGrassImport so that the import can be canceled immediately. stdoutStream << ( bool )true; // row written stdoutFile.flush(); #endif } if ( isCanceled ) { Rast_unopen( cf ); } else { Rast_close( cf ); struct History history; Rast_short_history( name, "raster", &history ); Rast_command_history( &history ); Rast_write_history( name, &history ); } exit( EXIT_SUCCESS ); }