/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Yokogawa Electric Corporation,
* YDC Corporation, IPA (Information-technology Promotion Agency, Japan).
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms, with
* or without modification, are permitted provided that the following
* conditions and disclaimer are agreed and accepted by the user:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the names of the copyrighters, the name of the project which
* is related to this software (hereinafter referred to as "project") nor
* the names of the contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. No merchantable use may be permitted without prior written
* notification to the copyrighters. However, using this software for the
* purpose of testing or evaluating any products including merchantable
* products may be permitted without any notification to the copyrighters.
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHTERS, THE PROJECT AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING
* BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHTERS, THE PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT,STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $TAHI: v6eval/lib/Pz/WObject.cc,v 1.68 2003/12/04 04:59:47 akisada Exp $
*/
#include "WObject.h"
#include "MmObject.h"
#include "MmChecksum.h"
#include "PObject.h"
#include "PControl.h"
#include "PvOctets.h"
#include "ItPosition.h"
#include "CmMain.h"
#include <stdio.h>
//----------------------------------------------------------------------
const PObject* WObject::rgenerate() const {return object();}
const PObject* WmObject::rgenerate() const {return rgenerate_;}
const PObject* WcObject::rgenerate() const {return rgenerate_;}
const PObject* WvSubstr::rgenerate() const {return substr_;}
//----------------------------------------------------------------------
bool WObject::encodeNumber(WControl& c,OCTBUF& b,const PvNumber& p) {
const MObject* m=meta(); // m==0 ????????
if(m!=0) {m->encodeNumber(c,offset(),b,p);}
return (m!=0);}
bool WObject::encodeOctets(WControl& c,OCTBUF& b,const PvOctets& p) {
const MObject* m=meta(); // m==0 ????????
if(m!=0) {m->encodeOctets(c,offset(),b,p);}
return (m!=0);}
bool WvObject::encodeNumber(WControl&,OCTBUF& b,const PvNumber& p) {
b.encodeUint(p.value(),offset(),8);
return true;}
bool WvObject::encodeOctets(WControl&,OCTBUF& b,const PvOctets& p) {
b.encode(offset(),p);
return true;}
void WObject::algorithm(const PaObject*) {}
//----------------------------------------------------------------------
inline void WObject::stepPostion(ItPosition& it) {
ItPosition size(length(),width());
it.add(size);}
void WObject::setSize(const ItPosition& it) {
const ItPosition& o=offset();
ItPosition& size=size_;
if(o==it) {
ItPosition s(length(),width());
size=s;}
else {
size=it;
size.subtract(o);}}
uint32_t WObject::distance() const {
WObject* p=parent();
if(!p)return offset().bytes();
if(p==0 && DBGFLAGS('a')) {
printf("=%s cannot calculate distance\n",metaString());
return 0;}
ItPosition at(offset());
at-=p->offset();
uint16_t b=at.bits();
if(b!=0 && DBGFLAGS('a')) {
printf("=%s bits remains %d\n",metaString(),b);}
return at.bytes();}
//----------------------------------------------------------------------
PvObject* WObject::geneAutoValue() {
const MObject* m=meta();
return (m!=0)?m->geneAutoValue(this):0;}
PvObject* WObject::evalAutoValue() {
const MObject* m=meta();
return (m!=0)?m->evalAutoValue(this):0;}
//----------------------------------------------------------------------
bool WObject::geneAuto(WControl& c,OCTBUF& s) {
const MObject* m=meta();
if(m!=0) {m->geneAuto(c,this,s);}
return c;}
bool WObject::geneFix(WControl& c,OCTBUF& s) {
const MObject* m=meta();
if(m!=0) {m->geneFix(c,this,s);}
return c;}
bool WObject::generate(WControl& c,OCTBUF& s) {
const MObject* m=meta();
if(m!=0) {return m->generate(c,this,s);} //tranfer to Meta
// not has a meta
const PObject* o=object();
return (o!=0)?o->generate(c,this,s):geneAuto(c,s);}
bool WtNode::generate(WControl& c,OCTBUF& s) {
return WObject::generate(c,s);}
bool WmObject::generate(WControl& c,OCTBUF& s) {
return WtNode::generate(c,s);}
bool WcObject::generate(WControl& c,OCTBUF& s) {
uint32_t sl=s.length();
uint32_t o=offset().bytes();
uint32_t l=size().bytes();
if(o+l<=sl) {rgenerate_=s.substr(o,l,rgenerate_);}
return WtNode::generate(c,s);}
bool WvSubstr::generate(WControl& c,OCTBUF& s) {
return WvObject::generate(c,s);}
bool WvOneof::generate(WControl& wc,OCTBUF&) {
const PObject* o=object();
o->generateNotAllow("oneof"); wc.result(1);
return wc;}
bool WvComb::generate(WControl& wc,OCTBUF&) {
const PObject* o=object();
o->generateNotAllow("comb"); wc.result(1);
return wc;}
//----------------------------------------------------------------------
void WObject::internalGeneratePrologue(ItPosition&) {}
void WtNode::internalGeneratePrologue(ItPosition& it) {
CmQueue* n=0;
for(n=nextChild();n!=0;n=nextChild(n)) {
WObject* w=(WObject*)n;
w->generatePrologue(it);}}
void WmObject::internalGeneratePrologue(ItPosition&) {
const PObject* o=object();
if(o!=0) {
operator_=(eOperation)o->operation();
if(operator_!=eOPEQ_) {o->generateNotAllow(operatorString());}}
set_rgenerate(o!=0?o->generateValue(this):geneAutoValue());
if(DBGFLAGS('k')) {
const PObject *rg=rgenerate();
printf("WmObject::internalGeneratePrologue() %s %s ",
metaString(),operatorString());
if(rg!=0) {rg->print(); printf("\n");}
else {printf("NULL\n");}}}
void WvSubstr::internalGeneratePrologue(ItPosition&) {
if(reference_==0||substr_!=0) return;
ItPosition it;
reference_->generatePrologue(it);
const PObject* o=object();
substr_=new PvOctets(it.bytes());
o->generateOctetsWith(*substr_,reference_);}
void WObject::generatePrologue(ItPosition& at) {
ItPosition it(at);
offset(it);
internalGeneratePrologue(it);
setSize(it);
stepPostion(at);}
void WcObject::generatePrologue(ItPosition& at) {
WtNode::generatePrologue(at);
//Check alignment requirement
const MObject* mc = meta();
uint32_t X = mc->alignment_requirement();
uint32_t H = distance();
uint32_t S = length();
uint32_t pad = MObject::padcount_alignment_requirement(X,H,S);
if(pad){
const PObject* o =object();
const PObject* op = parent()? parent()->object() : 0;
o->error("W %s alignment requirement(%d) need %d pad in %s",
o->nameString(),X,pad,(op?op->nameString():""));
}
if(DBGFLAGS('a')) {
printf("=%s distance %d\n",nameString(),H);}
}
//----------------------------------------------------------------------
void WObject::notMatch(WControl& c,CSTR s,RObject& v) const {
if(!c.logging()&&DBGFLAGS('e')==0) return;
const MObject* m=meta();
const MObject* vm=v.meta();
TObject* p=0;
const MObject* pm=0;
printf("%sng %s ",logLevel>0?"log:":"",s);
p=parent(); pm=p!=0?p->meta():0;
if(pm!=0) {printf("%s.",pm->string());}
printf("%s != ",m->string());
p=v.parent(); pm=p!=0?p->meta():0;
if(pm!=0) {printf("%s.",pm->string());}
printf("%s\n",vm->string());}
void WObject::evaluateFailure(const PObject* r,const PObject* e,CSTR op) const {
const MObject* m=meta();
WObject* p=parent();
CSTR n=p!=0?p->nameString():"";
printf("log:ng compare %s.%s received:",n,m->string());
if(r!=0) {r->log(0);} else {printf("NULL");}
printf(" %s ",op!=0?op:"=");
if(e!=0) {e->log(0);} else {printf("NULL");}
printf("\n");}
void WObject::functionFailure(RObject* r) const {
const MObject* m=r!=0?r->meta():0;
const PObject* o=object();
printf("log:ng function at %s not match with ",m!=0?m->string():"NULL");
o->print(); printf("\n");}
void WObject::dbgEvaluate(const PObject* r,const PObject* e,bool ok,CSTR op) const {
const MObject* m=meta();
WObject* p=parent();
CSTR n=p!=0?p->nameString():"";
printf("%s: %s.%s received:",ok?"OK":"NG",n,m!=0?m->string():"");
if(r!=0) {r->print();} else {printf("NULL");}
printf(" %s ",op!=0?op:"=");
if(e!=0) {e->print();} else {printf("NULL");}
printf("\n");}
bool WObject::mustDefine(const PObject* m) const {
const WObject* p=parent();
const PObject* o=p!=0?p->object():m;
o->error("E %s must define %s",o->nameString(),metaString());
return false;}
bool WObject::mustDefineMem(const MObject* m) const {
const PObject* o=object();
o->error("E %s must define %s",o->nameString(),m->string());
return false;}
//----------------------------------------------------------------------
bool WObject::vevaluate(const void *r) {
if(r==0) {return false;}
WControl c;
evaluate(c,(RObject*)r);
return c;}
bool WObject::metaEvaluate(WControl& c,RObject& v) {
const MObject* m=meta();
const MObject* vm=v.meta();
bool comp=m->comparableMeta(vm);
if(!comp) {c.result(1); notMatch(c,"meta",v);}
return comp;}
bool WObject::valueEvaluate(WControl& c,const PvObject* ro,const PvObject* eo) {
if(eo==0||ro==0) {abort(); return false;}
int32_t x=eo->compareObjectWith(c,*ro);
bool cmp=false;
uint32_t op=operation();
/**/ if(x> 0) {cmp=op&eOPLT_;}
else if(x==0) {cmp=op&eOPEQ_;}
else if(x< 0) {cmp=op&eOPGT_;}
if(DBGFLAGS('e')) {dbgEvaluate(ro,eo,cmp,operatorString());}
if(!cmp) {
c.result(1);
if(c.logging()) {evaluateFailure(ro,eo,operatorString());}}
return cmp;}
//----------------------------------------------------------------------
RObject* WObject::evaluate(WControl& c,RObject* r) {
if(r==0) return 0;
if(metaEvaluate(c,*r)) {doEvaluate(c,*r);}
RObject* p=r->parent();
return (p!=0)?p->nextEvaluation(r):0;}
bool WObject::doEvaluate(WControl&,RObject&) {return false;}
bool WcObject::doEvaluate(WControl& c,RObject& r) {
WObject* w=nextEvaluation();
RObject* cr=r.nextEvaluation();
for(;w!=0;w=nextEvaluation(w)) {
if(cr==0) {break;}
cr=w->evaluate(c,(RObject*)cr);
if(c.stop()) {c.clearStop(); w=0; cr=0; break;}}
if(w!=0||cr!=0) {c.result(1); notMatch(c,"count",r);}
return c;}
bool WmObject::doEvaluate(WControl& c,RObject& r) {
const PvObject* ro=r.pvalue();
const PvObject* eo=revaluate();
return valueEvaluate(c,ro,eo);}
RObject* WvOneof::evaluate(WControl& c,RObject* r) {
WObject* ok=references_.findMatching(r,(WObjectEqFunc)&WObject::vevaluate);
if(ok==0) {c.result(1); functionFailure(r);}
RObject* p=r->parent();
return p->nextEvaluation(r);}
RObject* WvComb::evaluate(WControl& c,RObject* r) {
WObjectList tmp(references_);
RObject* q=r;
RObject* p=r->parent();
for(;tmp.size();) {
if(q==0) {q=p->nextEvaluation(r); r=q;}
WObject* ok=tmp.findMatching(q,(WObjectEqFunc)&WObject::vevaluate);
if(ok==0) {c.result(1); functionFailure(r); return q;}
q=0;
tmp.remove(ok);}
if(tmp.size()!=0) {c.result(1); functionFailure(r);}
return p->nextEvaluation(r);}
//----------------------------------------------------------------------
void WObject::internalEvaluatePrologue(ItPosition&) {}
void WtNode::internalEvaluatePrologue(ItPosition& it) {
CmQueue* n=0;
for(n=nextEvaluation();n!=0;n=nextEvaluation(n)) {
WObject* w=(WObject*)n;
w->evaluatePrologue(it);}}
void WmObject::internalEvaluatePrologue(ItPosition&) {
const PObject* o=object();
if(o!=0) {operator_=(eOperation)o->operation();}
revaluate_=o!=0?o->evaluateValue(this):evalAutoValue();
if(DBGFLAGS('k')) {
PObject* re=revaluate();
printf("WmObject::internalEvaluatePrologue() %s %s ",
metaString(),operatorString());
if(re!=0) {re->print(); printf("\n");}
else {printf("NULL\n");}}}
void WObject::evaluatePrologue(ItPosition& it) {
internalEvaluatePrologue(it);}
//----------------------------------------------------------------------
void WObject::icvUpdate(const PaObject&) {}
void WtNode::icvUpdate(const PaObject& sa) {
CmQueue* n=0;
for(n=nextEvaluation();n!=0;n=nextEvaluation(n)) {
WObject* w=(WObject*)n;
w->icvUpdate(sa);}}
void WcObject::icvUpdate(const PaObject& sa) {
const MObject* m=meta();
if(m!=0&&m->icvUpdate(sa,rgenerate_)) {return;}
WtNode::icvUpdate(sa);}
//----------------------------------------------------------------------
const WObject* WObject::ancestor(const PObject* r) const {
const PObject* o=object();
if(o==r) return this;
WObject* p=parent();
return p!=0?p->ancestor(r):0;}
WObject* WtNode::insert(TObject* w) {
return (WObject*)children_.insert(w);}
void WtNode::child(TObject* c) {insert(c);}
void WvSubstr::child(TObject* c) {
if(reference_==0) {reference_=(WObject*)c;}
WvObject::child(c);}
void WvOneof::child(TObject* c) {
references_.add((WObject*)c); WvObject::child(c);}
void WvComb::child(TObject* c) {
references_.add((WObject*)c); WvObject::child(c);}
//----------------------------------------------------------------------
uint16_t WObject::width() const {
uint16_t w=0;
const ItPosition& s=size();
if(s.bytes()>=0) {
w=s.bits();}
else {
const MObject* m=meta();
const PObject* po=object();
w=m!=0?m->width():(po!=0)?po->width():0;}
return w;}
uint32_t WObject::length() const {
const ItPosition& s=size();
int32_t l=s.bytes();
if(l<0) {
const MObject* m=meta();
const PObject* po=object();
l=m!=0?m->objectLength(po,this):(po!=0)?po->objectLength(this):0;}
return l;}
//======================================================================
// CONSTRUCTOR/DESCTUCTOR
WObject::WObject(WObject* p,const MObject* m,const PObject* o):TObject(p,m),
object_(o),size_(-1,0),offset_(){}
WObject::~WObject() {object_=0;}
WtNode::WtNode(WObject* p,const MObject* m,const PObject* o):WObject(p,m,o),
children_() {}
WtNode::~WtNode() {
CmQueue* n=0;
CmQueue* o=&children_;
for(n=o->prev();n!=o;n=o->prev()) {
n->deque(); delete n;}}
WmObject::WmObject(WObject* p,const MObject* m,const PObject* o):WtNode(p,m,o),
operator_(eOPEQ_),rgenerate_(0),revaluate_(0) {}
WmObject::~WmObject() {
if(rgenerate_!=0) {delete rgenerate_; rgenerate_=0;}
if(revaluate_!=0) {delete revaluate_; revaluate_=0;}}
WcObject::WcObject(WObject* p,const MObject* m,const PObject* o):WtNode(p,m,o),
rgenerate_(0) {}
WcObject::~WcObject() {
if(rgenerate_!=0) {delete rgenerate_; rgenerate_=0;}}
WcPacket_IP::WcPacket_IP(WObject* p,const MObject* m,const PObject* o):
WcObject(p,m,o),IPinfo_(new Con_IPinfo()) {}
WcPacket_IP::~WcPacket_IP() {
if(IPinfo_!=0) {delete IPinfo_; IPinfo_=0;}}
WvObject::WvObject(WObject* p,const MObject* m,const PObject* o):WtNode(p,m,o) {}
WvObject::~WvObject() {}
WvSubstr::WvSubstr(WObject* p,const MObject* m,const PObject* o):WvObject(p,m,o),
reference_(0),substr_(0) {}
WvSubstr::~WvSubstr() {
reference_=0; // reference_ is in children.
if(substr_!=0) {delete substr_; substr_=0;}}
WvOneof::WvOneof(WObject* p,const MObject* m,const PObject* o):WvObject(p,m,o),
references_() {}
WvOneof::~WvOneof() {}
WvComb::WvComb(WObject* p,const MObject* m,const PObject* o):WvObject(p,m,o),
references_() {}
WvComb::~WvComb() {}
//======================================================================
// FOR DEBUGING
void WObject::printName(uint32_t t,CSTR cls) const {
TObject::printName(t,cls?cls:"WObject");
const PObject* o=object();
if(o!=0) printf("='%s'",o->nameString());
const ItPosition& it=offset();
const ItPosition& sz=size();
printf("\t%d %d %d %d",it.bytes(),it.bits(),sz.bytes(),sz.bits());}
void WcObject::printName(uint32_t t,CSTR cls) const {
WObject::printName(t,cls);
if(DBGFLAGS('k')&&rgenerate_!=0) {
printf(" rg=%d",rgenerate_->length());}}
CSTR WObject::nameString() const {
const PObject* o=object();
return (o!=0)?o->nameString():"UNKOWN";}
implementCmList(WObjectList,WObject);
syntax highlighted by Code2HTML, v. 0.9.1