Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

rdbModel::Assertion::Operator Class Reference

#include <Assertion.h>

List of all members.

Public Member Functions

bool appendChild (Operator *child)
 Add another child to a conjunction-style operator.
bool appendChild (Operator *child)
 Add another child to a conjunction-style operator.
const std::vector< Operator * > & getChildren () const
 Throw exception if Operator is a comparison operator.
const std::vector< Operator * > & getChildren () const
 Throw exception if Operator is a comparison operator.
const std::string * getCompareArgs () const
 Throw exception if Operator is not a comparison operator.
const std::string * getCompareArgs () const
 Throw exception if Operator is not a comparison operator.
const FIELDTYPEgetCompareArgTypes () const
 Get types of comparison args.
const FIELDTYPEgetCompareArgTypes () const
 Throw exception if Operator is not a comparison operator.
bool getOld () const
 True if operator or sub-operator refers to existing row.
bool getOld () const
 True if operator or sub-operator refers to existing row.
OPTYPE getOpType () const
OPTYPE getOpType () const
const std::string & getTableName () const
 Throw exception if Operaotr is not EXISTS.
const std::string & getTableName () const
 Throw exception if Operator is not EXISTS.
bool getToBe () const
 True if operator or sub-operator refers to future row.
bool getToBe () const
 True if operator or sub-operator refers to future row.
bool isCompareOp () const
bool isCompareOp () const
 Operator (Operator *op, Row *toBe)
 Copy an operator, substituting from toBe row as appropriate.
 Operator (OPTYPE type, const std::vector< Operator * > &children, bool keepChildren=false)
 Constructor for OR, AND, NOT.
 Operator (OPTYPE type, const std::string &tableName, Operator *child=0)
 Constructor for EXISTS.
 Operator (OPTYPE type, const std::string &leftArg, const std::string &rightArg, FIELDTYPE leftType, FIELDTYPE rightType)
 Operator ()
 Operator (Operator *op, Row *toBe)
 Copy an operator, substituting from toBe row as appropriate.
 Operator (OPTYPE type, const std::vector< Operator * > &children, bool keepChildren=false)
 Constructor for OR, AND, NOT.
 Operator (OPTYPE type, const std::string &tableName, Operator *child=0)
 Constructor for EXISTS.
 Operator (OPTYPE type, const std::string &leftArg, const std::string &rightArg, FIELDTYPE leftType, FIELDTYPE rightType)
 Operator ()
bool validCompareOp (Table *table) const
bool validCompareOp (Table *table) const
bool verify (Row &old, Row &toBe, Table *t) const
 Evaluate operator on argument Rows.
bool verify (Row &old, Row &toBe, Table *t) const
 Evaluate operator on argument Rows.
 ~Operator ()
 ~Operator ()

Private Member Functions

bool compareFloat (const std::string *vals, OPTYPE type) const
 Handling specific to floating point data.
bool compareFloat (const std::string *vals, OPTYPE type) const
 Handling specific to floating point data.
bool compareInt (const std::string *vals, OPTYPE type) const
 Handling specific to integer data.
bool compareInt (const std::string *vals, OPTYPE type) const
 Handling specific to integer data.
bool compareString (const std::string *vals, OPTYPE type) const
 Handling specific to string data.
bool compareString (const std::string *vals, OPTYPE type) const
 Handling specific to string data.
bool compareTs (const std::string *vals, OPTYPE type) const
 Handling specific to timestamp data.
bool compareTs (const std::string *vals, OPTYPE type) const
 Handling specific to timestamp data.
bool verifyCompare (Row &old, Row &toBe, Table *t) const
 Handling specific to 2-arg compare operators.
bool verifyCompare (Row &old, Row &toBe, Table *t) const
 Handling specific to 2-arg compare operators.

Private Attributes

std::string m_compareArgs [2]
FIELDTYPE m_compareType [2]
bool m_keepChildren
bool m_old
std::vector< Operator * > m_operands
 Following is used only for non-compare operators.
std::vector< Operator * > m_operands
 Following is used only for non-compare operators.
OPTYPE m_opType
std::string m_tableName
 Following used only for EXISTS.
bool m_toBe


Constructor & Destructor Documentation

rdbModel::Assertion::Operator::Operator  )  [inline]
 

00073 : m_opType(OPTYPEundefined) {};

