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__); }
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; }
unsigned V8ScriptRunner::tagForCodeCache(CachedMetadataHandler* cacheHandler) { return cacheTag(CacheTagCode, cacheHandler); }
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; }
unsigned V8ScriptRunner::tagForParserCache(CachedMetadataHandler* cacheHandler) { return cacheTag(CacheTagParser, cacheHandler); }