Пример #1
0
bool Nicookie::safariFindCookie(QIODevice &device)
{
    qint64 begin_pos = device.pos();

    readUint32LE(device); // cookie_size not use
    readUint32LE(device); // unknown
    readUint32LE(device); // flags not use
    readUint32LE(device);  // unknown
    quint32 url_offset = readUint32LE(device);
    quint32 name_offset = readUint32LE(device);
    quint32 path_offset = readUint32LE(device);
    quint32 value_offset = readUint32LE(device);

    // check url
    device.seek(begin_pos + url_offset);
    if (!checkSameStr(device, Nicookie::COOKIE_HOST)) return false;

    // check name
    device.seek(begin_pos + name_offset);
    if (!checkSameStr(device, Nicookie::COOKIE_NAME)) return false;

    // check path
    device.seek(begin_pos + path_offset);
    if (!checkSameStr(device, Nicookie::COOKIE_PATH)) return false;

    device.seek(begin_pos + value_offset);
    QString str = readStr(device);
    if (str.isEmpty()) {
        setError(Nicookie::NotFoundDataError);
        return false;
    } else {
        this->userSession = str;
        return true;
    }
}
Пример #2
0
bool Nicookie::safariFindPage(QIODevice &device)
{
    qint64 begin_pos = device.pos();

    // Page Header
    quint32 page_header = readUint32BE(device);
    if (page_header != 0x00000100) {
        setError(Nicookie::InvalidDataFormtaError);
        return false;
    }

    // No. of cookies
    quint32 cookie_num = readUint32LE(device);
    if (cookie_num == 0) {
        // エラーじゃ無い?
        return false;
    }

    // Cookie N offset
    QList<quint32> cookie_offset_list;
    for (quint32 i = 0; i < cookie_num; i++) {
        cookie_offset_list.append(readUint32LE(device));
    }

    // Cookie N
    for (auto &cookie_offset: cookie_offset_list) {
        device.seek(begin_pos + cookie_offset);
        if (safariFindCookie(device)) return true;
    }

    return false;
}
qint64 QIODeviceProto::pos() const
{
  QIODevice *item = qscriptvalue_cast<QIODevice*>(thisObject());
  if (item)
    return item->pos();
  return 0;
}
Пример #4
0
int64_t khopper::ffmpeg::seek( void * opaque, int64_t offset, int whence ) {
	QIODevice * device = static_cast< QIODevice * >( opaque );
	switch( whence ) {
	case SEEK_CUR:
		offset += device->pos();
		break;
	case SEEK_END:
		offset = device->size();
		break;
	case AVSEEK_SIZE:
		return device->size();
	default:
		;
	}
	device->seek( offset );
	return device->pos();
}
Пример #5
0
bool ExternalFile::readItem( QDataStream& in, ItemData& itemData, DatFormat *datFormat, TibiaModule *tibiaModule, qint32 index, quint32& address, QString& error )
{
    QIODevice *device = in.device();
    if( !device )
        return false;

    quint8 type = 0;
    in >> type;

    if( type != ITEM_TYPE_ITEM && type != ITEM_TYPE_OUTFIT && type != ITEM_TYPE_EFFECT && type != ITEM_TYPE_PROJECTILE ) {
        error = QObject::tr( "Unknown Item type" );
        return false;
    }

    ItemData d_itemData;
    if( datFormat ) {
        if( !ItemFile::loadItem( datFormat, in, d_itemData, error ) )
            return false;
    }

    d_itemData.parent = ITEM_PARENT_EXTERNAL;
    d_itemData.type = type;

    address = 0;

    if( !device->atEnd() ) {
        quint32 spriteCount = 0, now = 0, offset = 0;
        in >> spriteCount;
        address = device->pos();
        now = device->pos();
        for( quint32 i = 0; i < spriteCount; i++ ) {
            device->seek( now );
            in >> offset;
            if ( offset == 0x00000000 || offset > device->size() ) { // Direct to an image that doesnt exist or out of boundaries
                now += sizeof( quint32 );
                continue;
            }

            QMutex mutex;
            mutex.lock();
            SharedResource *resource = &g_resourceHandler.addResource(RESOURCE_TYPE_SPRITE, index, i, tibiaModule);
            d_itemData.setSpriteResource(i, *resource);
            mutex.unlock();
            now += sizeof( quint32 );
        }
    }
Пример #6
0
toff_t okular_tiffSeekProc( thandle_t handle, toff_t offset, int whence )
{
    QIODevice * device = static_cast< QIODevice * >( handle );
    switch ( whence )
    {
        case SEEK_SET:
            device->seek( offset );
            break;
        case SEEK_CUR:
            device->seek( device->pos() + offset );
            break;
        case SEEK_END:
            device->seek( device->size() + offset );
            break;
    }

    return device->pos();
}
Пример #7
0
voidpf ZCALLBACK qiodevice_open_file_func (
   voidpf opaque,
   voidpf file,
   int mode)
{
    QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
    QIODevice *iodevice = reinterpret_cast<QIODevice*>(file);
    QIODevice::OpenMode desiredMode;
    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
        desiredMode = QIODevice::ReadOnly;
    else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
        desiredMode = QIODevice::ReadWrite;
    else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
        desiredMode = QIODevice::WriteOnly;
    if (iodevice->isOpen()) {
        if ((iodevice->openMode() & desiredMode) == desiredMode) {
            if (desiredMode != QIODevice::WriteOnly
                    && iodevice->isSequential()) {
                // We can use sequential devices only for writing.
                delete d;
                return NULL;
            } else {
                if ((desiredMode & QIODevice::WriteOnly) != 0) {
                    // open for writing, need to seek existing device
                    if (!iodevice->isSequential()) {
                        iodevice->seek(0);
                    } else {
                        d->pos = iodevice->pos();
                    }
                }
            }
            return iodevice;
        } else {
            delete d;
            return NULL;
        }
    }
    iodevice->open(desiredMode);
    if (iodevice->isOpen()) {
        if (desiredMode != QIODevice::WriteOnly && iodevice->isSequential()) {
            // We can use sequential devices only for writing.
            iodevice->close();
            delete d;
            return NULL;
        } else {
            return iodevice;
        }
    } else {
        delete d;
        return NULL;
    }
}
Пример #8
0
Tellico::Data::CollPtr AMCImporter::collection() {
  if(m_coll) {
    return m_coll;
  }

  if(!fileRef().open()) {
    return Data::CollPtr();
  }

  QIODevice* f = fileRef().file();
  m_ds.setDevice(f);
  // AMC is always little-endian? can't confirm
  m_ds.setByteOrder(QDataStream::LittleEndian);
  emit signalTotalSteps(this, f->size());

  const uint l = AMC_FILE_ID.length();
  QVector<char> buffer(l+1);
  m_ds.readRawData(buffer.data(), l);
  QString version = QString::fromLocal8Bit(buffer.data(), l);
  QRegExp versionRx(QLatin1String(".+AMC_(\\d+)\\.(\\d+).+"));
  if(versionRx.indexIn(version) == -1) {
    myDebug() << "no file id match";
    return Data::CollPtr();
  }

  m_coll = new Data::VideoCollection(true);

  m_majVersion = versionRx.cap(1).toInt();
  m_minVersion = versionRx.cap(2).toInt();
//  myDebug() << m_majVersion << "-" << m_minVersion;

  readString(); // name
  readString(); // email
  if(m_majVersion <= 3 && m_minVersion < 5) {
    readString(); // icq
  }
  readString(); // webpage
  readString(); // description

  const bool showProgress = options() & ImportProgress;

  while(!m_cancelled && !m_failed && !f->atEnd()) {
    readEntry();
    if(showProgress) {
      emit signalProgress(this, f->pos());
      qApp->processEvents();
    }
  }

  return m_coll;
}
Пример #9
0
ZPOS64_T ZCALLBACK qiodevice64_tell_file_func (
   voidpf opaque,
   voidpf stream)
{
    QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
    QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
    qint64 ret;
    if (iodevice->isSequential()) {
        ret = d->pos;
    } else {
        ret = iodevice->pos();
    }
    return static_cast<ZPOS64_T>(ret);
}
Пример #10
0
quint16 readCompressedUnsignedWord(QIODevice &device)
{
    qint64 pos = device.pos();
    quint8 lowByte = readUnsignedByte(device);
    if((lowByte & 1) != 0)
    {
        seekFile(device, pos);
        return readUnsignedWord(device) / 2;
    }
    else
    {
        return static_cast<quint16>(lowByte) / 2;
    }
}
Пример #11
0
//--------------------------------------------------------------------
void tst_QIODevice::peek()
{
    QBuffer buffer;
    QFile::remove("peektestfile");
    QFile file("peektestfile");

    for (int i = 0; i < 2; ++i) {
        QIODevice *device = i ? (QIODevice *)&file : (QIODevice *)&buffer;

        device->open(QBuffer::ReadWrite);
        device->write("ZXCV");

        device->seek(0);
        QCOMPARE(device->peek(4), QByteArray("ZXCV"));
        QCOMPARE(device->pos(), qint64(0));
        device->write("ABCDE");
        device->seek(3);
        QCOMPARE(device->peek(1), QByteArray("D"));
        QCOMPARE(device->peek(5), QByteArray("DE"));
        device->seek(0);
        QCOMPARE(device->read(4), QByteArray("ABCD"));
        QCOMPARE(device->pos(), qint64(4));

        device->seek(0);
        device->write("ZXCV");
        device->seek(0);
        char buf[5];
        buf[4] = 0;
        device->peek(buf, 4);
        QCOMPARE(static_cast<const char *>(buf), "ZXCV");
        QCOMPARE(device->pos(), qint64(0));
        device->read(buf, 4);
        QCOMPARE(static_cast<const char *>(buf), "ZXCV");
        QCOMPARE(device->pos(), qint64(4));
    }
    QFile::remove("peektestfile");
}
Пример #12
0
uLong ZCALLBACK qiodevice_tell_file_func (
   voidpf opaque,
   voidpf stream)
{
    QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
    QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
    uLong ret;
    qint64 ret64;
    if (iodevice->isSequential()) {
        ret64 = d->pos;
    } else {
        ret64 = iodevice->pos();
    }
    ret = static_cast<uLong>(ret64);
    return ret;
}
Пример #13
0
qint32 readCompressedSignedDWord(QIODevice &device)
{
    qint64 pos = device.pos();
    quint8 lowByte = readUnsignedByte(device);
    if((lowByte & 1) != 0)
    {
        seekFile(device, pos);
        return static_cast<qint32>((static_cast<qint64>(readUnsignedDWord(
                        device)) - Q_INT64_C(0x80000000)) / Q_INT64_C(2));
    }
    else
    {
        seekFile(device, pos);
        return static_cast<qint32>((static_cast<qint64>(readUnsignedWord(device))
                - Q_INT64_C(0x8000)) / Q_INT64_C(2));
    }
}
Пример #14
0
sf_count_t nSndfileStream_vio_seek(sf_count_t offset, int whence, void * userData)
{
    QIODevice * device = ((QIODevice*)userData);
    switch(whence)
    {
    case SEEK_SET:
        device->seek(offset);
        return 0;

    case SEEK_CUR:
        device->seek(device->pos()+offset);
        return 0;

    case SEEK_END:
        device->seek(device->size()-offset);
        return 0;
    }

    return -1;
}
Пример #15
0
/*! Read and parse the header block from the given input device stream. 
    The stream must be random access, binary and positioned to 0.

	 \retval true the header was read successfully.
	 \retval false the header failed to read for some reason.
 */
bool BlockHeader::Read(
	QIODevice& fIn	//! Input stream (binary, random access).
							 )
{
	ASSERT(fIn.isSequential()==false);
	ASSERT(fIn.isReadable()==true);
	ASSERT(fIn.isTextModeEnabled()==false);
	ASSERT(fIn.pos() == 0);
	ASSERT(sizeof(float) == 4);
	
	QDataStream in(&fIn);
	// Check the magic number
	quint32 uiMagic;
	in >> uiMagic;
	// OK, try to read the rest of the header.
	if(uiMagic == MAGIC_NUMBER) {
		in >> m_uiVersion;
		in >> m_iJulianDay;
		
		in >> m_fOriginLon;
		in >> m_fOriginLat;
		in >> m_fArcLon;
		in >> m_fArcLat;
		
		in >> m_uiRasterPos;
		in >> m_uiVectorPos;
		
		// The next 24 bytes are reserved. 
		// They should be zero, but we do not read them, just skip them.
		// Some additional checks are fast and harmless.
		if(   m_uiVersion >= 1 
		   && m_iJulianDay > 2454110 // 9.Jan.2007
			&& m_fArcLon >= 1.0f
			&& m_fArcLat >= 1.0f
			&& fIn.size() >= MBH_HEADER_SIZE
		  ) {
			fIn.seek(MBH_HEADER_SIZE); // position the file pointer to the 64-th byte.
			return true;
		}
	}
Пример #16
0
bool Nicookie::safariFindFile(QIODevice &device) {
    // Signature
    QByteArray headr_signature("cook", 4);
    if (headr_signature != device.read(4)) {
        setError(Nicookie::InvalidDataFormtaError);
        return false;
    }

    // No. of pages
    quint32 page_num = readUint32BE(device);
    if (page_num == 0) {
        setError(Nicookie::NotFoundDataError);
        return false;
    }

    // Page N Size
    QList<quint32> page_size_list;
    for (quint32 i = 0; i < page_num; ++i) {
        page_size_list.append(readUint32BE(device));
    }
    if (device.atEnd()) {
        setError(Nicookie::InvalidDataFormtaError);
        return false;
    }

    // Page N
    for (auto &page_size: page_size_list) {
        qint64 pos = device.pos();
        if (safariFindPage(device)) return true;
        device.seek(pos + page_size);
    }

    if (!hasError()) {
        setError(Nicookie::NotFoundDataError);
    }
    return false;
}
Пример #17
0
static int64_t SeekFunc(void *opaque, int64_t offset, int whence)
{
    QIODevice *io = (QIODevice*)opaque;

    if (whence == AVSEEK_SIZE)
    {
        return io->size();
    }
    else if (whence == SEEK_SET)
    {
        if (offset <= io->size())
            return io->seek(offset);
        else
            return -1;
    }
    else if (whence == SEEK_END)
    {
        int64_t newPos = io->size() + offset;
        if (newPos >= 0 && newPos <= io->size())
            return io->seek(newPos);
        else
            return -1;
    }
    else if (whence == SEEK_CUR)
    {
        int64_t newPos = io->pos() + offset;
        if (newPos >= 0 && newPos < io->size())
            return io->seek(newPos);
        else
            return -1;
    }
    else
        return -1;

     return -1;
}
Пример #18
0
/*!
    Only Size option is supported
*/
QVariant QWbmpHandler::option(ImageOption option) const
{
    if (option == QImageIOHandler::Size) {
        QIODevice *device = QImageIOHandler::device();
        if (device->isSequential())
            return QVariant();

        // Save old position
        qint64 oldPos = device->pos();

        WBMPHeader hdr;
        if (readWBMPHeader(device, &hdr)) {
            device->seek(oldPos);
            return QSize(hdr.width, hdr.height);
        }

        device->seek(oldPos);

    } else if (option == QImageIOHandler::ImageFormat) {
        return QVariant(QImage::Format_Mono);
    }

    return QVariant();
}
Пример #19
0
bool KAr::openArchive( QIODevice::OpenMode mode )
{
    // Open archive

    if ( mode == QIODevice::WriteOnly )
        return true;
    if ( mode != QIODevice::ReadOnly && mode != QIODevice::ReadWrite )
    {
        //qWarning() << "Unsupported mode " << mode;
        return false;
    }

    QIODevice* dev = device();
    if ( !dev )
        return false;

    QByteArray magic = dev->read( 7 );
    if ( magic != "!<arch>" ) {
        //qWarning() << "Invalid main magic";
        return false;
    }

    char *ar_longnames = 0;
    while (! dev->atEnd()) {
        QByteArray ar_header;
        ar_header.resize(61);

        dev->seek( dev->pos() + (2 - (dev->pos() % 2)) % 2 ); // Ar headers are padded to byte boundary

        if ( dev->read(ar_header.data(), 60) != 60 ) { // Read ar header
            //qWarning() << "Couldn't read header";
            delete[] ar_longnames;
            //return false;
            return true; // Probably EOF / trailing junk
        }

        if (!ar_header.endsWith("`\n")) { // Check header magic // krazy:exclude=strings
            //qWarning() << "Invalid magic";
            delete[] ar_longnames;
            return false;
        }

        QByteArray name = ar_header.mid( 0, 16 ); // Process header
        const int date = ar_header.mid( 16, 12 ).toInt();
        //const int uid = ar_header.mid( 28, 6 ).toInt();
        //const int gid = ar_header.mid( 34, 6 ).toInt();
        const int mode = ar_header.mid( 40, 8 ).toInt();
        const qint64 size = ar_header.mid( 48, 10 ).toInt();

        bool skip_entry = false; // Deal with special entries
        if (name.mid(0, 1) == "/") {
            if (name.mid(1, 1) == "/") { // Longfilename table entry
                delete[] ar_longnames;
                ar_longnames = new char[size + 1];
                ar_longnames[size] = '\0';
                dev->read(ar_longnames, size);
                skip_entry = true;
                //qDebug() << "Read in longnames entry";
            } else if (name.mid(1, 1) == " ") { // Symbol table entry
                //qDebug() << "Skipped symbol entry";
                dev->seek( dev->pos() + size );
                skip_entry = true;
            } else { // Longfilename
                //qDebug() << "Longfilename #" << name.mid(1, 15).toInt();
                if (! ar_longnames) {
                    //qWarning() << "Invalid longfilename reference";
                    delete[] ar_longnames;
                    return false;
                }
                name = &ar_longnames[name.mid(1, 15).toInt()];
                name = name.left(name.indexOf("/"));
            }
        }
        if (skip_entry) continue;

        name = name.trimmed(); // Process filename
        name.replace( '/', QByteArray() );
        //qDebug() << "Filename: " << name << " Size: " << size;

        KArchiveEntry* entry = new KArchiveFile(this, QString::fromLocal8Bit(name.constData()), mode, date,
                                                rootDir()->user(), rootDir()->group(), /*symlink*/ QString(),
                                                dev->pos(), size);
        rootDir()->addEntry(entry); // Ar files don't support directories, so everything in root

        dev->seek( dev->pos() + size ); // Skip contents
    }
    delete[] ar_longnames;

    return true;
}
Пример #20
0
static
void CALLBACK_CALL_TYPE iod_read_fn(png_structp png_ptr, png_bytep data, png_size_t length)
{
    QPngHandlerPrivate *d = (QPngHandlerPrivate *)png_get_io_ptr(png_ptr);
    QIODevice *in = d->q->device();

    if (d->state == QPngHandlerPrivate::ReadingEnd && !in->isSequential() && (in->size() - in->pos()) < 4 && length == 4) {
        // Workaround for certain malformed PNGs that lack the final crc bytes
        uchar endcrc[4] = { 0xae, 0x42, 0x60, 0x82 };
        qMemCopy(data, endcrc, 4);
        in->seek(in->size());
        return;
    }

    while (length) {
        int nr = in->read((char*)data, length);
        if (nr <= 0) {
            png_error(png_ptr, "Read Error");
            return;
        }
        length -= nr;
    }
}
Пример #21
0
bool KTar::openArchive( QIODevice::OpenMode mode ) {

    if ( !(mode & QIODevice::ReadOnly) )
        return true;

    if ( !d->fillTempFile( fileName() ) )
        return false;

    // We'll use the permission and user/group of d->rootDir
    // for any directory we emulate (see findOrCreate)
    //struct stat buf;
    //stat( fileName(), &buf );

    d->dirList.clear();
    QIODevice* dev = device();

    if ( !dev )
        return false;

    // read dir information
    char buffer[ 0x200 ];
    bool ende = false;
    do
    {
        QString name;
        QString symlink;

        // Read header
        qint64 n = d->readHeader( buffer, name, symlink );
        if (n < 0) return false;
        if (n == 0x200)
        {
            bool isdir = false;

            if ( name.endsWith( QLatin1Char( '/' ) ) )
            {
                isdir = true;
                name.truncate( name.length() - 1 );
            }

            QByteArray prefix = QByteArray(buffer + 0x159, 155);
            if (prefix[0] != '\0') {
                name = (QString::fromLatin1(prefix.constData()) + QLatin1Char('/') +  name);
            }

            int pos = name.lastIndexOf( QLatin1Char('/') );
            QString nm = ( pos == -1 ) ? name : name.mid( pos + 1 );

            // read access
            buffer[ 0x6b ] = 0;
            char *dummy;
            const char* p = buffer + 0x64;
            while( *p == ' ' ) ++p;
            int access = (int)strtol( p, &dummy, 8 );

            // read user and group
            QString user = QString::fromLocal8Bit( buffer + 0x109 );
            QString group = QString::fromLocal8Bit( buffer + 0x129 );

            // read time
            buffer[ 0x93 ] = 0;
            p = buffer + 0x88;
            while( *p == ' ' ) ++p;
            uint time = (int)strtol( p, &dummy, 8 );

            // read type flag
            char typeflag = buffer[ 0x9c ];
            // '0' for files, '1' hard link, '2' symlink, '5' for directory
            // (and 'L' for longlink fileNames, 'K' for longlink symlink targets)
            // 'D' for GNU tar extension DUMPDIR, 'x' for Extended header referring
            // to the next file in the archive and 'g' for Global extended header

            if ( typeflag == '5' )
                isdir = true;

            bool isDumpDir = false;
            if ( typeflag == 'D' )
            {
                isdir = false;
                isDumpDir = true;
            }
            //qDebug() << nm << "isdir=" << isdir << "pos=" << dev->pos() << "typeflag=" << typeflag << " islink=" << ( typeflag == '1' || typeflag == '2' );

            if (typeflag == 'x' || typeflag == 'g') { // pax extended header, or pax global extended header
                // Skip it for now. TODO: implement reading of extended header, as per http://pubs.opengroup.org/onlinepubs/009695399/utilities/pax.html
                (void)dev->read( buffer, 0x200 );
                continue;
            }

            if (isdir)
                access |= S_IFDIR; // f*cking broken tar files

            KArchiveEntry* e;
            if ( isdir )
            {
                //qDebug() << "directory" << nm;
                e = new KArchiveDirectory( this, nm, access, KArchivePrivate::time_tToDateTime(time), user, group, symlink );
            }
            else
            {
                // read size
                QByteArray sizeBuffer( buffer + 0x7c, 12 );
                qint64 size = sizeBuffer.trimmed().toLongLong( 0, 8 /*octal*/ );
                //qDebug() << "sizeBuffer='" << sizeBuffer << "' -> size=" << size;

                // for isDumpDir we will skip the additional info about that dirs contents
                if ( isDumpDir )
                {
                    //qDebug() << nm << "isDumpDir";
                    e = new KArchiveDirectory( this, nm, access, KArchivePrivate::time_tToDateTime(time), user, group, symlink );
                }
                else
                {

                    // Let's hack around hard links. Our classes don't support that, so make them symlinks
                    if ( typeflag == '1' )
                    {
                        //qDebug() << "Hard link, setting size to 0 instead of" << size;
                        size = 0; // no contents
                    }

                    //qDebug() << "file" << nm << "size=" << size;
                    e = new KArchiveFile( this, nm, access, KArchivePrivate::time_tToDateTime(time), user, group, symlink,
                                          dev->pos(), size );
                }

                // Skip contents + align bytes
                qint64 rest = size % 0x200;
                qint64 skip = size + (rest ? 0x200 - rest : 0);
                //qDebug() << "pos()=" << dev->pos() << "rest=" << rest << "skipping" << skip;
                if (! dev->seek( dev->pos() + skip ) ) {
                    //qWarning() << "skipping" << skip << "failed";
                }
            }

            if ( pos == -1 )
            {
                if (nm == QLatin1String(".")) { // special case
                    Q_ASSERT( isdir );
                    if (isdir) {
                        setRootDir( static_cast<KArchiveDirectory *>( e ) );
                    }
                } else {
                    rootDir()->addEntry( e );
                }
            }
            else
            {
                // In some tar files we can find dir/./file => call cleanPath
                QString path = QDir::cleanPath( name.left( pos ) );
                // Ensure container directory exists, create otherwise
                KArchiveDirectory * d = findOrCreate( path );
                d->addEntry( e );
            }
        }
        else
        {
            //qDebug("Terminating. Read %d bytes, first one is %d", n, buffer[0]);
            d->tarEnd = dev->pos() - n; // Remember end of archive
            ende = true;
        }
    } while( !ende );
    return true;
}
int TAbstractWebSocket::parse(QByteArray &recvData)
{
    tSystemDebug("parse enter  data len:%d  sid:%d", recvData.length(), socketId());
    if (websocketFrames().isEmpty()) {
        websocketFrames().append(TWebSocketFrame());
    } else {
        const TWebSocketFrame &f = websocketFrames().last();
        if (f.state() == TWebSocketFrame::Completed) {
            websocketFrames().append(TWebSocketFrame());
        }
    }

    TWebSocketFrame *pfrm = &websocketFrames().last();
    quint8  b;
    quint16 w;
    quint32 n;
    quint64 d;

    QDataStream ds(recvData);
    ds.setByteOrder(QDataStream::BigEndian);
    QIODevice *dev = ds.device();
    QByteArray hdr;

    while (!ds.atEnd()) {
        switch (pfrm->state()) {
        case TWebSocketFrame::Empty: {
            hdr = dev->peek(14);
            QDataStream dshdr(hdr);
            dshdr.setByteOrder(QDataStream::BigEndian);
            QIODevice *devhdr = dshdr.device();

            if (Q_UNLIKELY(devhdr->bytesAvailable() < 2)) {
                goto parse_end;
            }

            dshdr >> b;
            pfrm->setFirstByte(b);
            dshdr >> b;
            bool maskFlag = b & 0x80;
            quint8 len = b & 0x7f;

            // payload length
            switch (len) {
            case 126:
                if (Q_UNLIKELY(devhdr->bytesAvailable() < (int)sizeof(w))) {
                    goto parse_end;
                }
                dshdr >> w;
                if (Q_UNLIKELY(w < 126)) {
                    tSystemError("WebSocket protocol error  [%s:%d]", __FILE__, __LINE__);
                    return -1;
                }
                pfrm->setPayloadLength( w );
                break;

            case 127:
                if (Q_UNLIKELY(devhdr->bytesAvailable() < (int)sizeof(d))) {
                    goto parse_end;
                }
                dshdr >> d;
                if (Q_UNLIKELY(d <= 0xFFFF)) {
                    tSystemError("WebSocket protocol error  [%s:%d]", __FILE__, __LINE__);
                    return -1;
                }
                pfrm->setPayloadLength( d );
                break;

            default:
                pfrm->setPayloadLength( len );
                break;
            }

            // Mask key
            if (maskFlag) {
                if (Q_UNLIKELY(devhdr->bytesAvailable() < (int)sizeof(n))) {
                    goto parse_end;
                }
                dshdr >> n;
                pfrm->setMaskKey( n );
            }

            if (pfrm->payloadLength() == 0) {
                pfrm->setState(TWebSocketFrame::Completed);
            } else {
                pfrm->setState(TWebSocketFrame::HeaderParsed);
                if (pfrm->payloadLength() >= 2 * 1024 * 1024 * 1024ULL) {
                    tSystemError("Too big frame  [%s:%d]", __FILE__, __LINE__);
                    pfrm->clear();
                } else {
                    pfrm->payload().reserve(pfrm->payloadLength());
                }
            }

            tSystemDebug("WebSocket parse header pos: %lld", devhdr->pos());
            tSystemDebug("WebSocket payload length:%lld", pfrm->payloadLength());

            int hdrlen = hdr.length() - devhdr->bytesAvailable();
            ds.skipRawData(hdrlen);  // Forwards the pos
            break; }

        case TWebSocketFrame::HeaderParsed:  // fall through
        case TWebSocketFrame::MoreData: {
            tSystemDebug("WebSocket reading payload:  available length:%lld", dev->bytesAvailable());
            tSystemDebug("WebSocket parsing  length to read:%llu  current buf len:%d", pfrm->payloadLength(), pfrm->payload().size());
            quint64 size = qMin((pfrm->payloadLength() - pfrm->payload().size()), (quint64)dev->bytesAvailable());
            if (Q_UNLIKELY(size == 0)) {
                Q_ASSERT(0);
                break;
            }

            char *p = pfrm->payload().data() + pfrm->payload().size();
            size = ds.readRawData(p, size);

            if (pfrm->maskKey()) {
                // Unmask
                const quint8 mask[4] = { quint8((pfrm->maskKey() & 0xFF000000) >> 24),
                                         quint8((pfrm->maskKey() & 0x00FF0000) >> 16),
                                         quint8((pfrm->maskKey() & 0x0000FF00) >> 8),
                                         quint8((pfrm->maskKey() & 0x000000FF)) };

                int i = pfrm->payload().size();
                const char *end = p + size;
                while (p < end) {
                    *p++ ^= mask[i++ % 4];
                }
            }
            pfrm->payload().resize( pfrm->payload().size() + size );
            tSystemDebug("WebSocket payload curent buf len: %d", pfrm->payload().length());

            if ((quint64)pfrm->payload().size() == pfrm->payloadLength()) {
                pfrm->setState(TWebSocketFrame::Completed);
                tSystemDebug("Parse Completed   payload len: %d", pfrm->payload().size());
            } else {
                pfrm->setState(TWebSocketFrame::MoreData);
                tSystemDebug("Parse MoreData   payload len: %d", pfrm->payload().size());
            }
            break; }

        case TWebSocketFrame::Completed:  // fall through
        default:
            Q_ASSERT(0);
            break;
        }

        if (pfrm->state() == TWebSocketFrame::Completed) {
            if (Q_UNLIKELY(!pfrm->validate())) {
                pfrm->clear();
                continue;
            }

            // Fragmented message validation
            if (pfrm->opCode() == TWebSocketFrame::Continuation) {
                if (websocketFrames().count() >= 2) {
                    const TWebSocketFrame &before = websocketFrames()[websocketFrames().count() - 2];
                    if (before.isFinalFrame() || before.isControlFrame()) {
                        pfrm->clear();
                        tSystemWarn("Invalid continuation frame detected  [%s:%d]", __FILE__, __LINE__);
                        continue;
                    }
                }
            }

            // In case of control frame, moves forward after previous control frames
            if (pfrm->isControlFrame()) {
                if (websocketFrames().count() >= 2) {
                    TWebSocketFrame frm = websocketFrames().takeLast();
                    QMutableListIterator<TWebSocketFrame> it(websocketFrames());
                    while (it.hasNext()) {
                        TWebSocketFrame &f = it.next();
                        if (!f.isControlFrame()) {
                            break;
                        }
                    }

                    it.insert(frm);
                }
            }

            if (!ds.atEnd()) {
                // Prepare next frame
                websocketFrames().append(TWebSocketFrame());
                pfrm = &websocketFrames().last();
            } else {
                break;
            }
        }
    }

parse_end:
    int parsedlen = recvData.size() - dev->bytesAvailable();
    recvData.remove(0, parsedlen);
    return parsedlen;
}
Пример #23
0
bool JArchivePrivate::read_contents() {
	if (!m_file) return false;
	m_records.clear();
	m_record_keys.clear();
	m_file->seek(0);
	qint32 header_size,version_number;
	{
		qint32 code=read_int32(); 
		if (code!=JARCHIVE_BEGIN_FILE_CODE) {
			qWarning() << "Error in JArchivePrivate::read_contents. JARCHIVE_BEGIN_FILE_CODE does not match" << code << JARCHIVE_BEGIN_FILE_CODE;
			return false;
		}
		header_size=read_int32();
		version_number=read_int32();
	}
	m_read_version_number=version_number;
	
	m_file->seek(header_size);
	qint64 filepos=m_file->pos();
	bool done=false;
	while ((!m_file->atEnd())&&(!done)) {
		qint32 code=read_int32();
		if (code==JARCHIVE_BEGIN_RECORD_CODE) {
			qint32 length_of_header,length_of_key,is_compressed;
			qint32 length_of_data,compressed_length_of_data;
			QByteArray key;
			qint32 length_of_data_type;
			QByteArray data_type;
			if (version_number<=1) {
				length_of_header=read_int32(); //4
				compressed_length_of_data=read_int32(); //4
				length_of_data=read_int32(); //4
				length_of_key=read_int32(); //4
				key=read_bytes(length_of_key);
				is_compressed=read_int32(); //4
			}
			else {
				length_of_header=read_int32(); //4
				compressed_length_of_data=read_int32(); //4
				length_of_data=read_int32(); //4
				length_of_key=read_int32(); //4
				key=read_bytes(length_of_key); //length_of_key
				is_compressed=read_int32(); //4
				length_of_data_type=read_int32(); //4
				data_type=read_bytes(length_of_data_type); //4
			}
			JArchiveRecordInfo R;
			R.compressed_length_of_data=compressed_length_of_data;
			R.is_compressed=(is_compressed!=0);
			R.key=QString(key);
			R.data_type=QString(data_type);
			R.length_of_data=length_of_data;
			R.pos=filepos+length_of_header;
			m_records[QString(key)]=R;
			m_record_keys.append(QString(key));
			m_file->seek(filepos+length_of_header+compressed_length_of_data);
			filepos=m_file->pos();
		}
		else {
		}
	}
	return true;
}