rdbModel::Assertion::Operator::~Operator  ) 
 

00012                                {
00013     if (!m_keepChildren) {
00014       while (m_operands.size() ) {
00015         Operator* op = m_operands.back();
00016         m_operands.pop_back();
00017         delete op;
00018       }
00019     }
00020   }

rdbModel::Assertion::Operator::Operator OPTYPE  type,
const std::string &  leftArg,
const std::string &  rightArg,
FIELDTYPE  leftType,
FIELDTYPE  rightType
 

Constructor for comparison. If the operator is OPTTYPEisNull or OPTYPEisEmpty rightArg and rightLiteral are ignored.

00043     :  m_opType(type), m_keepChildren(false), m_toBe(false), m_old(false) {
00044 
00045     m_tableName.clear();
00046     m_operands.clear();
00047     if (!isCompareOp()) {
00048       m_opType = OPTYPEundefined;
00049       return;
00050     }
00051 
00052     m_compareArgs[0] = leftArg;
00053     m_compareArgs[1] = rightArg;
00054     m_compareType[0] = leftLiteral;
00055     m_compareType[1] = rightLiteral;
00056     if ((type == OPTYPEisNull) || (type ==OPTYPEisEmpty)) {
00057       m_compareType[1] = FIELDTYPElit;
00058       m_compareArgs[1] = "";
00059     }
00060     m_toBe = ((leftLiteral == FIELDTYPEtoBe) || 
00061               (rightLiteral == FIELDTYPEtoBe));
00062     m_old = ((leftLiteral == FIELDTYPEold) || 
00063              (rightLiteral == FIELDTYPEold));
00064   }

rdbModel::Assertion::Operator::Operator OPTYPE  type,
const std::string &  tableName,
Operator child = 0
 

Constructor for EXISTS.

00068                                                  : m_opType(type),
00069                                                    m_tableName(tableName),
00070                                                    m_keepChildren(false)
00071   {
00072     if (type != OPTYPEexists) {
00073       m_opType = OPTYPEundefined;
00074       return;
00075     }
00076     m_operands.clear();
00077     m_operands.push_back(child);
00078   }

rdbModel::Assertion::Operator::Operator OPTYPE  type,
const std::vector< Operator * > &  children,
bool  keepChildren = false
 

Constructor for OR, AND, NOT.

00083                                                     :
00084     m_opType(type), m_keepChildren(keepChildren) {
00085 
00086     m_toBe = false;
00087     m_old = false;
00088     if ((type == OPTYPEor) || (type == OPTYPEand) || (type = OPTYPEnot)) {
00089       m_tableName.clear();
00090       unsigned int nChild = children.size();
00091       if (!nChild) {
00092         m_opType = OPTYPEundefined;
00093         return;
00094       }
00095       for (unsigned int iChild = 0; iChild < nChild; iChild++) {
00096         m_toBe |= (children[iChild]->m_toBe);
00097         m_old |= (children[iChild]->m_old);
00098         m_operands.push_back(children[iChild]);
00099       }
00100     }
00101     else m_opType = OPTYPEundefined;
00102   }

rdbModel::Assertion::Operator::Operator Operator op,
Row toBe
 

Copy an operator, substituting from toBe row as appropriate.

00107     : m_opType(op->m_opType), m_tableName(op->m_tableName), 
00108       m_keepChildren(false), m_toBe(false), m_old(op->m_old) {
00109     m_operands.clear();
00110 
00111     switch (m_opType) {
00112       // OPTYPEor, and, not and exists all have child operators
00113     case OPTYPEor:
00114     case OPTYPEand: 
00115     case OPTYPEnot: 
00116     case OPTYPEexists:
00117       {
00118         unsigned nChild = op->m_operands.size();
00119         for (unsigned iChild = 0; iChild < nChild; iChild++) {
00120           Operator* child = new Operator((op->m_operands)[iChild], toBe);
00121           appendChild(child);
00122         }
00123         break;
00124       }
00125     case OPTYPEequal:
00126     case OPTYPEnotEqual:
00127     case OPTYPElessThan:
00128     case OPTYPEgreaterThan:
00129     case OPTYPElessOrEqual:
00130     case OPTYPEgreaterOrEqual:
00131     case OPTYPEisEmpty:
00132     case OPTYPEisNull: {
00133       for (unsigned i = 0; i < 2; i++) {
00134         if ((op->m_compareType[i] == FIELDTYPEtoBe) || 
00135             (op->m_compareType[i] == FIELDTYPEtoBeDef) ) { 
00136           // have to supply value from row
00137           FieldVal* f = toBe->find(op->m_compareArgs[i]);
00138           if (!f) {
00139             throw RdbException
00140               ("Assertion::Operator constructor can't resolve field");
00141           }
00142           m_compareArgs[i] = f->m_val;
00143           m_compareType[i] = FIELDTYPElit;
00144         }
00145         else {   // just copy what's there
00146           m_compareArgs[i] = op->m_compareArgs[i];
00147           m_compareType[i] =op->m_compareType[i];
00148         }
00149       }
00150       break;
00151     }
00152     default:
00153       throw RdbException("Assertion::Operator constructor - Unknown OP type");
00154     }
00155   }

