Ejemplo n.º 1
0
/*
 * copies "header" to a newly allocated data structure
 */
srmio_data_t srmio_data_header( srmio_data_t src, srmio_error_t *err )
{
	srmio_data_t dst;

	assert(src);

	if( NULL == ( dst = srmio_data_new( err ) ))
		return NULL;

	if( src->notes && NULL == ( dst->notes = strdup( src->notes ) ) ){
		srmio_error_errno( err, "data notes" );
		goto clean1;
	}

	if( src->athlete && NULL == ( dst->athlete = strdup( src->athlete ) ) ){
		srmio_error_errno( err, "data athlete");
		goto clean1;
	}

	dst->slope = src->slope;
	dst->zeropos = src->zeropos;
	dst->circum = src->circum;

	return dst;
clean1:
	srmio_data_free(dst);
	return NULL;
}
Ejemplo n.º 2
0
bool
SrmDevice::download( const QDir &tmpdir,
                    QList<DeviceDownloadFile> &files,
                    QString &err)
{
    srmio_error_t serr;
    struct _srmio_pc_xfer_block_t block;
    srmio_data_t data( NULL );
    srmio_data_t *splitList( NULL );
    srmio_data_t *split;
    int mfirst( -1 );
    size_t block_cnt, block_num( 0 );
    size_t prog_sum( 0 ), prog_prev( 0 );
    size_t chunks_done( 0 );
    srmio_time_t splitGap( 72000 ); // 2h - NOTE: we could make this configurable

    if( ! is_open ){
        if( ! open( err ) )
            return false;
    }

    // fetch preview in case user didn't
    if( srmio_pc_can_preview(pc) && rideList.size() == 0 ){
        if( ! preview( err ) )
            return false;
    }

    data = srmio_data_new( &serr );
    if( ! data ){
        err = tr("failed to allocate data handle: %1")
            .arg(serr.message);
        goto fail;
    }

    if( m_Cancelled ){
        err = tr("download cancelled");
        goto fail;
    }

    if( ! srmio_pc_xfer_start( pc, &serr )){
        err = tr("failed to start download: %1")
            .arg(serr.message);
        goto fail;
    }

    if( ! srmio_pc_xfer_get_blocks( pc, &block_cnt, &serr ) ){
        err = tr("failed to get number of data blocks: %1")
            .arg(serr.message);
        goto fail1;
    }

    for( int i = 0; i < rideList.size(); ++i ){
        if( rideList.at(i)->wanted )
            prog_sum += rideList.at(i)->work;
    }

    while( srmio_pc_xfer_block_next( pc, &block )){
        bool wanted = false;
        struct _srmio_chunk_t chunk;
        bool is_int;
        bool is_first;
        size_t prog_total;

        if( rideList.empty() ){
            wanted = true;

        } else {
            for( int i = 0; i < rideList.size(); ++i ){
                if( rideList.at(i)->startTime.toTime_t() == block.start / 10 ){
                    wanted = rideList.at(i)->wanted;
                    break;
                }
            }
        }

        if( ! wanted ){
            emit updateStatus(tr("skipping unselected ride block %1")
                .arg(block_num +1));
            ++block_num;
            continue;
        }

        data->slope = block.slope;
        data->zeropos = block.zeropos;
        data->circum = block.circum;
        if( block.athlete ){
            if( data->athlete )
                free( data->athlete );
            data->athlete = strdup( block.athlete );
        }

        if( ! rideList.empty() ){
            prog_total = prog_sum;

        } else if( block_cnt == 1 ){
            prog_total = block.total;

        } else {
            prog_total = block_cnt * 1000;
        }

        while( srmio_pc_xfer_chunk_next( pc, &chunk, &is_int, &is_first  ) ){
            if( m_Cancelled ){
                err = tr("download cancelled");
                goto fail1;
            }

            if( chunks_done % 16 == 0 ){
                size_t block_done;

                srmio_pc_xfer_block_progress( pc, &block_done );
                if( ! rideList.empty() ){
                    block_done += prog_prev;

                } else if( block_cnt == 1 ){
                    // unchanged

                } else {
                    block_done = (double)block_num * 1000
                        + 1000 * block.total / block_done;
                }

                emit updateProgress( tr("progress: %1/%2")
                    .arg(block_done)
                    .arg(prog_total));
            }

            if( ! srmio_data_add_chunk( data, &chunk, &serr ) ){
                err = tr("adding chunk failed: %1")
                    .arg(serr.message);
                goto fail1;
            }

            ++chunks_done;

            /* finish previous marker */
            if( mfirst >= 0 && ( ! is_int || is_first ) )
                if( ! srmio_data_add_marker( data, mfirst, data->cused -2, &serr ) ){
                    err = tr("adding marker failed: %1")
                        .arg(serr.message);
                    goto fail1;
                }

            /* start marker */
            if( is_first ){
                mfirst = (int)data->cused -1;

            } else if( ! is_int ){
                mfirst = -1;

            }
        }

        /* finalize marker at block end */
        if( mfirst >= 0 ){
            if( ! srmio_data_add_marker( data, mfirst, data->cused -1, &serr ) ){;
                err = tr("adding marker failed: %1")
                  .arg(serr.message);
                goto fail1;
            }
            mfirst = -1;
        }

        if( ! rideList.empty() )
            prog_prev += block.total;
        else
            prog_prev += 1000;

        if( block.athlete )
            free( block.athlete );
        block.athlete = NULL;

        ++block_num;
    }

    if( srmio_pc_xfer_state_success != srmio_pc_xfer_status( pc, &serr ) ){
        err = tr( "download failed: %1")
            .arg(serr.message);
        goto fail;
    }

    if( ! srmio_pc_xfer_finish( pc, &serr ) ){
        err = tr( "download failed: %1")
            .arg(serr.message);
        goto fail;
    }

    emit updateStatus( tr("got %1 records").arg(data->cused) );

    if( m_Cancelled ){
        err = tr("download cancelled");
        goto fail;
    }

    if( ! data->cused ){
        err = tr("no data available");
        goto fail;
    }

    splitList = srmio_data_split( data, splitGap, 1000, &serr );
    if( ! splitList ){
        err = tr("Couldn't split data: %1")
            .arg(serr.message);
        goto fail;
    }

    for( split = splitList; *split; ++split ){
        FILE *fh( NULL );
        srmio_time_t stime;
        srmio_data_t fixed;
        DeviceDownloadFile file;

        // skip empty hunks ... shouldn't happen, just to be safe
        if( ! (*split)->cused ){
            continue;
        }

        fixed = srmio_data_fixup( *split, &serr );
        if( ! fixed ){
            err = tr("Couldn't fixup data: %1")
                .arg(serr.message);
            goto fail;
        }

        // skip empty hunks ... shouldn't happen, just to be safe
        if( ! fixed->cused ){
            srmio_data_free(fixed);
            continue;
        }

        file.extension = "srm";
        if (!get_tmpname(tmpdir, file.name, err))
            goto fail;

        if( ! srmio_data_time_start( fixed, &stime, &serr ) ){
            srmio_data_free(fixed);
            err = tr("Couldn't get start time of data: %1")
                .arg(serr.message);
            goto fail;
        }
        file.startTime.setTime_t( 0.1 * stime );

        fh = fopen( file.name.toAscii().constData(), "wb" );
        if( ! fh ){
            srmio_data_free(fixed);
            err = tr( "failed to open file %1: %2")
                .arg(file.name)
                .arg(strerror(errno));
            goto fail;
        }

        if( ! srmio_file_srm7_write(fixed, fh, &serr) ){
            srmio_data_free(fixed);
            err = tr("Couldn't write to file %1: %2")
                .arg(file.name)
                .arg(serr.message);
            fclose(fh);
            goto fail;
        }

        files.append(file);

        fclose( fh );
        srmio_data_free(fixed);

    }

    for( split = splitList; *split; ++split )
        srmio_data_free( *split );
    free(splitList);

    srmio_data_free( data );
    return true;

fail1:
    srmio_pc_xfer_finish(pc, NULL);

fail:
    if( data ) srmio_data_free( data );
    if( splitList ){
        for( split = splitList; *split; ++split )
            srmio_data_free( *split );
        free(splitList);
    }
    close();
    return false;
}