bool SSurface::ClosestPointNewton(Vector p, double *u, double *v, bool converge) { // Initial guess is in u, v; refine by Newton iteration. Vector p0 = Vector::From(0, 0, 0); for(int i = 0; i < (converge ? 25 : 5); i++) { p0 = PointAt(*u, *v); if(converge) { if(p0.Equals(p, RATPOLY_EPS)) { return true; } } Vector tu, tv; TangentsAt(*u, *v, &tu, &tv); // Project the point into a plane through p0, with basis tu, tv; a // second-order thing would converge faster but needs second // derivatives. Vector dp = p.Minus(p0); double du = dp.Dot(tu), dv = dp.Dot(tv); *u += du / (tu.MagSquared()); *v += dv / (tv.MagSquared()); } if(converge) { dbp("didn't converge"); dbp("have %.3f %.3f %.3f", CO(p0)); dbp("want %.3f %.3f %.3f", CO(p)); dbp("distance = %g", (p.Minus(p0)).Magnitude()); } return false; }
//----------------------------------------------------------------------------- // Load a TrueType font into memory. We care about the curves that define // the letter shapes, and about the mappings that determine which glyph goes // with which character. //----------------------------------------------------------------------------- bool TtfFont::LoadFromFile(FT_Library fontLibrary, bool nameOnly) { FT_Open_Args args = {}; args.flags = FT_OPEN_PATHNAME; args.pathname = &fontFile[0]; // FT_String is char* for historical reasons // We don't use ssfopen() here to let freetype do its own memory management. // This is OK because on Linux/OS X we just delegate to fopen and on Windows // we only look into C:\Windows\Fonts, which has a known short path. if(int fterr = FT_Open_Face(fontLibrary, &args, 0, &fontFace)) { dbp("freetype: loading font from file '%s' failed: %s", fontFile.c_str(), ft_error_string(fterr)); return false; } if(int fterr = FT_Select_Charmap(fontFace, FT_ENCODING_UNICODE)) { dbp("freetype: loading unicode CMap for file '%s' failed: %s", fontFile.c_str(), ft_error_string(fterr)); FT_Done_Face(fontFace); return false; } name = std::string(fontFace->family_name) + " (" + std::string(fontFace->style_name) + ")"; if(nameOnly) { FT_Done_Face(fontFace); fontFace = NULL; } return true; }
const IR::Node* DoRemoveActionParameters::postorder(IR::P4Action* action) { LOG1("Visiting " << dbp(action)); BUG_CHECK(getParent<IR::P4Control>() || getParent<IR::P4Program>(), "%1%: unexpected parent %2%", getOriginal(), getContext()->node); auto result = new IR::IndexedVector<IR::Declaration>(); auto leftParams = new IR::IndexedVector<IR::Parameter>(); auto initializers = new IR::IndexedVector<IR::StatOrDecl>(); auto postamble = new IR::IndexedVector<IR::StatOrDecl>(); auto invocation = invocations->get(getOriginal<IR::P4Action>()); if (invocation == nullptr) return action; auto args = invocation->arguments; ParameterSubstitution substitution; substitution.populate(action->parameters, args); bool removeAll = invocations->removeAllParameters(getOriginal<IR::P4Action>()); for (auto p : action->parameters->parameters) { if (p->direction == IR::Direction::None && !removeAll) { leftParams->push_back(p); } else { auto decl = new IR::Declaration_Variable(p->srcInfo, p->name, p->annotations, p->type, nullptr); LOG3("Added declaration " << decl << " annotations " << p->annotations); result->push_back(decl); auto arg = substitution.lookup(p); if (arg == nullptr) { ::error("action %1%: parameter %2% must be bound", invocation, p); continue; } if (p->direction == IR::Direction::In || p->direction == IR::Direction::InOut || p->direction == IR::Direction::None) { auto left = new IR::PathExpression(p->name); auto assign = new IR::AssignmentStatement(arg->srcInfo, left, arg->expression); initializers->push_back(assign); } if (p->direction == IR::Direction::Out || p->direction == IR::Direction::InOut) { auto right = new IR::PathExpression(p->name); auto assign = new IR::AssignmentStatement(arg->srcInfo, arg->expression, right); postamble->push_back(assign); } } } if (result->empty()) return action; initializers->append(action->body->components); initializers->append(*postamble); action->parameters = new IR::ParameterList(action->parameters->srcInfo, *leftParams); action->body = new IR::BlockStatement(action->body->srcInfo, *initializers); LOG1("To replace " << dbp(action)); result->push_back(action); return result; }
void ReferenceMap::setDeclaration(const IR::This* pointer, const IR::IDeclaration* decl) { CHECK_NULL(pointer); CHECK_NULL(decl); LOG1("Resolved " << pointer << " to " << decl); auto previous = get(thisToDeclaration, pointer); if (previous != nullptr && previous != decl) BUG("%1% already resolved to %2% instead of %3%", dbp(pointer), dbp(previous), dbp(decl)); thisToDeclaration.emplace(pointer, decl); }
const IR::Node* ReplaceStructs::preorder(IR::P4Control* control) { for (auto p : control->getApplyParameters()->parameters) { auto pt = replacementMap->typeMap->getType(p, true); auto repl = replacementMap->getReplacement(pt); if (repl != nullptr) { toReplace.emplace(p, repl); LOG3("Replacing parameter " << dbp(p) << " of " << dbp(control)); } } return control; }
void ReferenceMap::setDeclaration(const IR::Path* path, const IR::IDeclaration* decl) { CHECK_NULL(path); CHECK_NULL(decl); LOG1("Resolved " << path << " to " << decl); auto previous = get(pathToDeclaration, path); if (previous != nullptr && previous != decl) BUG("%1% already resolved to %2% instead of %3%", dbp(path), dbp(previous), dbp(decl->getNode())); pathToDeclaration.emplace(path, decl); usedName(path->name.name); used.insert(decl); }
//----------------------------------------------------------------------------- // Find all points where the indicated finite (if segment) or infinite (if not // segment) line intersects our surface. Report them in uv space in the list. // We first do a bounding box check; if the line doesn't intersect, then we're // done. If it does, then we check how small our surface is. If it's big, // then we subdivide into quarters and recurse. If it's small, then we refine // by Newton's method and record the point. //----------------------------------------------------------------------------- void SSurface::AllPointsIntersectingUntrimmed(Vector a, Vector b, int *cnt, int *level, List<Inter> *l, bool segment, SSurface *sorig) { // Test if the line intersects our axis-aligned bounding box; if no, then // no possibility of an intersection if(LineEntirelyOutsideBbox(a, b, segment)) return; if(*cnt > 2000) { dbp("!!! too many subdivisions (level=%d)!", *level); dbp("degm = %d degn = %d", degm, degn); return; } (*cnt)++; // If we might intersect, and the surface is small, then switch to Newton // iterations. if(DepartureFromCoplanar() < 0.2*SS.ChordTolMm()) { Vector p = (ctrl[0 ][0 ]).Plus( ctrl[0 ][degn]).Plus( ctrl[degm][0 ]).Plus( ctrl[degm][degn]).ScaledBy(0.25); Inter inter; sorig->ClosestPointTo(p, &(inter.p.x), &(inter.p.y), false); if(sorig->PointIntersectingLine(a, b, &(inter.p.x), &(inter.p.y))) { Vector p = sorig->PointAt(inter.p.x, inter.p.y); // Debug check, verify that the point lies in both surfaces // (which it ought to, since the surfaces should be coincident) double u, v; ClosestPointTo(p, &u, &v); l->Add(&inter); } else { // Might not converge if line is almost tangent to surface... } return; } // But the surface is big, so split it, alternating by u and v SSurface surf0, surf1; SplitInHalf((*level & 1) == 0, &surf0, &surf1); int nextLevel = (*level) + 1; (*level) = nextLevel; surf0.AllPointsIntersectingUntrimmed(a, b, cnt, level, l, segment, sorig); (*level) = nextLevel; surf1.AllPointsIntersectingUntrimmed(a, b, cnt, level, l, segment, sorig); }
const IR::Node* SubstituteParameters::postorder(IR::Type_Name* type) { auto decl = refMap->getDeclaration(type->path, true); auto var = decl->to<IR::Type_Var>(); if (var != nullptr && bindings->containsKey(var)) { auto repl = bindings->lookup(var); LOG1("Replaced " << dbp(type) << " with " << dbp(repl)); return repl; } IR::ID newid = type->path->name; auto path = new IR::Path(newid, type->path->absolute); refMap->setDeclaration(path, decl); auto result = new IR::Type_Name(type->srcInfo, path); LOG1("Cloned " << dbp(type) << " into " << dbp(result)); return result; }
static void TagByClassifiedEdge(int bspclass, int *indir, int *outdir) { switch(bspclass) { case SBspUv::INSIDE: *indir = SShell::INSIDE; *outdir = SShell::INSIDE; break; case SBspUv::OUTSIDE: *indir = SShell::OUTSIDE; *outdir = SShell::OUTSIDE; break; case SBspUv::EDGE_PARALLEL: *indir = SShell::INSIDE; *outdir = SShell::OUTSIDE; break; case SBspUv::EDGE_ANTIPARALLEL: *indir = SShell::OUTSIDE; *outdir = SShell::INSIDE; break; default: dbp("TagByClassifiedEdge: fail!"); *indir = SShell::OUTSIDE; *outdir = SShell::OUTSIDE; break; } }
static FILE *open_db(const char *name, FILE **update_db) { char path[PATH_MAX]; FILE *db; /* FIXME: locking */ dbp(name, path, sizeof(path)); db = fopen(path, "r"); if (!db) { loge("Can't open database: %m\n"); return NULL; } if (update_db) { FILE *udb; dbup(name, path, sizeof(path)); udb = fopen(path, "w"); if (!udb) { loge("Can't open update base: %m\n"); fclose(db); return NULL; } *update_db = udb; } return db; }
// Abbreviated debug print cstring IR::dbp(const IR::INode* node) { std::stringstream str; if (node == nullptr) { str << "<nullptr>"; } else { if (node->is<IR::IDeclaration>()) { node->getNode()->Node::dbprint(str); str << " " << node->to<IR::IDeclaration>()->getName(); } else if (node->is<IR::Member>()) { node->getNode()->Node::dbprint(str); str << " ." << node->to<IR::Member>()->member; } else if (node->is<IR::Type_Type>()) { node->getNode()->Node::dbprint(str); str << "(" << dbp(node->to<IR::Type_Type>()->type) << ")"; } else if (node->is<IR::PathExpression>() || node->is<IR::Path>() || node->is<IR::TypeNameExpression>() || node->is<IR::Constant>() || node->is<IR::Type_Name>() || node->is<IR::Type_Base>()) { node->getNode()->Node::dbprint(str); str << " " << node->toString(); } else { node->getNode()->Node::dbprint(str); } } return str.str(); }
static int close_db(const char *name, FILE *db, FILE *udb, bool updated) { fclose(db); if (udb) { char upath[PATH_MAX]; fclose(udb); dbup(name, upath, sizeof(upath)); if (updated) { char path[PATH_MAX]; dbp(name, path, sizeof(path)); if (rename(upath, path)) { loge("Can't update database: %m\n"); return -1; } } else { if (unlink(upath)) logw("Can't remove update database: %m\n"); } } return 0; }
void SBezier::ClosestPointTo(Vector p, double *t, bool converge) { int i; double minDist = VERY_POSITIVE; *t = 0; double res = (deg <= 2) ? 7.0 : 20.0; for(i = 0; i < (int)res; i++) { double tryt = (i/res); Vector tryp = PointAt(tryt); double d = (tryp.Minus(p)).Magnitude(); if(d < minDist) { *t = tryt; minDist = d; } } Vector p0; for(i = 0; i < (converge ? 15 : 5); i++) { p0 = PointAt(*t); if(p0.Equals(p, RATPOLY_EPS)) { return; } Vector dp = TangentAt(*t); Vector pc = p.ClosestPointOnLine(p0, dp); *t += (pc.Minus(p0)).DivPivoting(dp); } if(converge) { dbp("didn't converge (closest point on bezier curve)"); } }
/// generate extern_instances from instance declarations. bool Extern::preorder(const IR::Declaration_Instance* decl) { LOG1("ExternConv Visiting ..." << dbp(decl)); // Declaration_Instance -> P4Control -> ControlBlock auto grandparent = getContext()->parent->node; if (grandparent->is<IR::ControlBlock>()) { auto block = grandparent->to<IR::ControlBlock>()->getValue(decl); CHECK_NULL(block); if (block->is<IR::ExternBlock>()) { auto externBlock = block->to<IR::ExternBlock>(); auto name = decl->name; auto type = ""; if (decl->type->is<IR::Type_Specialized>()) type = decl->type->to<IR::Type_Specialized>()->baseType->toString(); else if (decl->type->is<IR::Type_Name>()) type = decl->type->to<IR::Type_Name>()->path->name.toString(); else P4C_UNIMPLEMENTED("extern support for %1%", decl); auto attributes = addExternAttributes(decl, externBlock); json->add_extern(name, type, attributes); } else { BUG("%1% Unsupported block type for extern generation.", block->toString()); } } return false; }
void smallDatabaseTest() { DbProxy dbp(db); for (uint32_t i = 0; i < 5; i++) dbp.require_insert(i, 0); dbp.require_check_integrity(); }
const IR::Node* SubstituteParameters::postorder(IR::PathExpression* expr) { auto decl = refMap->getDeclaration(expr->path, true); auto param = decl->to<IR::Parameter>(); if (param != nullptr && subst->contains(param)) { auto value = subst->lookup(param)->expression; LOG1("Replaced " << dbp(expr) << " with " << dbp(value)); return value; } // Path expressions always need to be cloned. IR::ID newid = expr->path->name; auto path = new IR::Path(newid, expr->path->absolute); auto result = new IR::PathExpression(path); LOG1("Cloned " << dbp(expr) << " into " << dbp(result)); refMap->setDeclaration(path, decl); return result; }
Point2d Point2d::WithMagnitude(double v) { double m = Magnitude(); if(m < 1e-20) { dbp("!!! WithMagnitude() of zero vector"); Point2d r = { v, 0 }; return r; } else { return ScaledBy(v/m); } }
const IR::Node* DoReplaceTuples::insertReplacements(const IR::Node* before) { // Check that we are in the top-level P4Program list of declarations. if (!getParent<IR::P4Program>()) return before; auto result = repl->getNewReplacements(); if (result == nullptr) return before; LOG3("Inserting replacements before " << dbp(before)); result->push_back(before); return result; }
Vector Vector::WithMagnitude(double v) { double m = Magnitude(); if(EXACT(m == 0)) { // We can do a zero vector with zero magnitude, but not any other cases. if(fabs(v) > 1e-100) { dbp("Vector::WithMagnitude(%g) of zero vector!", v); } return From(0, 0, 0); } else { return ScaledBy(v/m); } }
//----------------------------------------------------------------------------- // Generate the piecewise linear approximation of the trim stb, which applies // to the curve sc. //----------------------------------------------------------------------------- void SSurface::MakeTrimEdgesInto(SEdgeList *sel, int flags, SCurve *sc, STrimBy *stb) { Vector prev = Vector::From(0, 0, 0); bool inCurve = false, empty = true; double u = 0, v = 0; int i, first, last, increment; if(stb->backwards) { first = sc->pts.n - 1; last = 0; increment = -1; } else { first = 0; last = sc->pts.n - 1; increment = 1; } for(i = first; i != (last + increment); i += increment) { Vector tpt, *pt = &(sc->pts.elem[i].p); if(flags & AS_UV) { ClosestPointTo(*pt, &u, &v); tpt = Vector::From(u, v, 0); } else { tpt = *pt; } if(inCurve) { sel->AddEdge(prev, tpt, sc->h.v, stb->backwards); empty = false; } prev = tpt; // either uv or xyz, depending on flags if(pt->Equals(stb->start)) inCurve = true; if(pt->Equals(stb->finish)) inCurve = false; } if(inCurve) dbp("trim was unterminated"); if(empty) dbp("trim was empty"); }
const IR::Type* ReplacementMap::convertType(const IR::Type* type) { auto it = replacement.find(type); if (it != replacement.end()) return it->second; if (type->is<IR::Type_Struct>()) { auto st = type->to<IR::Type_Struct>(); bool changes = false; IR::IndexedVector<IR::StructField> fields; for (auto f : st->fields) { auto ftype = typeMap->getType(f); auto cftype = convertType(ftype); if (cftype != ftype) changes = true; auto field = new IR::StructField(f->name, f->annotations, cftype->getP4Type()); fields.push_back(field); } if (changes) { auto result = new IR::Type_Struct(st->srcInfo, st->name, st->annotations, fields); LOG3("Converted " << dbp(type) << " to " << dbp(result)); replacement.emplace(type, result); return result; } else { return type; } } else if (type->is<IR::Type_Tuple>()) { cstring name = ng->newName("tuple"); IR::IndexedVector<IR::StructField> fields; for (auto t : type->to<IR::Type_Tuple>()->components) { auto ftype = convertType(t); auto fname = ng->newName("field"); auto field = new IR::StructField(IR::ID(fname), ftype->getP4Type()); fields.push_back(field); } auto result = new IR::Type_Struct(name, fields); LOG3("Converted " << dbp(type) << " to " << dbp(result)); replacement.emplace(type, result); return result; } return type; }
void SSurface::PointOnSurfaces(SSurface *s1, SSurface *s2, double *up, double *vp) { double u[3] = { *up, 0, 0 }, v[3] = { *vp, 0, 0 }; SSurface *srf[3] = { this, s1, s2 }; // Get initial guesses for (u, v) in the other surfaces Vector p = PointAt(*u, *v); (srf[1])->ClosestPointTo(p, &(u[1]), &(v[1]), false); (srf[2])->ClosestPointTo(p, &(u[2]), &(v[2]), false); int i, j; for(i = 0; i < 20; i++) { // Approximate each surface by a plane Vector p[3], tu[3], tv[3], n[3]; double d[3]; for(j = 0; j < 3; j++) { p[j] = (srf[j])->PointAt(u[j], v[j]); (srf[j])->TangentsAt(u[j], v[j], &(tu[j]), &(tv[j])); n[j] = ((tu[j]).Cross(tv[j])).WithMagnitude(1); d[j] = (n[j]).Dot(p[j]); } // If a = b and b = c, then does a = c? No, it doesn't. if((p[0]).Equals(p[1], RATPOLY_EPS) && (p[1]).Equals(p[2], RATPOLY_EPS) && (p[2]).Equals(p[0], RATPOLY_EPS)) { *up = u[0]; *vp = v[0]; return; } bool parallel; Vector pi = Vector::AtIntersectionOfPlanes(n[0], d[0], n[1], d[1], n[2], d[2], ¶llel); if(parallel) break; for(j = 0; j < 3; j++) { Vector dp = pi.Minus(p[j]); double du = dp.Dot(tu[j]), dv = dp.Dot(tv[j]); u[j] += du / (tu[j]).MagSquared(); v[j] += dv / (tv[j]).MagSquared(); } } dbp("didn't converge (three surfaces intersecting)"); }
Vector SSurface::ClosestPointOnThisAndSurface(SSurface *srf2, Vector p) { // This is untested. int i, j; Point2d puv[2]; SSurface *srf[2] = { this, srf2 }; for(j = 0; j < 2; j++) { (srf[j])->ClosestPointTo(p, &(puv[j]), false); } for(i = 0; i < 10; i++) { Vector tu[2], tv[2], cp[2], n[2]; double d[2]; for(j = 0; j < 2; j++) { (srf[j])->TangentsAt(puv[j].x, puv[j].y, &(tu[j]), &(tv[j])); cp[j] = (srf[j])->PointAt(puv[j]); n[j] = ((tu[j]).Cross(tv[j])).WithMagnitude(1); d[j] = (n[j]).Dot(cp[j]); } if((cp[0]).Equals(cp[1], RATPOLY_EPS)) break; Vector p0 = Vector::AtIntersectionOfPlanes(n[0], d[0], n[1], d[1]), dp = (n[0]).Cross(n[1]); Vector pc = p.ClosestPointOnLine(p0, dp); // Adjust our guess and iterate for(j = 0; j < 2; j++) { Vector dc = pc.Minus(cp[j]); double du = dc.Dot(tu[j]), dv = dc.Dot(tv[j]); puv[j].x += du / ((tu[j]).MagSquared()); puv[j].y += dv / ((tv[j]).MagSquared()); } } if(i >= 10) { dbp("this and srf, didn't converge, d=%g", (puv[0].Minus(puv[1])).Magnitude()); } // If this converged, then the two points are actually equal. return ((srf[0])->PointAt(puv[0])).Plus( ((srf[1])->PointAt(puv[1]))).ScaledBy(0.5); }
EXPORT_C void DeleteAllOtherAPs(const TDesC& aName) { auto_ptr<CCommsDatabase> dbp(CCommsDatabase::NewL(EDatabaseTypeIAP)); CCommsDatabase& db=*dbp; User::LeaveIfError(db.BeginTransaction()); CCommsDbTableView* aTable=db.OpenTableLC(TPtrC(IAP)); TInt err=aTable->GotoFirstRecord(); TBuf<50> name; while(err==KErrNone) { aTable->ReadTextL(TPtrC(COMMDB_NAME), name); if (name.CompareF(aName)!=0) { aTable->DeleteRecord(); } err=aTable->GotoNextRecord(); } User::LeaveIfError(db.CommitTransaction()); }
static void DEBUGEDGELIST(SEdgeList *sel, SSurface *surf) { dbp("print %d edges", sel->l.n); SEdge *se; for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { Vector mid = (se->a).Plus(se->b).ScaledBy(0.5); Vector arrow = (se->b).Minus(se->a); swap(arrow.x, arrow.y); arrow.x *= -1; arrow = arrow.WithMagnitude(0.01); arrow = arrow.Plus(mid); SS.nakedEdges.AddEdge(surf->PointAt(se->a.x, se->a.y), surf->PointAt(se->b.x, se->b.y)); SS.nakedEdges.AddEdge(surf->PointAt(mid.x, mid.y), surf->PointAt(arrow.x, arrow.y)); } }
void SSurface::TriangulateInto(SShell *shell, SMesh *sm) { SEdgeList el = {}; MakeEdgesInto(shell, &el, AS_UV); SPolygon poly = {}; if(el.AssemblePolygon(&poly, NULL, true)) { int i, start = sm->l.n; if(degm == 1 && degn == 1) { // A surface with curvature along one direction only; so // choose the triangulation with chords that lie as much // as possible within the surface. And since the trim curves // have been pwl'd to within the desired chord tol, that will // produce a surface good to within roughly that tol. // // If this is just a plane (degree (1, 1)) then the triangulation // code will notice that, and not bother checking chord tols. poly.UvTriangulateInto(sm, this); } else { // A surface with compound curvature. So we must overlay a // two-dimensional grid, and triangulate around that. poly.UvGridTriangulateInto(sm, this); } STriMeta meta = { face, color }; for(i = start; i < sm->l.n; i++) { STriangle *st = &(sm->l.elem[i]); st->meta = meta; st->an = NormalAt(st->a.x, st->a.y); st->bn = NormalAt(st->b.x, st->b.y); st->cn = NormalAt(st->c.x, st->c.y); st->a = PointAt(st->a.x, st->a.y); st->b = PointAt(st->b.x, st->b.y); st->c = PointAt(st->c.x, st->c.y); // Works out that my chosen contour direction is inconsistent with // the triangle direction, sigh. st->FlipNormal(); } } else { dbp("failed to assemble polygon to trim nurbs surface in uv space"); } el.Clear(); poly.Clear(); }
const IR::Node* TypeVariableSubstitutionVisitor::replacement(IR::ITypeVar* typeVariable) { LOG3("Visiting " << dbp(getOriginal())); const IR::ITypeVar* current = getOriginal<IR::ITypeVar>(); const IR::Type* replacement = nullptr; while (true) { // This will end because there should be no circular chain of variables pointing // to each other. const IR::Type* type = bindings->lookup(current); if (type == nullptr) break; replacement = type; if (!type->is<IR::ITypeVar>()) break; current = type->to<IR::ITypeVar>(); } if (replacement == nullptr) return typeVariable->getNode(); LOG2("Replacing " << getOriginal() << " with " << replacement); return replacement; }
Expr *Expr::From(const char *in, bool popUpError) { UnparsedCnt = 0; UnparsedP = 0; OperandsP = 0; OperatorsP = 0; Expr *r; try { Lex(in); Parse(); r = PopOperand(); } catch (const char *e) { dbp("exception: parse/lex error: %s", e); if(popUpError) { Error("Not a valid number or expression: '%s'", in); } return NULL; } return r; }
void levelledDatabaseTest() { ups_parameter_t env_params[] = { { UPS_PARAM_PAGESIZE, 1024 }, { 0, 0 } }; ups_parameter_t db_params[] = { { UPS_PARAM_KEYSIZE, 80 }, { 0, 0 } }; close(); require_create(0, env_params, 0, db_params); DbProxy dbp(db); std::vector<uint8_t> kvec(80); std::vector<uint8_t> rvec; for (int i = 0; i < 100; i++) { *(int *)&kvec[0] = i; dbp.require_insert(kvec, rvec) .require_check_integrity(); } }
//----------------------------------------------------------------------------- // Check the consistency of the heap on which all the PLC program stuff is // stored. //----------------------------------------------------------------------------- void CheckHeap(char *file, int line) { static unsigned int SkippedCalls; static SDWORD LastCallTime; SDWORD now = GetTickCount(); // It slows us down too much to do the check every time we are called; // but let's still do the check periodically; let's do it every 70 // calls or every 20 ms, whichever is sooner. if(SkippedCalls < 70 && (now - LastCallTime) < 20) { SkippedCalls++; return; } SkippedCalls = 0; LastCallTime = now; if(!HeapValidate(MainHeap, 0, NULL)) { dbp("file %s line %d", file, line); Error("Noticed memory corruption at file '%s' line %d.", file, line); oops(); } }