rdbModel::Assertion::Operator::Operator  )  [inline]
 

00073 : m_opType(OPTYPEundefined) {};

rdbModel::Assertion::Operator::~Operator  ) 
 

rdbModel::Assertion::Operator::Operator OPTYPE  type,
const std::string &  leftArg,
const std::string &  rightArg,
FIELDTYPE  leftType,
FIELDTYPE  rightType
 

Constructor for comparison. If the operator is OPTTYPEisNull or OPTYPEisEmpty rightArg and rightLiteral are ignored.

rdbModel::Assertion::Operator::Operator OPTYPE  type,
const std::string &  tableName,
Operator child = 0
 

Constructor for EXISTS.

rdbModel::Assertion::Operator::Operator OPTYPE  type,
const std::vector< Operator * > &  children,
bool  keepChildren = false
 

Constructor for OR, AND, NOT.

rdbModel::Assertion::Operator::Operator Operator op,
Row toBe
 

Copy an operator, substituting from toBe row as appropriate.


Member Function Documentation

bool rdbModel::Assertion::Operator::appendChild Operator child  ) 
 

Add another child to a conjunction-style operator.

bool rdbModel::Assertion::Operator::appendChild Operator child  ) 
 

Add another child to a conjunction-style operator.

00158                                                      {
00159     m_toBe |= child->m_toBe;
00160     m_old |= child->m_old;
00161     if  ((m_opType == OPTYPEor) || (m_opType == OPTYPEand) ) {
00162       m_operands.push_back(child);
00163       return true;
00164     }
00165     else if ((m_opType == OPTYPEnot) && (m_operands.size() == 0) ) {
00166       m_operands.push_back(child);
00167       return true;
00168     }
00169     throw RdbException("Assertion::Operator::appendChild: wrong parent operator type");
00170     return false;
00171   }

bool rdbModel::Assertion::Operator::compareFloat const std::string *  vals,
OPTYPE  type
const [private]
 

Handling specific to floating point data.

bool rdbModel::Assertion::Operator::compareFloat const std::string *  vals,
OPTYPE  type
const [private]
 

Handling specific to floating point data.

00412                                                                   {
00413     using facilities::Util;
00414     double left, right;
00415     try {
00416       left = Util::stringToDouble(*vals);
00417       right = Util::stringToDouble(*(vals + 1));
00418     }
00419     catch (facilities::WrongType ex) {
00420       throw
00421         RdbException("Assertion::Operator::compareFloat illegal input");
00422     }
00423     switch (type) {
00424     case OPTYPEequal:
00425       return left == right;
00426     case OPTYPEnotEqual:
00427       return left != right;
00428     case OPTYPElessThan:
00429       return left < right;
00430     case OPTYPEgreaterThan:
00431       return left > right;
00432     case OPTYPElessOrEqual:
00433       return left <= right;
00434     case OPTYPEgreaterOrEqual:
00435       return right >= right;
00436     default:
00437       throw RdbException("Assertion::Operator::compareFloat bad OPTYPE");
00438     }
00439     return false;
00440   }

bool rdbModel::Assertion::Operator::compareInt const std::string *  vals,
OPTYPE  type
const [private]
 

Handling specific to integer data.

bool rdbModel::Assertion::Operator::compareInt const std::string *  vals,
OPTYPE  type
const [private]
 

Handling specific to integer data.

