/* Web Polygraph http://www.web-polygraph.org/
* (C) 2003-2006 The Measurement Factory
* Licensed under the Apache License, Version 2.0 */
#include "base/polygraph.h"
#include "xstd/h/sstream.h"
#include "xml/XmlAttr.h"
#include "loganalyzers/ReportBlob.h"
#include "loganalyzers/BlobDb.h"
static const String strKey = "key";
String BlobDb::Key(const String &name, const Scope &scope) {
return name + KeySuffix(scope);
}
String BlobDb::KeySuffix(const Scope &scope) {
return scope ? String(".scope=") + scope.image() : String("");
}
BlobDb::BlobDb(): theBlobIdx(15991) {
}
const ReportBlob *BlobDb::has(const String &key) {
return find(key);
}
bool CheckParent(const XmlNode &n) {
if (n.kids()) {
for (int i = 0; i < n.kids()->count(); ++i) {
//clog << here << n.kids()->item(i)->name() << endl;
Assert(n.kids()->item(i)->parent());
if (!CheckParent(*n.kids()->item(i))) {
Assert(false);
return false;
}
}
}
return true;
}
const ReportBlob *BlobDb::add(const ReportBlob &b) {
//clog << here << "created: " << b.key() << endl;
//CheckParent(b);
if (const ReportBlob *copy = find(b.key())) {
//cerr << here << "duplicate: " << b.key() << endl;
ostringstream buf1, buf2;
b.print(buf1, "") << ends;
copy->print(buf2, "") << ends;
if (buf1.str() != buf2.str())
cerr << "internal_error: inconsistent computation of " << b.key() << endl;
streamFreeze(buf1, false);
streamFreeze(buf2, false);
return copy;
} else {
theBlobs << b;
theBlobIdx.add((const ReportBlob*)theBlobs.last());
return (const ReportBlob*)theBlobs.last();
}
}
const ReportBlob &BlobDb::get(const String &key) {
//cerr << here << "looking for blob: " << key << endl;
const char *descr = 0;
if (const ReportBlob *blob = find(key))
return *blob;
XmlSearchRes errs;
theErrors.selByAttrVal(strKey, key, errs);
if (errs.count())
return *(const ReportBlob*)errs.last();
cerr << here << "error: cannot find blob: " << key << endl;
// create an error blob so that we can return something
ReportBlob blob(key, "internal reporter error");
XmlTag err("internal_error");
if (descr)
err << XmlAttr("description", "blob not found");
err << XmlAttr("context", key);
blob << err;
theErrors << blob;
return *(const ReportBlob*)theErrors.last();
}
// XXX: check that include is used at most once per key
const XmlNode &BlobDb::include(const String &key) {
XmlTag t("include");
t << XmlAttr("src", key);
t << XmlAttr("auth", "1"); // authoritative
theIncludes << t;
return *theIncludes.last();
}
const XmlNode &BlobDb::quote(const String &key) {
XmlTag t("include");
t << XmlAttr("src", key);
theIncludes << t;
return *theIncludes.last();
}
XmlNode &BlobDb::ptr(const String &key, const XmlNodes &context) {
XmlTag t("blob_ptr");
t << XmlAttr(strKey, key);
t << context;
thePtrs << t;
return *thePtrs.last();
}
const ReportBlob *BlobDb::find(const String &key) const {
return theBlobIdx.find(key);
}
ostream &BlobDb::print(ostream &os, const String &pfx) const {
return theBlobs.print(os, pfx);
}
syntax highlighted by Code2HTML, v. 0.9.1