Ejemplo n.º 1
0
/*!
    Opens the file handle \a fh using the open mode \a flags.
*/
bool QFSFileEnginePrivate::openFh(QIODevice::OpenMode openMode, FILE *fh)
{
    Q_Q(QFSFileEngine);
    this->fh = fh;
    fd = -1;

    // Seek to the end when in Append mode.
    if (openMode & QIODevice::Append) {
        int ret;
        do {
            ret = QT_FSEEK(fh, 0, SEEK_END);
        } while (ret != 0 && errno == EINTR);

        if (ret != 0) {
            q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
                        qt_error_string(int(errno)));

            this->openMode = QIODevice::NotOpen;
            this->fh = 0;

            return false;
        }
    }

    return true;
}
Ejemplo n.º 2
0
/*!
    \internal
*/
bool QFSFileEnginePrivate::seekFdFh(qint64 pos)
{
    Q_Q(QFSFileEngine);

    // On Windows' stdlib implementation, the results of calling fread and
    // fwrite are undefined if not called either in sequence, or if preceded
    // with a call to fflush().
    if (lastIOCommand != QFSFileEnginePrivate::IOFlushCommand && !q->flush())
        return false;

    if (pos < 0 || pos != qint64(QT_OFF_T(pos)))
        return false;

    if (fh) {
        // Buffered stdlib mode.
        int ret;
        do {
            ret = QT_FSEEK(fh, QT_OFF_T(pos), SEEK_SET);
        } while (ret != 0 && errno == EINTR);

        if (ret != 0) {
            q->setError(QFile::ReadError, qt_error_string(int(errno)));
            return false;
        }
    } else {
        // Unbuffered stdio mode.
        if (QT_LSEEK(fd, QT_OFF_T(pos), SEEK_SET) == -1) {
            qWarning() << "QFile::at: Cannot set file position" << pos;
            q->setError(QFile::PositionError, qt_error_string(errno));
            return false;
        }
    }
    return true;
}
Ejemplo n.º 3
0
/*!
    \internal
*/
qint64 QFSFileEnginePrivate::readFdFh(char *data, qint64 len)
{
    Q_Q(QFSFileEngine);

    if (len < 0 || len != qint64(size_t(len))) {
        q->setError(QFile::ReadError, qt_error_string(EINVAL));
        return -1;
    }

    qint64 readBytes = 0;
    bool eof = false;

    if (fh) {
        // Buffered stdlib mode.

        size_t result;
        bool retry = true;
        do {
            result = fread(data + readBytes, 1, size_t(len - readBytes), fh);
            eof = feof(fh);
            if (retry && eof && result == 0) {
                // On OS X, this is needed, e.g., if a file was written to
                // through another stream since our last read. See test
                // tst_QFile::appendAndRead
                QT_FSEEK(fh, QT_FTELL(fh), SEEK_SET); // re-sync stream.
                retry = false;
                continue;
            }
            readBytes += result;
        } while (!eof && (result == 0 ? errno == EINTR : readBytes < len));

    } else if (fd != -1) {
        // Unbuffered stdio mode.

        SignedIOType result;
        do {
            // calculate the chunk size
            // on Windows or 32-bit no-largefile Unix, we'll need to read in chunks
            // we limit to the size of the signed type, otherwise we could get a negative number as a result
            quint64 wantedBytes = quint64(len) - quint64(readBytes);
            UnsignedIOType chunkSize = std::numeric_limits<SignedIOType>::max();
            if (chunkSize > wantedBytes)
                chunkSize = wantedBytes;
            result = QT_READ(fd, data + readBytes, chunkSize);
        } while (result > 0 && (readBytes += result) < len);

        eof = !(result == -1);
    }

    if (!eof && readBytes == 0) {
        readBytes = -1;
        q->setError(QFile::ReadError, qt_error_string(errno));
    }

    return readBytes;
}
Ejemplo n.º 4
0
/*!
    \internal
*/
qint64 QFSFileEnginePrivate::readFdFh(char *data, qint64 len)
{
    Q_Q(QFSFileEngine);

    if (len < 0 || len != qint64(size_t(len))) {
        q->setError(QFile::ReadError, qt_error_string(EINVAL));
        return -1;
    }

    qint64 readBytes = 0;
    bool eof = false;

    if (fh) {
        // Buffered stdlib mode.

        size_t result;
        bool retry = true;
        do {
            result = fread(data + readBytes, 1, size_t(len - readBytes), fh);
            eof = feof(fh);
            if (retry && eof && result == 0) {
                // On Mac OS, this is needed, e.g., if a file was written to
                // through another stream since our last read. See test
                // tst_QFile::appendAndRead
                QT_FSEEK(fh, QT_FTELL(fh), SEEK_SET); // re-sync stream.
                retry = false;
                continue;
            }
            readBytes += result;
        } while (!eof && (result == 0 ? errno == EINTR : readBytes < len));

    } else if (fd != -1) {
        // Unbuffered stdio mode.

#ifdef Q_OS_WIN
        int result;
#else
        ssize_t result;
#endif
        do {
            result = QT_READ(fd, data + readBytes, size_t(len - readBytes));
        } while ((result == -1 && errno == EINTR)
                || (result > 0 && (readBytes += result) < len));

        eof = !(result == -1);
    }

    if (!eof && readBytes == 0) {
        readBytes = -1;
        q->setError(QFile::ReadError, qt_error_string(errno));
    }

    return readBytes;
}
Ejemplo n.º 5
0
/*
    \internal
*/
qint64 QFSFileEnginePrivate::nativeSize() const
{
    Q_Q(const QFSFileEngine);
    QFSFileEngine *thatQ = const_cast<QFSFileEngine *>(q);

    // ### Don't flush; for buffered files, we should get away with ftell.
    thatQ->flush();

    // Always retrive the current information
    metaData.clearFlags(QFileSystemMetaData::SizeAttribute);
#if defined(Q_OS_WINCE)
    // Buffered stdlib mode.
    if (fh) {
        QT_OFF_T oldPos = QT_FTELL(fh);
        QT_FSEEK(fh, 0, SEEK_END);
        qint64 fileSize = (qint64)QT_FTELL(fh);
        QT_FSEEK(fh, oldPos, SEEK_SET);
        if (fileSize == -1) {
            fileSize = 0;
            thatQ->setError(QFile::UnspecifiedError, qt_error_string(errno));
        }
        return fileSize;
    }
    if (fd != -1) {
        thatQ->setError(QFile::UnspecifiedError, QLatin1String("Not implemented!"));
        return 0;
    }
#endif
    bool filled = false;
    if (fileHandle != INVALID_HANDLE_VALUE && openMode != QIODevice::NotOpen )
        filled = QFileSystemEngine::fillMetaData(fileHandle, metaData,
                                                 QFileSystemMetaData::SizeAttribute);
    else
        filled = doStat(QFileSystemMetaData::SizeAttribute);

    if (!filled) {
        thatQ->setError(QFile::UnspecifiedError, qt_error_string(errno));
        return 0;
    }
    return metaData.size();
}
Ejemplo n.º 6
0
/*!
    \internal
*/
bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
{
    Q_Q(QFSFileEngine);

    if (openMode & QIODevice::Unbuffered) {
        int flags = openModeToOpenFlags(openMode);

        // Try to open the file in unbuffered mode.
        do {
            fd = QT_OPEN(nativeFilePath.constData(), flags, 0666);
        } while (fd == -1 && errno == EINTR);

        // On failure, return and report the error.
        if (fd == -1) {
            q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
                        qt_error_string(errno));
            return false;
        }

#ifndef O_CLOEXEC
        // not needed on Linux >= 2.6.23
        setCloseOnExec(fd);     // ignore failure
#endif

        // Seek to the end when in Append mode.
        if (flags & QFile::Append) {
            int ret;
            do {
                ret = QT_LSEEK(fd, 0, SEEK_END);
            } while (ret == -1 && errno == EINTR);

            if (ret == -1) {
                q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
                            qt_error_string(int(errno)));
                return false;
            }
        }

        fh = 0;
    } else {
        QByteArray fopenMode = openModeToFopenMode(openMode, filePath);

        // Try to open the file in buffered mode.
        do {
            fh = QT_FOPEN(nativeFilePath.constData(), fopenMode.constData());
        } while (!fh && errno == EINTR);

        // On failure, return and report the error.
        if (!fh) {
            q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
                        qt_error_string(int(errno)));
            return false;
        }

        setCloseOnExec(fileno(fh)); // ignore failure

        // Seek to the end when in Append mode.
        if (openMode & QIODevice::Append) {
            int ret;
            do {
                ret = QT_FSEEK(fh, 0, SEEK_END);
            } while (ret == -1 && errno == EINTR);

            if (ret == -1) {
                q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
                            qt_error_string(int(errno)));
                return false;
            }
        }

        fd = -1;
    }

    closeFileHandle = true;
    return true;
}
Ejemplo n.º 7
0
/*!
    \internal
*/
bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
{
    Q_Q(QFSFileEngine);

    if (openMode & QIODevice::Unbuffered) {
        int flags = openModeToOpenFlags(openMode);

        // Try to open the file in unbuffered mode.
        do {
            fd = QT_OPEN(fileEntry.nativeFilePath().constData(), flags, 0666);
        } while (fd == -1 && errno == EINTR);

        // On failure, return and report the error.
        if (fd == -1) {
            q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
                        qt_error_string(errno));
            return false;
        }

        if (!(openMode & QIODevice::WriteOnly)) {
            // we don't need this check if we tried to open for writing because then
            // we had received EISDIR anyway.
            if (QFileSystemEngine::fillMetaData(fd, metaData)
                    && metaData.isDirectory()) {
                q->setError(QFile::OpenError, QLatin1String("file to open is a directory"));
                QT_CLOSE(fd);
                return false;
            }
        }

        // Seek to the end when in Append mode.
        if (flags & QFile::Append) {
            int ret;
            do {
                ret = QT_LSEEK(fd, 0, SEEK_END);
            } while (ret == -1 && errno == EINTR);

            if (ret == -1) {
                q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
                            qt_error_string(int(errno)));
                return false;
            }
        }

        fh = 0;
    } else {
        QByteArray fopenMode = openModeToFopenMode(openMode, fileEntry, metaData);

        // Try to open the file in buffered mode.
        do {
            fh = QT_FOPEN(fileEntry.nativeFilePath().constData(), fopenMode.constData());
        } while (!fh && errno == EINTR);

        // On failure, return and report the error.
        if (!fh) {
            q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
                        qt_error_string(int(errno)));
            return false;
        }

        if (!(openMode & QIODevice::WriteOnly)) {
            // we don't need this check if we tried to open for writing because then
            // we had received EISDIR anyway.
            if (QFileSystemEngine::fillMetaData(QT_FILENO(fh), metaData)
                    && metaData.isDirectory()) {
                q->setError(QFile::OpenError, QLatin1String("file to open is a directory"));
                fclose(fh);
                return false;
            }
        }

        setCloseOnExec(fileno(fh)); // ignore failure

        // Seek to the end when in Append mode.
        if (openMode & QIODevice::Append) {
            int ret;
            do {
                ret = QT_FSEEK(fh, 0, SEEK_END);
            } while (ret == -1 && errno == EINTR);

            if (ret == -1) {
                q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
                            qt_error_string(int(errno)));
                return false;
            }
        }

        fd = -1;
    }

    closeFileHandle = true;
    return true;
}
Ejemplo n.º 8
0
bool StarComponent::loadStaticData()
{
    // We break from Qt / KDE API and use traditional file handling here, to obtain speed.
    // We also avoid C++ constructors for the same reason.
    KStarsData* data = KStarsData::Instance();
    FILE *dataFile, *nameFile;
    bool swapBytes = false;
    BinFileHelper dataReader, nameReader;
    QString name, gname, visibleName;
    StarObject *star;

    if(starsLoaded)
        return true;

    // prepare to index stars to this date
    m_skyMesh->setKSNumbers( &m_reindexNum );

    /* Open the data files */
    // TODO: Maybe we don't want to hardcode the filename?
    if((dataFile = dataReader.openFile("namedstars.dat")) == NULL) {
        qDebug() << "Could not open data file namedstars.dat" << endl;
        return false;
    }

    if(!(nameFile = nameReader.openFile("starnames.dat"))) {
        qDebug() << "Could not open data file starnames.dat" << endl;
        return false;
    }

    if(!dataReader.readHeader()) {
        qDebug() << "Error reading namedstars.dat header : " << dataReader.getErrorNumber() << " : " << dataReader.getError() << endl;
        return false;
    }

    if(!nameReader.readHeader()) {
        qDebug() << "Error reading starnames.dat header : " << nameReader.getErrorNumber() << " : " << nameReader.getError() << endl;
        return false;
    }
    //KDE_fseek(nameFile, nameReader.getDataOffset(), SEEK_SET);
    QT_FSEEK(nameFile, nameReader.getDataOffset(), SEEK_SET);
    swapBytes = dataReader.getByteSwap();

    long int nstars = 0;

    //KDE_fseek(dataFile, dataReader.getDataOffset(), SEEK_SET);
    QT_FSEEK(dataFile, dataReader.getDataOffset(), SEEK_SET);

    qint16 faintmag;
    quint8 htm_level;
    quint16 t_MSpT;

    fread( &faintmag, 2, 1, dataFile );
    if( swapBytes )
        faintmag = bswap_16( faintmag );
    fread( &htm_level, 1, 1, dataFile );
    fread( &t_MSpT, 2, 1, dataFile ); // Unused
    if( swapBytes )
        faintmag = bswap_16( faintmag );


    if( faintmag / 100.0 > m_FaintMagnitude )
        m_FaintMagnitude = faintmag / 100.0;

    if( htm_level != m_skyMesh->level() )
        qDebug() << "WARNING: HTM Level in shallow star data file and HTM Level in m_skyMesh do not match. EXPECT TROUBLE" << endl;

    for(int i = 0; i < m_skyMesh -> size(); ++i) {

        Trixel trixel = i;// = ( ( i >= 256 ) ? ( i - 256 ) : ( i + 256 ) );
        for(unsigned long j = 0; j < (unsigned long)dataReader.getRecordCount(i); ++j) {
            if(!fread(&stardata, sizeof(starData), 1, dataFile)){
                qDebug() << "FILE FORMAT ERROR: Could not read starData structure for star #" << j << " under trixel #" << trixel << endl;
            }

            /* Swap Bytes when required */
            if(swapBytes)
                byteSwap( &stardata );

            if(stardata.flags & 0x01) {
                /* Named Star - Read the nameFile */
                visibleName = "";
                if(!fread(&starname, sizeof( starName ), 1, nameFile))
                    qDebug() << "ERROR: fread() call on nameFile failed in trixel " << trixel << " star " << j << endl;
                name = QByteArray(starname.longName, 32);
                gname = QByteArray(starname.bayerName, 8);
                if ( ! gname.isEmpty() && gname.at(0) != '.')
                    visibleName = gname;
                if(! name.isEmpty() ) {
                    // HEV: look up star name in internationalization filesource
                    name = i18nc("star name", name.toLocal8Bit().data());
                } else {
                    name = i18n("star");
                }
            }
            else
                qDebug() << "ERROR: Named star file contains unnamed stars! Expect trouble." << endl;

            /* Create the new StarObject */
            star = new StarObject;
            star->init( &stardata );
            if( star->getHDIndex() != 0 && name == i18n("star"))
                name = QString("HD %1").arg(star->getHDIndex());

            star->setNames( name, visibleName );
            star->EquatorialToHorizontal( data->lst(), data->geo()->lat() );
            ++nstars;

            if ( ! gname.isEmpty() ) m_genName.insert( gname, star );

            if ( ! name.isEmpty() && name != i18n("star")) {
                objectNames(SkyObject::STAR).append( name );
            }
            if ( ! visibleName.isEmpty() && gname != name ) {
                objectNames(SkyObject::STAR).append( star -> gname(false) );
            }

            m_ObjectList.append( star );

            m_starIndex->at( trixel )->append( star );
            double pm = star->pmMagnitude();
            for (int j = 0; j < m_highPMStars.size(); j++ ) {
                HighPMStarList* list = m_highPMStars.at( j );
                if ( list->append( trixel, star, pm ) ) break;
            }

            if( star->getHDIndex() != 0 )
                m_HDHash.insert( star->getHDIndex(), star );

        }

    }

    dataReader.closeFile();
    nameReader.closeFile();

    starsLoaded = true;
    return true;

}
Ejemplo n.º 9
0
bool DeepStarComponent::loadStaticStars() {
    FILE *dataFile;

    if( !staticStars )
        return true;
    if( !fileOpened )
        return false;

    dataFile = starReader.getFileHandle();
    rewind( dataFile );

    if( !starReader.readHeader() ) {
        qDebug() << "Error reading header of catalog file " << dataFileName << ": " << starReader.getErrorNumber() << ": " << starReader.getError() << endl;
        return false;
    }

    quint8 recordSize = starReader.guessRecordSize();
    if( recordSize != 16 && recordSize != 32 )
    {
        qDebug() << "Cannot understand catalog file " << dataFileName << endl;
        return false;
    }

    //KDE_fseek(dataFile, starReader.getDataOffset(), SEEK_SET);
    QT_FSEEK(dataFile, starReader.getDataOffset(), SEEK_SET);

    qint16 faintmag;
    quint8 htm_level;
    quint16 t_MSpT;

    fread( &faintmag, 2, 1, dataFile );
    if( starReader.getByteSwap() )
        faintmag = bswap_16( faintmag );
    fread( &htm_level, 1, 1, dataFile );
    fread( &t_MSpT, 2, 1, dataFile ); // Unused
    if( starReader.getByteSwap() )
        faintmag = bswap_16( faintmag );


    // TODO: Read the multiplying factor from the dataFile
    m_FaintMagnitude = faintmag / 100.0;

    if( htm_level != m_skyMesh->level() )
        qDebug() << "WARNING: HTM Level in shallow star data file and HTM Level in m_skyMesh do not match. EXPECT TROUBLE" << endl;

    // JM 2012-12-05: Breaking into into 2 loops instead of one previously with multiple IF checks for recordSize
    // While the CPU branch prediction might not suffer any penalities since the branch prediction after a few times
    // should always gets it right. It's better to do it this way to avoid any chances since the compiler might not optimize it.
    if (recordSize == 32)
    {
        for(Trixel i = 0; i < (unsigned int)m_skyMesh->size(); ++i)
        {
            Trixel trixel = i;
            quint64 records = starReader.getRecordCount( i );
            StarBlock *SB = new StarBlock( records );

            if( !SB )
                qDebug() << "ERROR: Could not allocate new StarBlock to hold shallow unnamed stars for trixel " << trixel << endl;

            m_starBlockList.at( trixel )->setStaticBlock( SB );

            for(quint64 j = 0; j < records; ++j)
            {
                bool fread_success = false;
                fread_success = fread( &stardata, sizeof( starData ), 1, dataFile );

                if( !fread_success )
                {
                    qDebug() << "ERROR: Could not read starData structure for star #" << j << " under trixel #" << trixel << endl;
                }

                /* Swap Bytes when required */
                if( starReader.getByteSwap() )
                    byteSwap( &stardata );

                /* Initialize star with data just read. */
                StarObject* star;
                #ifdef KSTARS_LITE
                star = &(SB->addStar( stardata )->star);
                #else
                star = SB->addStar( stardata );
                #endif
                if( star )
                {
                    //KStarsData* data = KStarsData::Instance();
                    //star->EquatorialToHorizontal( data->lst(), data->geo()->lat() );
                    //if( star->getHDIndex() != 0 )
                    if (stardata.HD)
                        m_CatalogNumber.insert( stardata.HD, star );
                }
                else
                {
                    qDebug() << "CODE ERROR: More unnamed static stars in trixel " << trixel << " than we allocated space for!" << endl;
                }
            }
        }
    }
    else
    {
        for(Trixel i = 0; i < (unsigned int)m_skyMesh->size(); ++i)
        {
            Trixel trixel = i;
            quint64 records = starReader.getRecordCount( i );
            StarBlock *SB = new StarBlock( records );

            if( !SB )
                qDebug() << "ERROR: Could not allocate new StarBlock to hold shallow unnamed stars for trixel " << trixel << endl;

            m_starBlockList.at( trixel )->setStaticBlock( SB );

            for(quint64 j = 0; j < records; ++j)
            {
                bool fread_success = false;
                fread_success = fread( &deepstardata, sizeof( deepStarData ), 1, dataFile );

                if( !fread_success )
                {
                    qDebug() << "ERROR: Could not read starData structure for star #" << j << " under trixel #" << trixel << endl;
                }

                /* Swap Bytes when required */
                if( starReader.getByteSwap() )
                    byteSwap( &deepstardata );

                /* Initialize star with data just read. */
                StarObject* star;
                #ifdef KSTARS_LITE
                star = &(SB->addStar( stardata )->star);
                #else
                star = SB->addStar( deepstardata );
                #endif
                if( star )
                {
                    //KStarsData* data = KStarsData::Instance();
                    //star->EquatorialToHorizontal( data->lst(), data->geo()->lat() );
                    //if( star->getHDIndex() != 0 )
                    if (stardata.HD)
                        m_CatalogNumber.insert( stardata.HD, star );
                }
                else
                {
                    qDebug() << "CODE ERROR: More unnamed static stars in trixel " << trixel << " than we allocated space for!" << endl;
                }
            }
        }
    }

    return true;
}
/*!
    \internal
*/
qint64 QFSFileEnginePrivate::readFdFh(char *data, qint64 len)
{
    Q_Q(QFSFileEngine);

    // Buffered stdlib mode.
    if (fh) {
        qint64 readBytes = 0;
        qint64 read = 0;
        int retry = 0;

        // Read in blocks of 4k to avoid platform limitations (Windows
        // commonly bails out if you read or write too large blocks at once).
        qint64 bytesToRead;
        do {
            if (retry == 1)
                retry = 2;

            bytesToRead = qMin<qint64>(4096, len - read);
            do {
                readBytes = fread(data + read, 1, size_t(bytesToRead), fh);
            } while (readBytes == 0 && !feof(fh) && errno == EINTR);

            if (readBytes > 0) {
                read += readBytes;
            } else if (!retry && feof(fh)) {
                // Synchronize and try again (just once though).
                if (++retry == 1)
                    QT_FSEEK(fh, QT_FTELL(fh), SEEK_SET);
            }
        } while (retry == 1 || (readBytes == bytesToRead && read < len));

        // Return the number of bytes read, or if nothing was read, return -1
        // if an error occurred, or 0 if we detected EOF.
        if (read == 0) {
            q->setError(QFile::ReadError, qt_error_string(int(errno)));
            if (!feof(fh))
                read = -1;
        }
        return read;
    }

    // Unbuffered stdio mode.
    qint64 ret = 0;
    if (len) {
        int result;
        qint64 read = 0;
        errno = 0;

        // Read in blocks of 4k to avoid platform limitations (Windows
        // commonly bails out if you read or write too large blocks at once).
        do {
            qint64 bytesToRead = qMin<qint64>(4096, len - read);
            do {
                result = QT_READ(fd, data + read, int(bytesToRead));
            } while (result == -1 && errno == EINTR);
            if (result > 0)
                read += result;
        } while (result > 0 && read < len);

        // Return the number of bytes read, or if nothing was read, return -1
        // if an error occurred.
        if (read > 0) {
            ret += read;
        } else if (read == 0 && result < 0) {
            ret = -1;
            q->setError(QFile::ReadError, qt_error_string(errno));
        }
    }
    return ret;
}