00396                                                               {
00397     using facilities::Util;
00398 
00399     try {
00400       int i= Util::stringToInt(*vals);
00401       i = Util::stringToInt(*(vals + 1));
00402     }
00403     catch (facilities::WrongType ex) {
00404       throw
00405         RdbException("Assertion::Operator::compareInt illegal input");
00406     }
00407     return compareFloat(vals, type);
00408   }

bool rdbModel::Assertion::Operator::compareString const std::string *  vals,
OPTYPE  type
const [private]
 

Handling specific to string data.

bool rdbModel::Assertion::Operator::compareString const std::string *  vals,
OPTYPE  type
const [private]
 

Handling specific to string data.

Handling specific to string data. Only supported operators for strings are == and !=

00445                                                                    {
00446     switch (type) {
00447     case OPTYPEequal: 
00448       return ( (*vals).compare(*(vals+1)) == 0 );
00449     case OPTYPEnotEqual:
00450       return ( (*vals).compare(*(vals+1)) != 0 );
00451     default:
00452       throw 
00453         RdbException("Assertion::Operator::compareString Unsupported OPTYPE");
00454     }
00455     return false;
00456   }

bool rdbModel::Assertion::Operator::compareTs const std::string *  vals,
OPTYPE  type
const [private]
 

Handling specific to timestamp data.

bool rdbModel::Assertion::Operator::compareTs const std::string *  vals,
OPTYPE  type
const [private]
 

Handling specific to timestamp data.

00362                                                              {
00363     using facilities::Timestamp;
00364     Timestamp left, right;
00365     try {
00366       left = Timestamp(*vals);
00367       right = Timestamp(*(vals + 1));
00368     }
00369     catch(facilities::BadTimeInput ex) {
00370       throw
00371         RdbException("Assertion::Operator::CompareTs illegal input");
00372     }
00373 
00374     switch (type) {
00375     case OPTYPEequal:
00376       return left == right;
00377     case OPTYPEnotEqual:
00378       return left != right;
00379     case OPTYPElessThan:
00380       return left < right;
00381     case OPTYPEgreaterThan:
00382       return left > right;
00383     case OPTYPElessOrEqual:
00384       return left <= right;
00385     case OPTYPEgreaterOrEqual:
00386       return right >= right;
00387     default:
00388       throw RdbException("Assertion::Operator::compareTs bad OPTYPE");
00389     }
00390     return false;
00391 
00392     
00393   }

const std::vector<Operator* >& rdbModel::Assertion::Operator::getChildren  )  const
 

Throw exception if Operator is a comparison operator.

const std::vector< Assertion::Operator * > & rdbModel::Assertion::Operator::getChildren  )  const
 

Throw exception if Operator is a comparison operator.

00338                                        {
00339     if (isCompareOp()) 
00340       throw RdbException("Assertion::Operator::getChildren: wrong type");
00341     return m_operands;
00342   }

const std::string* rdbModel::Assertion::Operator::getCompareArgs  )  const
 

Throw exception if Operator is not a comparison operator.

const std::string * rdbModel::Assertion::Operator::getCompareArgs  )  const
 

Throw exception if Operator is not a comparison operator.

00193                                                            {
00194     if (!isCompareOp()) 
00195       throw RdbException("Assertion::Operator::getCompareArgs: wrong type");
00196     return &m_compareArgs[0];
00197   }

const FIELDTYPE* rdbModel::Assertion::Operator::getCompareArgTypes  )  const
 

Get types of comparison args.

const FIELDTYPE * rdbModel::Assertion::Operator::getCompareArgTypes  )  const
 

Throw exception if Operator is not a comparison operator.

00201                                                                {
00202     if (!isCompareOp()) 
00203       throw RdbException("Assertion::Operator::getLiteralness: wrong type");
00204     return &m_compareType[0];
00205   }

bool rdbModel::Assertion::Operator::getOld  )  const [inline]
 

True if operator or sub-operator refers to existing row.

00121 {return m_old;}

bool rdbModel::Assertion::Operator::getOld  )  const [inline]
 

True if operator or sub-operator refers to existing row.

00121 {return m_old;}

OPTYPE rdbModel::Assertion::Operator::getOpType  )  const [inline]
 

00115 {return m_opType;}

