Example #1
0
bool ParseOBJ::maybeReadWhitespace() {
    bool changedLines = false;

    while (remainingCharacters > 0) {
        switch (*nextCharacter) {
        case '\n':
        case '\r':
            {
                char c = *nextCharacter;
                consumeCharacter();
                ++m_line;
                changedLines = true;
                if ((remainingCharacters > 0) && (c != *nextCharacter) && 
                    ((*nextCharacter == '\r') || (*nextCharacter == '\n'))) {
                    // This is part of a two-character, e.g., Mac or
                    // Windows.  Consume the next character as well.
                    consumeCharacter();
                }
            }
            break;

        case ' ':
        case '\t':
            // Consume whitespace
            consumeCharacter();
            break;

        case '#':
            // Consume comment
            readUntilNewline();
            // Don't consume the newline; we'll catch it on the next
            // iteration
            break;

        default:
            return changedLines;
        }
    }

    return true;
}
Example #2
0
void ParseOBJ::processCommand(const Command command) {
    switch (command) {
    case VERTEX:
        maybeReadWhitespace();
        vertexArray.append(readVector3());
        // Consume anything else on this line
        readUntilNewline();
        break;

    case TEXCOORD:
        maybeReadWhitespace();
        texCoord0Array.append(readVector2());
        if (m_objOptions.texCoord1Mode == ParseOBJ::Options::UNPACK_FROM_TEXCOORD0_Z) {
            float w = readFloat();
            Vector2 texCoord1;
            texCoord1.x = floor(w / (2.0f * 2048.0f)) / 2048.0f;
            texCoord1.y = (w - 2.0f * 2048.0f * floor(w / (2.0f * 2048.0f))) / 2048.0f;
            texCoord1Array.append(texCoord1);
        } else if (m_objOptions.texCoord1Mode == ParseOBJ::Options::TEXCOORD0_ZW) {
            texCoord1Array.append(readVector2());
        }

        // Consume anything else on this line
        readUntilNewline();
        break;

    case NORMAL:
        maybeReadWhitespace();
        normalArray.append(readVector3());
        // Consume anything else on this line
        readUntilNewline();
        break;

    case FACE:
        readFace();
        // Faces consume newlines by themselves
        break;

    case GROUP:
        {
            // Change group
            const String& groupName = readName();

            shared_ptr<Group>& g = groupTable.getCreate(groupName);

            if (isNull(g)) {
                // Newly created
                g = Group::create();
                g->name = groupName;
            }

            m_currentGroup = g;
        }
        // Consume anything else on this line
        readUntilNewline();
        break;

    case USEMTL:
        {
            // Change the mesh within the group
            const String& materialName = readName();
            m_currentMaterial = getMaterial(materialName);

            // Force re-obtaining or creating of the appropriate mesh
            m_currentMesh.reset();
        }
        // Consume anything else on this line
        readUntilNewline();
        break;

    case MTLLIB:
        {
            // Specify material library 
            String mtlFilename = readName();
            mtlArray.append(mtlFilename);
            mtlFilename = FilePath::concat(m_basePath, mtlFilename);

            TextInput ti2(mtlFilename);
            m_currentMaterialLibrary.parse(ti2);
        }
        // Consume anything else on this line
        readUntilNewline();
        break;

    case UNKNOWN:
        // Nothing to do
        readUntilNewline();
        break;
    }
}
bool
PowerTapDevice::download( const QDir &tmpdir,
                         QList<DeviceDownloadFile> &files,
                         QString &err)
{
    if (!dev->open(err)) {
        err = tr("ERROR: open failed: ") + err;
        return false;
    }
    // make several attempts at reading the version
    int attempts = 3;
    int veridx = -1;
    int version_len;
    char vbuf[256];
    QByteArray version;

    do {
	if (!doWrite(dev, 0x56, false, err)) // 'V'
	    return false;

    emit updateStatus( tr("Reading version...") );
    if(m_Cancelled) {
        err = tr("download cancelled");
	    return false;
	}

	version_len = readUntilNewline(dev, vbuf, sizeof(vbuf), err);
	if (version_len < 0) {
	    err = tr("Error reading version: ") + err;
	    return false;
	}
	if (PT_DEBUG) {
	    printf("read version \"%s\"\n",
		   cEscape(vbuf, version_len).toLatin1().constData());
	}
	version = QByteArray(vbuf, version_len);

	// We expect the version string to be something like
	// "VER 02.21 PRO...", so if we see two V's, it's probably
	// because there's a hardware echo going on.
	veridx = version.indexOf("VER");

    } while ((--attempts > 0) && (veridx < 0));

    if (veridx < 0) {
	err = QString(tr("Unrecognized version \"%1\""))
	    .arg(cEscape(vbuf, version_len));
	return false;
    }
    bool hwecho = version.indexOf('V') < veridx;
    if (PT_DEBUG) printf("hwecho=%s\n", hwecho ? "true" : "false");

    emit updateStatus( tr("Reading header...") );
    if(m_Cancelled) {
        err = tr("download cancelled");
        return false;
    }

    if (!doWrite(dev, 0x44, hwecho, err)) // 'D'
        return false;
    unsigned char header[6];
    int header_len = dev->read(header, sizeof(header), err);
    if (header_len != 6) {
        if (header_len < 0)
            err = tr("ERROR: reading header: ") + err;
        else
            err = tr("ERROR: timeout reading header");
        return false;
    }
    if (PT_DEBUG) {
        printf("read header \"%s\"\n",
               cEscape((char*) header,
                       sizeof(header)).toLatin1().constData());
    }
    QVector<unsigned char> records;
    for (size_t i = 0; i < sizeof(header); ++i)
        records.append(header[i]);

    emit updateStatus( tr("Reading data...") );
    if(m_Cancelled) {
        err = tr("download cancelled");
        return false;
    }
    double recIntSecs = 0.0;

    fflush(stdout);
    while (true) {
        if (PT_DEBUG) printf("reading block\n");
        unsigned char buf[256 * 6 + 1];
        int n = dev->read(buf, 2, err);
        if (n < 2) {
            if (n < 0)
                err = tr("ERROR: reading first two: ") + err;
            else
                err = tr("ERROR: timeout reading first two");
            return false;
        }
        if (PT_DEBUG) {
            printf("read 2 bytes: \"%s\"\n",
                   cEscape((char*) buf, 2).toLatin1().constData());
        }
        if (hasNewline((char*) buf, 2))
            break;
        unsigned count = 2;
        while (count < sizeof(buf)) {
            n = dev->read(buf + count, sizeof(buf) - count, err);
            if (n < 0) {
                err = tr("ERROR: reading block: ") + err;
                return false;
            }
            if (n == 0) {
                err = tr("ERROR: timeout reading block");
                return false;
            }
            if (PT_DEBUG) {
                printf("read %d bytes: \"%s\"\n", n,
                       cEscape((char*) buf + count, n).toLatin1().constData());
            }
            count += n;
        }
        unsigned csum = 0;
        for (int i = 0; i < ((int) sizeof(buf)) - 1; ++i)
            csum += buf[i];
        if ((csum % 256) != buf[sizeof(buf) - 1]) {
            err = tr("ERROR: bad checksum");
            return false;
        }
        if (PT_DEBUG) printf("good checksum\n");
        for (size_t i = 0; i < sizeof(buf) - 1; ++i)
            records.append(buf[i]);
        if (recIntSecs == 0.0) {
            unsigned char *data = records.data();
            bool bIsVer81 = PowerTapUtil::is_Ver81(data);
            for (int i = 0; i < records.size(); i += 6) {
                if (PowerTapUtil::is_config(data + i, bIsVer81)) {
                    unsigned unused1, unused2, unused3;
                    PowerTapUtil::unpack_config(
                        data + i, &unused1, &unused2,
                        &recIntSecs, &unused3, bIsVer81);
                }
            }
        }
        if (recIntSecs != 0.0) {
            int min = (int) round(records.size() / 6 * recIntSecs);
            emit updateProgress( QString(tr("progress: %1:%2"))
                .arg(min / 60)
                .arg(min % 60, 2, 10, QLatin1Char('0')));
        }
        if(m_Cancelled){
            err = tr("download cancelled");
            return false;
        }
        if (!doWrite(dev, 0x71, hwecho, err)) // 'q'
            return false;
    }

    QString tmpl = tmpdir.absoluteFilePath(".ptdl.XXXXXX");
    QTemporaryFile tmp(tmpl);
    tmp.setAutoRemove(false);
    if (!tmp.open()) {
        err = tr("Failed to create temporary file ")
            + tmpl + ": " + tmp.error();
        return false;
    }
    // QTemporaryFile initially has permissions set to 0600.
    // Make it readable by everyone.
    tmp.setPermissions(tmp.permissions()
                       | QFile::ReadOwner | QFile::ReadUser
                       | QFile::ReadGroup | QFile::ReadOther);

    DeviceDownloadFile file;
    file.extension = "raw";
    file.name = tmp.fileName();

    QTextStream os(&tmp);
    os << hex;
    os.setPadChar('0');

    bool time_set = false;
    unsigned char *data = records.data();
    bool bIsVer81 = PowerTapUtil::is_Ver81(data);

    for (int i = 0; i < records.size(); i += 6) {
        if (data[i] == 0 && !bIsVer81)
            continue;
        for (int j = 0; j < 6; ++j) {
            os.setFieldWidth(2);
            os << data[i+j];
            os.setFieldWidth(1);
            os << ((j == 5) ? "\n" : " ");
        }
        if (!time_set && PowerTapUtil::is_time(data + i, bIsVer81)) {
            struct tm time;
            time_t timet = PowerTapUtil::unpack_time(data + i, &time, bIsVer81);
            file.startTime.setTime_t( timet );
            time_set = true;
        }
    }
    if (!time_set) {
        err = tr("Failed to find start time.");
        tmp.setAutoRemove(true);
        return false;
    }

    // hack for CERVO bug dates >= 2016 set the year to 2000 (!)
    if (file.startTime.date().year() == 2000) {

        // it's in the past... so set year to this
        QDate date(QDate::currentDate().year(), file.startTime.date().month(), file.startTime.date().day());

        // is that a future date?
        if (date > QDate::currentDate()) date = date.addYears(-1);

        // now update for file, if it's valid otherwise keep as it is
        if(date.isValid()) file.startTime.setDate(date);
    }

    files << file;
    return true;
}