Esempio n. 1
0
rpmfi rpmfiNew(const rpmts ts, Header h, rpmTag tagN, rpmfiFlags flags)
{
    rpmfi fi = NULL;
    rpm_loff_t *asize = NULL;
    unsigned char * t;
    int isBuild, isSource;
    struct rpmtd_s fdigests, digalgo;
    struct rpmtd_s td;
    headerGetFlags scareFlags = (flags & RPMFI_KEEPHEADER) ? 
				HEADERGET_MINMEM : HEADERGET_ALLOC;
    headerGetFlags defFlags = HEADERGET_ALLOC;

    fi = xcalloc(1, sizeof(*fi));
    if (fi == NULL)	/* XXX can't happen */
	goto exit;

    fi->magic = RPMFIMAGIC;
    fi->i = -1;

    fi->fiflags = flags;
    fi->scareFlags = scareFlags;

    if (headerGet(h, RPMTAG_LONGARCHIVESIZE, &td, HEADERGET_EXT)) {
	asize = rpmtdGetUint64(&td);
    }
    /* 0 means unknown */
    fi->archiveSize = asize ? *asize : 0;
    rpmtdFreeData(&td);
    
    /* Archive size is not set when this gets called from build */
    isBuild = (asize == NULL);
    isSource = headerIsSource(h);
    if (isBuild) fi->fiflags |= RPMFI_ISBUILD;
    if (isSource) fi->fiflags |= RPMFI_ISSOURCE;

    _hgfi(h, RPMTAG_BASENAMES, &td, defFlags, fi->bnl);
    fi->fc = rpmtdCount(&td);
    if (fi->fc == 0) {
	goto exit;
    }

    _hgfi(h, RPMTAG_DIRNAMES, &td, defFlags, fi->dnl);
    fi->dc = rpmtdCount(&td);
    _hgfi(h, RPMTAG_DIRINDEXES, &td, scareFlags, fi->dil);
    if (!(flags & RPMFI_NOFILEMODES))
	_hgfi(h, RPMTAG_FILEMODES, &td, scareFlags, fi->fmodes);
    if (!(flags & RPMFI_NOFILEFLAGS))
	_hgfi(h, RPMTAG_FILEFLAGS, &td, scareFlags, fi->fflags);
    if (!(flags & RPMFI_NOFILEVERIFYFLAGS))
	_hgfi(h, RPMTAG_FILEVERIFYFLAGS, &td, scareFlags, fi->vflags);
    if (!(flags & RPMFI_NOFILESIZES))
	_hgfi(h, RPMTAG_FILESIZES, &td, scareFlags, fi->fsizes);

    if (!(flags & RPMFI_NOFILECOLORS))
	_hgfi(h, RPMTAG_FILECOLORS, &td, scareFlags, fi->fcolors);

    if (!(flags & RPMFI_NOFILECLASS)) {
	_hgfi(h, RPMTAG_CLASSDICT, &td, scareFlags, fi->cdict);
	fi->ncdict = rpmtdCount(&td);
	_hgfi(h, RPMTAG_FILECLASS, &td, scareFlags, fi->fcdictx);
    }
    if (!(flags & RPMFI_NOFILEDEPS)) {
	_hgfi(h, RPMTAG_DEPENDSDICT, &td, scareFlags, fi->ddict);
	fi->nddict = rpmtdCount(&td);
	_hgfi(h, RPMTAG_FILEDEPENDSX, &td, scareFlags, fi->fddictx);
	_hgfi(h, RPMTAG_FILEDEPENDSN, &td, scareFlags, fi->fddictn);
    }

    if (!(flags & RPMFI_NOFILESTATES))
	_hgfi(h, RPMTAG_FILESTATES, &td, defFlags, fi->fstates);

    if (!(flags & RPMFI_NOFILECAPS) && headerIsEntry(h, RPMTAG_FILECAPS)) {
	fi->fcapcache = strcacheNew();
	fi->fcaps = cacheTag(fi->fcapcache, h, RPMTAG_FILECAPS);
    }

    if (!(flags & RPMFI_NOFILELINKTOS)) {
	fi->flinkcache = strcacheNew();
	fi->flinks = cacheTag(fi->flinkcache, h, RPMTAG_FILELINKTOS);
    }
    /* FILELANGS are only interesting when installing */
    if ((headerGetInstance(h) == 0) && !(flags & RPMFI_NOFILELANGS))
	fi->flangs = cacheTag(langcache, h, RPMTAG_FILELANGS);

    /* See if the package has non-md5 file digests */
    fi->digestalgo = PGPHASHALGO_MD5;
    if (headerGet(h, RPMTAG_FILEDIGESTALGO, &digalgo, HEADERGET_MINMEM)) {
	pgpHashAlgo *algo = rpmtdGetUint32(&digalgo);
	/* Hmm, what to do with unknown digest algorithms? */
	if (algo && rpmDigestLength(*algo) != 0) {
	    fi->digestalgo = *algo;
	}
    }

    fi->digests = NULL;
    /* grab hex digests from header and store in binary format */
    if (!(flags & RPMFI_NOFILEDIGESTS) &&
	headerGet(h, RPMTAG_FILEDIGESTS, &fdigests, HEADERGET_MINMEM)) {
	const char *fdigest;
	size_t diglen = rpmDigestLength(fi->digestalgo);
	fi->digests = t = xmalloc(rpmtdCount(&fdigests) * diglen);

	while ((fdigest = rpmtdNextString(&fdigests))) {
	    if (!(fdigest && *fdigest != '\0')) {
		memset(t, 0, diglen);
		t += diglen;
		continue;
	    }
	    for (int j = 0; j < diglen; j++, t++, fdigest += 2)
		*t = (rnibble(fdigest[0]) << 4) | rnibble(fdigest[1]);
	}
	rpmtdFreeData(&fdigests);
    }

    /* XXX TR_REMOVED doesn;t need fmtimes, frdevs, finodes */
    if (!(flags & RPMFI_NOFILEMTIMES))
	_hgfi(h, RPMTAG_FILEMTIMES, &td, scareFlags, fi->fmtimes);
    if (!(flags & RPMFI_NOFILERDEVS))
	_hgfi(h, RPMTAG_FILERDEVS, &td, scareFlags, fi->frdevs);
    if (!(flags & RPMFI_NOFILEINODES))
	_hgfi(h, RPMTAG_FILEINODES, &td, scareFlags, fi->finodes);

    if (!(flags & RPMFI_NOFILEUSER)) 
	fi->fuser = cacheTag(ugcache, h, RPMTAG_FILEUSERNAME);
    if (!(flags & RPMFI_NOFILEGROUP)) 
	fi->fgroup = cacheTag(ugcache, h, RPMTAG_FILEGROUPNAME);

    /* lazily alloced from rpmfiFN() */
    fi->fn = NULL;

exit:
if (_rpmfi_debug < 0)
fprintf(stderr, "*** fi %p\t[%d]\n", fi, (fi ? fi->fc : 0));

    if (fi != NULL) {
	fi->h = (fi->fiflags & RPMFI_KEEPHEADER) ? headerLink(h) : NULL;
    }

    /* FIX: rpmfi null annotations */
    return rpmfiLink(fi, __FUNCTION__);
}
Esempio n. 2
0
rpmfi rpmfiNew(const rpmts ts, Header h, rpmTagVal tagN, rpmfiFlags flags)
{
    rpmfi fi = xcalloc(1, sizeof(*fi)); 
    unsigned char * t;
    struct rpmtd_s fdigests, digalgo;
    struct rpmtd_s td;
    headerGetFlags scareFlags = (flags & RPMFI_KEEPHEADER) ? 
				HEADERGET_MINMEM : HEADERGET_ALLOC;
    headerGetFlags defFlags = HEADERGET_ALLOC;

    fi->magic = RPMFIMAGIC;
    fi->i = -1;

    fi->fiflags = flags;

    _hgfi(h, RPMTAG_BASENAMES, &td, defFlags, fi->bnl);
    fi->fc = rpmtdCount(&td);
    if (fi->fc == 0) {
	goto exit;
    }

    _hgfi(h, RPMTAG_DIRNAMES, &td, defFlags, fi->dnl);
    fi->dc = rpmtdCount(&td);
    _hgfi(h, RPMTAG_DIRINDEXES, &td, scareFlags, fi->dil);

    /* Is our filename triplet sane? */
    if (fi->dc == 0 || fi->dc > fi->fc || rpmtdCount(&td) != fi->fc)
	goto errxit;

    for (rpm_count_t i = 0; i < fi->fc; i++) {
	if (fi->dil[i] >= fi->fc)
	    goto errxit;
    }

    /* XXX TODO: all these should be sanity checked, ugh... */
    if (!(flags & RPMFI_NOFILEMODES))
	_hgfi(h, RPMTAG_FILEMODES, &td, scareFlags, fi->fmodes);
    if (!(flags & RPMFI_NOFILEFLAGS))
	_hgfi(h, RPMTAG_FILEFLAGS, &td, scareFlags, fi->fflags);
    if (!(flags & RPMFI_NOFILEVERIFYFLAGS))
	_hgfi(h, RPMTAG_FILEVERIFYFLAGS, &td, scareFlags, fi->vflags);
    if (!(flags & RPMFI_NOFILESIZES))
	_hgfi(h, RPMTAG_FILESIZES, &td, scareFlags, fi->fsizes);

    if (!(flags & RPMFI_NOFILECOLORS))
	_hgfi(h, RPMTAG_FILECOLORS, &td, scareFlags, fi->fcolors);

    if (!(flags & RPMFI_NOFILECLASS)) {
	_hgfi(h, RPMTAG_CLASSDICT, &td, scareFlags, fi->cdict);
	fi->ncdict = rpmtdCount(&td);
	_hgfi(h, RPMTAG_FILECLASS, &td, scareFlags, fi->fcdictx);
    }
    if (!(flags & RPMFI_NOFILEDEPS)) {
	_hgfi(h, RPMTAG_DEPENDSDICT, &td, scareFlags, fi->ddict);
	fi->nddict = rpmtdCount(&td);
	_hgfi(h, RPMTAG_FILEDEPENDSX, &td, scareFlags, fi->fddictx);
	_hgfi(h, RPMTAG_FILEDEPENDSN, &td, scareFlags, fi->fddictn);
    }

    if (!(flags & RPMFI_NOFILESTATES))
	_hgfi(h, RPMTAG_FILESTATES, &td, defFlags, fi->fstates);

    if (!(flags & RPMFI_NOFILECAPS) && headerIsEntry(h, RPMTAG_FILECAPS)) {
	fi->fcapcache = strcacheNew();
	fi->fcaps = cacheTag(fi->fcapcache, h, RPMTAG_FILECAPS);
    }

    if (!(flags & RPMFI_NOFILELINKTOS)) {
	fi->flinkcache = strcacheNew();
	fi->flinks = cacheTag(fi->flinkcache, h, RPMTAG_FILELINKTOS);
    }
    /* FILELANGS are only interesting when installing */
    if ((headerGetInstance(h) == 0) && !(flags & RPMFI_NOFILELANGS))
	fi->flangs = cacheTag(langcache, h, RPMTAG_FILELANGS);

    /* See if the package has non-md5 file digests */
    fi->digestalgo = PGPHASHALGO_MD5;
    if (headerGet(h, RPMTAG_FILEDIGESTALGO, &digalgo, HEADERGET_MINMEM)) {
	uint32_t *algo = rpmtdGetUint32(&digalgo);
	/* Hmm, what to do with unknown digest algorithms? */
	if (algo && rpmDigestLength(*algo) != 0) {
	    fi->digestalgo = *algo;
	}
    }

    fi->digests = NULL;
    /* grab hex digests from header and store in binary format */
    if (!(flags & RPMFI_NOFILEDIGESTS) &&
	headerGet(h, RPMTAG_FILEDIGESTS, &fdigests, HEADERGET_MINMEM)) {
	const char *fdigest;
	size_t diglen = rpmDigestLength(fi->digestalgo);
	fi->digests = t = xmalloc(rpmtdCount(&fdigests) * diglen);

	while ((fdigest = rpmtdNextString(&fdigests))) {
	    if (!(fdigest && *fdigest != '\0')) {
		memset(t, 0, diglen);
		t += diglen;
		continue;
	    }
	    for (int j = 0; j < diglen; j++, t++, fdigest += 2)
		*t = (rnibble(fdigest[0]) << 4) | rnibble(fdigest[1]);
	}
	rpmtdFreeData(&fdigests);
    }

    /* XXX TR_REMOVED doesn;t need fmtimes, frdevs, finodes */
    if (!(flags & RPMFI_NOFILEMTIMES))
	_hgfi(h, RPMTAG_FILEMTIMES, &td, scareFlags, fi->fmtimes);
    if (!(flags & RPMFI_NOFILERDEVS))
	_hgfi(h, RPMTAG_FILERDEVS, &td, scareFlags, fi->frdevs);
    if (!(flags & RPMFI_NOFILEINODES))
	_hgfi(h, RPMTAG_FILEINODES, &td, scareFlags, fi->finodes);

    if (!(flags & RPMFI_NOFILEUSER)) 
	fi->fuser = cacheTag(ugcache, h, RPMTAG_FILEUSERNAME);
    if (!(flags & RPMFI_NOFILEGROUP)) 
	fi->fgroup = cacheTag(ugcache, h, RPMTAG_FILEGROUPNAME);

    /* lazily alloced from rpmfiFN() */
    fi->fn = NULL;

exit:

    if (fi != NULL) {
	fi->h = (fi->fiflags & RPMFI_KEEPHEADER) ? headerLink(h) : NULL;
    }

    /* FIX: rpmfi null annotations */
    return rpmfiLink(fi);

errxit:
    rpmfiFree(fi);
    return NULL;
}
Esempio n. 3
0
unsigned V8ScriptRunner::tagForCodeCache(CachedMetadataHandler* cacheHandler)
{
    return cacheTag(CacheTagCode, cacheHandler);
}
Esempio n. 4
0
void ReorderForsyth( std::vector< size_t >& indices, const size_t nVertices )
{
    size_t nTriangles = indices.size() / 3;

    // The tables need not be inited every time this function
    // is use. Either call initForsyth from the calling process,
    // or just replace the score tables with precalculated values.
    initForsyth();

    std::vector<AdjacencyType> numActiveTris( nVertices, 0 );

    // First scan over vertex data, count the total number of
    // occurences of each vertex.
    for ( size_t i=0; i<indices.size(); ++i )
    {
        AdjacencyType& adj = numActiveTris[indices[i]];
        if ( adj == MAX_ADJACENCY )
        {
            // Unsupported mesh.
            // vertex shared by too many triangles.
            return;
        }
        ++adj;
    }

    std::vector< ArrayIndexType >       offsets(nVertices);
    std::vector< ScoreType >            lastScore(nVertices);
    std::vector< CachePosType >         cacheTag(nVertices);
    std::vector< uint8_t >              triangleAdded( ( nTriangles + 7 ) / 8, 0 );
    std::vector< ScoreType >            triangleScore( nTriangles, 0 );
    std::vector< TriangleIndexType >    triangleIndices( indices.size(), 0 );

    // Count the triangle array offset for each vertex,
    // initialize the rest of the data.
    int sum = 0;
    for ( size_t i=0; i<nVertices; ++i )
    {
        offsets[i] = sum;
        sum += numActiveTris[i];
        numActiveTris[i] = 0;
        cacheTag[i] = -1;
    }

    // Fill the vertex data structures with indices to the triangles
    // using each vertex.
    for ( size_t i=0; i<nTriangles; ++i )
    {
        for ( size_t j=0; j<3; ++j )
        {
            size_t v = indices[ 3 * i + j ];
            triangleIndices[ offsets[v] + numActiveTris[v] ] = i;
            ++numActiveTris[v];
        }
    }

    // Initialize the score for all vertices.
    for ( size_t i=0; i<nVertices; ++i )
    {
        lastScore[i] = findVertexScore( numActiveTris[i], cacheTag[i] );
        for ( size_t j=0; j<numActiveTris[i]; ++j )
        {
            triangleScore[ triangleIndices[ offsets[i] + j ] ] += lastScore[i];
        }
    }

    // Find the best triangle.
    int bestTriangle = -1;
    int bestScore = -1;

    for ( size_t i=0; i<nTriangles; ++i )
    {
        if ( triangleScore[i] > bestScore )
        {
            bestScore = triangleScore[i];
            bestTriangle = i;
        }
    }

    std::vector< TriangleIndexType > outTriangles( nTriangles );
    size_t outPos = 0;

    // Initialize the cache.
    int cache[ VERTEX_CACHE_SIZE + 3 ];
    for ( size_t i=0; i<(VERTEX_CACHE_SIZE+3); ++i )
    {
        cache[i] = -1;
    }

    size_t scanPos = 0;

    // Output the currently best triangle, as long as there
    // are triangles left to output.
    while ( bestTriangle >= 0 )
    {
        // Mark the triangle as added.
        SETADDED( bestTriangle );
        // Output this triangle.
        outTriangles[outPos++] = bestTriangle;
        for ( int i=0; i<3; ++i )
        {
            // Update thi svertex
            size_t v = indices[ 3 * bestTriangle + i ];

            // Check the current cache position, if it
            // is in the cache
            int endpos = cacheTag[v];
            if ( endpos < 0 )
            {
                endpos = VERTEX_CACHE_SIZE + i;
            }

            // Move all cache entries from the previous position
            // in the cache to the new target position (i) one
            // step backwards.
            for ( int j=endpos; j>i; --j )
            {
                cache[j] = cache[j-1];
                // If this cache slot contains a real
                // vertex, updata its cache tag.
                if ( cache[j] >= 0 )
                {
                    ++cacheTag[ cache[j] ];
                }
            }

            // Insert the current vertex into its new target
            // slot.
            cache[i] = v;
            cacheTag[v] = i;

            // Find the current triangle in the list of active
            // triangles and remove it (moving the last
            // triangle in the list to the slot of this triangle).
            for ( size_t j=0; j<numActiveTris[v]; ++j )
            {
                if ( triangleIndices[ offsets[v] + j ] == bestTriangle )
                {
                    triangleIndices[ offsets[v] + j ] = triangleIndices[ offsets[v] + numActiveTris[v] - 1 ];
                    break;
                }
            }

            // Shorten the list.
            --numActiveTris[v];
        }

        // Update the scores of all triangles in the cache
        for ( size_t i=0; i<(VERTEX_CACHE_SIZE+3); ++i )
        {
            int v = cache[i];

            if ( v < 0 )
                break;

            // This vertex has been pushed outside of the
            // actual cache
            if ( i >= VERTEX_CACHE_SIZE )
            {
                cacheTag[v] = -1;
                cache[i] = -1;
            }

            ScoreType newScore = findVertexScore( numActiveTris[v], cacheTag[v] );

            ScoreType diff = newScore - lastScore[v];
            for ( size_t j=0; j<numActiveTris[v]; ++j )
            {
                triangleScore[ triangleIndices[ offsets[v] + j ] ] += diff;
                lastScore[v] = newScore;
            }
        }

        // Find the besttriangle referenced by vertices in the
        // cache
        bestTriangle = -1;
        bestScore = -1;
        for ( size_t i=0; i<VERTEX_CACHE_SIZE; ++i )
        {
            if ( cache[i] < 0 )
                break;

            int v = cache[i];
            for ( size_t j=0; j<numActiveTris[v]; ++j )
            {
                int t = triangleIndices[ offsets[v] + j ];
                if ( triangleScore[t] > bestScore )
                {
                    bestTriangle = t;
                    bestScore = triangleScore[t];
                }
            }
        }

        // If no active triangle was found at all, continue
        // scanning the whole list of triangles
        if ( bestTriangle < 0 )
        {
            for (; scanPos < nTriangles; ++scanPos )
            {
                if ( !ISADDED(scanPos) )
                {
                    bestTriangle = scanPos;
                    break;
                }
            }
        }
    }

    std::vector< size_t > outIndices( indices.size() );

    outPos = 0;
    for ( size_t i=0; i<nTriangles; ++i )
    {
        size_t t = outTriangles[i];
        for ( size_t j=0; j<3; ++j )
        {
            outIndices[outPos++] = indices[ 3 * t + j ];
        }
    }

    indices = outIndices;
}
Esempio n. 5
0
unsigned V8ScriptRunner::tagForParserCache(CachedMetadataHandler* cacheHandler)
{
    return cacheTag(CacheTagParser, cacheHandler);
}