OPTYPE rdbModel::Assertion::Operator::getOpType  )  const [inline]
 

00115 {return m_opType;}

const std::string& rdbModel::Assertion::Operator::getTableName  )  const
 

Throw exception if Operaotr is not EXISTS.

const std::string & rdbModel::Assertion::Operator::getTableName  )  const
 

Throw exception if Operator is not EXISTS.

00208                                                          {
00209     if (m_opType != OPTYPEexists) 
00210       throw RdbException("Assertion::Operator::getTableName: wrong type");
00211     return m_tableName;
00212   }

bool rdbModel::Assertion::Operator::getToBe  )  const [inline]
 

True if operator or sub-operator refers to future row.

00118 {return m_toBe;}

bool rdbModel::Assertion::Operator::getToBe  )  const [inline]
 

True if operator or sub-operator refers to future row.

00118 {return m_toBe;}

bool rdbModel::Assertion::Operator::isCompareOp  )  const [inline]
 

True if operator is isNull, isEmpty or any of the usual arithmetic comparisons

00101 {return (m_opType >= OPTYPEisNull);}

bool rdbModel::Assertion::Operator::isCompareOp  )  const [inline]
 

True if operator is isNull, isEmpty or any of the usual arithmetic comparisons

00101 {return (m_opType >= OPTYPEisNull);}

bool rdbModel::Assertion::Operator::validCompareOp Table table  )  const
 

Check whether columns or column and literal to be compared have compatible types

bool rdbModel::Assertion::Operator::validCompareOp Table table  )  const
 

Check whether columns or column and literal to be compared have compatible types

00174                                                              {
00175     if (m_compareType[0] != FIELDTYPElit) {
00176       Column* col0 = myTable->getColumnByName(m_compareArgs[0]);
00177       if (m_compareType[1] != FIELDTYPElit) {
00178         Column* col1 = myTable->getColumnByName(m_compareArgs[1]);
00179         return col1->isCompatible(col0);
00180       }
00181       else {  // one column, one literal
00182         return col0->okValue(m_compareArgs[1], false);
00183       }
00184     }
00185     else { // 1st arg is a literal; second arg must be column
00186       Column* col1 = myTable->getColumnByName(m_compareArgs[1]);
00187       return col1->okValue(m_compareArgs[0], false);        
00188     }
00189   }

bool rdbModel::Assertion::Operator::verify Row old,
Row toBe,
Table t
const
 

Evaluate operator on argument Rows.

bool rdbModel::Assertion::Operator::verify Row old,
Row toBe,
Table t
const
 

Evaluate operator on argument Rows.

00215                                                                      {
00216     switch(m_opType) {
00217     case OPTYPEor: {
00218       unsigned nChild = m_operands.size();
00219       for (unsigned i = 0; i < nChild; i++) {
00220         if (m_operands[i]->verify(old, toBe, t)) return true;
00221       }
00222       return false;
00223     }
00224 
00225     case OPTYPEand: {
00226       unsigned nChild = m_operands.size();
00227       for (unsigned i = 0; i < nChild; i++) {
00228         if (!(m_operands[i]->verify(old, toBe, t))) return false;
00229       }
00230       return true;
00231     }
00232     case OPTYPEnot:
00233       return (!(m_operands[0]->verify(old, toBe, t)));
00234 
00235       
00236     case OPTYPEisNull: 
00237     case OPTYPEisEmpty: 
00238       // These two are almost the same
00239       {
00240       Row* r = 0;
00241       if ( (m_compareType[0] == FIELDTYPEtoBe) || 
00242            (m_compareType[0] == FIELDTYPEtoBeDef) ) r = &toBe;
00243       else r = &old;
00244 
00245       FieldVal* f = r->find(m_compareArgs[0]);
00246       if (f) {
00247         if (m_opType == OPTYPEisNull) return f->m_null;
00248         return ((f->m_val).size() == 0);
00249       }
00250       else {  // improper input.  Field should have been found
00251         throw RdbException("Assertion::Operator::verify missing isNull field");
00252       }
00253     }
00254       // handle all 2-argument compare operators together
00255     case OPTYPEequal:
00256     case OPTYPEnotEqual:
00257     case OPTYPElessThan:
00258     case OPTYPEgreaterThan:
00259     case OPTYPElessOrEqual:
00260     case OPTYPEgreaterOrEqual:
00261       return verifyCompare(old, toBe, t);
00262 
00263     default:
00264       return false;
00265     }
00266     return false;
00267   }

