Matrix::Matrix(const stromx::runtime::Matrix& matrix)
  : m_data(0)
{
    allocate(matrix.rows(), matrix.cols(), matrix.valueType());
    
    for (unsigned int i = 0; i < rows(); ++i)
    {
        const uint8_t* srcRowPtr = matrix.data() + i * matrix.stride();
        uint8_t* dstRowPtr = data() + i * stride();
        unsigned int rowBytes = cols() * valueSize();
        memcpy(dstRowPtr, srcRowPtr, rowBytes);
    }
}
void RegionBuilder::prepare(const Streamline& streamline)
{
    m_count = streamline.m_items.size();
    if (m_count == 0) THROW("Empty streamline is invalid");

    m_size = sizeof(RegionHeader);
    m_metricsBufferSize = m_count * sizeof(MetricID);
    if (m_metricsBufferSize % 8 != 0) {
        m_metricsBufferSize = (m_metricsBufferSize / 8 + 1) * 8;
    }
    m_size += m_metricsBufferSize;
    m_size += m_count * sizeof(RegionRecord);
    m_dataOffset = m_size;

    m_metrics.reserve(m_count);

    map< MetricID, MetricTimeline >::const_iterator iter = streamline.m_items.begin();
    for ( ; iter != streamline.m_items.end(); ++iter) {
        if (iter->second.m_timeline->size() != iter->second.m_values->size()) {
            THROW("Different number of items in timeline and values array");
        }

        m_metrics.push_back(iter->first);

        size_t valuesSize = valueSize(iter->second.m_type) * iter->second.m_values->size();
        if (valuesSize % 8 != 0) {
            valuesSize = (valuesSize / 8 + 1) * 8;
        }
        m_values[iter->second.m_values] = valuesSize;
        m_size += valuesSize;

        if (m_timelines.find(iter->second.m_timeline) == m_timelines.end()) {
            size_t timelineSize = iter->second.m_timeline->size() * sizeof(Timestamp);
            m_timelines[iter->second.m_timeline] = timelineSize;
            m_size += timelineSize;
        }
    }

    m_header.m_count = m_count;
    m_header.m_size = m_size;
}