bool rdbModel::Assertion::Operator::verifyCompare Row old,
Row toBe,
Table t
const [private]
 

Handling specific to 2-arg compare operators.

bool rdbModel::Assertion::Operator::verifyCompare Row old,
Row toBe,
Table t
const [private]
 

Handling specific to 2-arg compare operators.

00270   {
00271     // Assume we already know the comparison is sensible; that is, that
00272     // the two args are of compatible types.  This check should be
00273     // done when the operator is constructed (by XercesBuilder)
00274     std::string values[2];
00275     std::string colname;
00276     colname.clear();   // used to determine type (string, int,..) of compare
00277 
00278     for (unsigned i = 0; i < 2; i++) {
00279       switch (m_compareType[i]) {
00280       case FIELDTYPElit:
00281       case FIELDTYPElitDef:
00282         values[i] = m_compareArgs[i];
00283         break;
00284       case FIELDTYPEold:
00285       case FIELDTYPEoldDef: {
00286         FieldVal* f = old.find(m_compareArgs[i]);
00287         if (!f) {
00288           std::string msg = 
00289             std::string("Assertion::Operator::verifyCompare missing field ")
00290             + m_compareArgs[i];
00291           throw
00292             RdbException(msg);
00293         }
00294         values[i] = f->m_val;
00295         colname = f->m_colname;
00296         break;
00297       }
00298       case FIELDTYPEtoBe:
00299       case FIELDTYPEtoBeDef: {
00300         FieldVal* f = toBe.find(m_compareArgs[i]);
00301         if (!f) {
00302           throw
00303             RdbException("Assertion::Operator::verifyCompare missing field");
00304         }
00305         values[i] = f->m_val;
00306         colname = f->m_colname;
00307         break;
00308       }
00309       default:
00310         throw
00311           RdbException("Assertion::Operator::verifyCompare bad arg type");
00312       }
00313     }
00314     if (colname.size() > 0) {// determine type to convert to
00315       Column* c = t->getColumnByName(colname);
00316       Datatype* d = c->getDatatype();
00317       
00318       switch (d->getType()) {
00319       case Datatype::TYPEtimestamp:
00320       case Datatype::TYPEdatetime:
00321         return compareTs(&values[0], m_opType);
00322       case Datatype::TYPEint:
00323       case Datatype::TYPEmediumint:
00324       case Datatype::TYPEsmallint:
00325         return compareInt(&values[0], m_opType);
00326       case Datatype::TYPEreal:
00327       case Datatype::TYPEdouble:
00328         return compareFloat(&values[0], m_opType);
00329       default:  // do nothing
00330         ;
00331       }
00332     }
00333     // Otherwise they're strings.
00334     return compareString(&values[0], m_opType);
00335   }


Member Data Documentation

std::string rdbModel::Assertion::Operator::m_compareArgs [private]
 

Following two lines apply only to compare operators (includes isNull, isEmpty)

In order to format properly in an SQL query, need to keep track of whether compare arg is literal, column name referring to current row under consideration, or column name referring to proposed row (in case this is part of an assertion about relation of existing rows to proposed row)

FIELDTYPE rdbModel::Assertion::Operator::m_compareType [private]
 

bool rdbModel::Assertion::Operator::m_keepChildren [private]
 

bool rdbModel::Assertion::Operator::m_old [private]
 

Following is true if this operator or suboperator has an arg. column name referring to a row already in the table

std::vector<Operator* > rdbModel::Assertion::Operator::m_operands [private]
 

Following is used only for non-compare operators.

std::vector<Operator* > rdbModel::Assertion::Operator::m_operands [private]
 

Following is used only for non-compare operators.

OPTYPE rdbModel::Assertion::Operator::m_opType [private]
 

std::string rdbModel::Assertion::Operator::m_tableName [private]
 

Following used only for EXISTS.

bool rdbModel::Assertion::Operator::m_toBe [private]
 

Following is true if this operator or suboperator has an arg. column name referring to a "toBe" row


The documentation for this class was generated from the following files:
Generated on Wed Feb 2 19:21:56 2011 for BOSS6.5.5 by  doxygen 1.3.9.1