bool GeneticSpawnBodypartAction::execute() { Bodypart* bp = new Bodypart(childBodypartType,parentBodypart->getGeneticCode()->copy(),parentBodypart->getParentOrganism(),parentBodypart); if(parentBodypart->spawnBodypart(bp)) { return true; } else { bp->destroy(); delete bp; return false; } };
class Bodypart * Message::bodypart( const EString & s, bool create ) { uint b = 0; Bodypart * bp = 0; while ( b < s.length() ) { uint e = b; while ( s[e] >= '0' && s[e] <= '9' ) e++; if ( e < s.length() && s[e] != '.' ) return 0; bool inrange = false; uint n = s.mid( b, e-b ).number( &inrange ); b = e + 1; if ( !inrange || n == 0 ) return 0; List<Bodypart> * c = children(); if ( bp ) c = bp->children(); List<Bodypart>::Iterator i( c ); while ( i && i->number() < n ) ++i; if ( i && i->number() == n ) { if ( n == 1 && !i->header() ) { // it's possible that i doesn't have a header of its // own, and that the parent message's header functions // as such. link it in if that's the case. Header * h = header(); if ( bp && bp->message() ) h = bp->message()->header(); if ( h && ( !h->contentType() || h->contentType()->type() != "multipart" ) ) i->setHeader( h ); } bp = i; } else if ( create ) { Bodypart * child = 0; if ( bp ) child = new Bodypart( n, bp ); else child = new Bodypart( n, this ); c->insert( i, child ); bp = child; } else { return 0; } } return bp; }
EString Message::body() const { EString r; ContentType *ct = header()->contentType(); if ( ct && ct->type() == "multipart" ) { appendMultipart( r ); } else { // XXX: Is this the right place to restore this linkage? Bodypart * firstChild = children()->first(); if ( firstChild ) { firstChild->setHeader( header() ); appendAnyPart( r, firstChild, ct ); } } return r; }
ContentType * Bodypart::contentType() const { ContentType * ct = header()->contentType(); if ( ct ) return ct; if ( !parent() ) return 0; ct = parent()->header()->contentType(); if ( ct ) { if ( ct->type() == "multipart" ) { ct = 0; } else if ( ct->type() == "message" && ct->subtype() == "rfc822" ) { Bodypart * bp = parent()->children()->firstElement(); ct = bp->header()->contentType(); } } return ct; }
void Multipart::appendMultipart( EString &r, bool avoidUtf8 ) const { ContentType * ct = header()->contentType(); EString delim = ct->parameter( "boundary" ); if ( ! this ) ::log( "Fetch::bodyStructure - FATAL, cannnot determine message", Log::Error ); else { if ( this->parent() && this->parent()->isMessage() ) { Message *msg = (Message *)this->parent(); if ( msg->hasPGPsignedPart() ) { appendAnyPart( r, children()->first(), ct, avoidUtf8 ); return; } } else if ( this->isMessage() ) { Message *msg = (Message *)this; if ( msg->hasPGPsignedPart() ) { appendAnyPart( r, children()->first(), ct, avoidUtf8 ); return; } } } List<Bodypart>::Iterator it( children() ); r.append( "--" + delim ); while ( it ) { r.append( crlf ); Bodypart * bp = it; ++it; r.append( bp->header()->asText( avoidUtf8 ) ); r.append( crlf ); appendAnyPart( r, bp, ct, avoidUtf8 ); r.append( crlf ); r.append( "--" ); r.append( delim ); } r.append( "--" ); r.append( crlf ); }
bool GeneticSpawnParentAction::execute() { Bodypart* parent = bp->getParentBodypart(); if(parent != 0) { SpawnpointInformation* spawnpoint = bp->getSpawnpointInformationForBodypart(parent); SpawnpointInformation* parentSpawnpoint = parent->getSpawnpointInformationForBodypart(bp); parent->unregisterChildBodypart(bp); RuntimeManager* runtime = 0; Organism* org = bp->getParentOrganism(); if(org != 0) { //remove storage link, but not the processor org->unregisterBodypart(bp); runtime = org->getRuntimeManager(); runtime->unregisterBodypart(bp); } Bodypart* newParent = new Bodypart(typeToSpawn,parent->getGeneticCode()->copy()); if(newParent->spawnPointAvailable(bp->getBodypartType()) && parent->spawnBodypart(newParent,parentSpawnpoint)) { newParent->spawnBodypart(bp,0,spawnpoint); //prevent spawn from registering processor at organism, but register new storage links return true; } else { newParent->destroy(); if(runtime) { runtime->addDelete(newParent); } else { delete newParent; } parent->spawnBodypart(bp,parentSpawnpoint,spawnpoint); //prevent spawn from registering processor return false; } } else { return false; } };
bool GeneticProcessor::executeRelevantClauses() { BodypartState state = bodypart->getBodypartState(); if(state != BSP_dead) { GeneticClauseList nextRelevantClauses; if(state == BSP_seed) { bodypart->setBodypartState(BSP_creation); executeRelevantClauses(); bodypart->resetSpawnpoints(); Bodypart* bp = new Bodypart(BPT_Stick,bodypart->getGeneticCode()->copy(),bodypart->getParentOrganism()); SpawnpointInformation* sp = new SpawnpointInformation(); sp->position = 1; sp->addSupportedType(BPT_Stick); sp->ang2d = 0.0f; bodypart->addSpawnpoint(sp); SpawnpointInformationList* spi = bp->getSpawnpoints(); sp = 0; for(SpawnpointInformationListIterator it = spi->begin(); it != spi->end(); it++) { if((*it)->position == 0) { sp = (*it); if(!sp->isSupportedType(bodypart->getBodypartType())) { sp->addSupportedType(bodypart->getBodypartType()); } sp->ang2d = 180.0f; } else { (*it)->occupied = true; }; } if(sp == 0) { sp = new SpawnpointInformation(); sp->position = 0; sp->addSupportedType(bodypart->getBodypartType()); sp->ang2d = 180.0f; bp->addSpawnpoint(sp); } if(!bodypart->spawnBodypart(bp)) { delete bp; } else { spi = bp->getSpawnpoints(); for(SpawnpointInformationListIterator it = spi->begin(); it != spi->end(); it++) { if((*it)->position != 0) { (*it)->occupied = false; } } } bodypart->setBodypartState(BSP_alive); }; static int bla = 0; //debug while(!relevantClauses.empty()) { GeneticClause* clause = relevantClauses.back(); //if(clause->description == "Spawn Seed") // bla += 1; clause->run(); //deleteMe is not used at the moment //if(!relevantClauses.back()->deleteMe) //if(clause == relevantClauses.back()) { nextRelevantClauses.push_front(clause); relevantClauses.pop_back(); //} } relevantClauses.clear(); relevantClauses.swap(nextRelevantClauses); //if(stepcount % 100 == 0) { // list_softShuffle(relevantClauses); //} //stepcount++; return true; } else { // BP is dead :_( if(bodypart->getChildBodyparts().empty()) bodypart->getParentOrganism()->deleteBodypart(bodypart); return false; } };
Bodypart * Bodypart::parseBodypart( uint start, uint end, const EString & rfc2822, Header * h, Multipart * parent ) { if ( rfc2822[start] == 13 ) start++; if ( rfc2822[start] == 10 ) start++; Bodypart * bp = new Bodypart; bp->setParent( parent ); bp->setHeader( h ); EString body; if ( end > start ) body = rfc2822.mid( start, end-start ); if ( !body.contains( '=' ) ) { // sometimes people send c-t-e: q-p _and_ c-t-e: 7bit or 8bit. // if they are equivalent we can accept it. uint i = 0; bool any = false; HeaderField * f = 0; while ( (f=h->field(HeaderField::ContentTransferEncoding,i)) != 0 ) { if ( ((ContentTransferEncoding*)f)->encoding() == EString::QP ) any = true; i++; } if ( any && i > 1 ) h->removeField( HeaderField::ContentTransferEncoding ); } EString::Encoding e = EString::Binary; ContentTransferEncoding * cte = h->contentTransferEncoding(); if ( cte ) e = cte->encoding(); if ( !body.isEmpty() ) { if ( e == EString::Base64 || e == EString::Uuencode ) body = body.decoded( e ); else body = body.crlf().decoded( e ); } ContentType * ct = h->contentType(); if ( !ct ) { switch ( h->defaultType() ) { case Header::TextPlain: h->add( "Content-Type", "text/plain" ); break; case Header::MessageRfc822: h->add( "Content-Type", "message/rfc822" ); break; } ct = h->contentType(); } if ( ct->type() == "text" ) { bool specified = false; bool unknown = false; Codec * c = 0; if ( ct ) { EString csn = ct->parameter( "charset" ); if ( csn.lower() == "default" ) csn = ""; if ( !csn.isEmpty() ) specified = true; c = Codec::byName( csn ); if ( !c ) unknown = true; if ( c && c->name().lower() == "us-ascii" ) { // Some MTAs appear to say this in case there is no // Content-Type field - without checking whether the // body actually is ASCII. If it isn't, we'd better // call our charset guesser. (void)c->toUnicode( body ); if ( !c->valid() ) specified = false; // Not pretty. } } if ( !c ) c = new AsciiCodec; bp->d->hasText = true; bp->d->text = c->toUnicode( body.crlf() ); if ( c->name() == "GB2312" || c->name() == "ISO-2022-JP" || c->name() == "KS_C_5601-1987" ) { // undefined code point usage in GB2312 spam is much too // common. (GB2312 spam is much too common, but that's // another matter.) Gb2312Codec turns all undefined code // points into U+FFFD, so here, we can take the unicode // form and say it's the canonical form. when a client // later reads the message, it gets the text in unicode, // including U+FFFD. bool bad = !c->valid(); // the header may contain some unencoded gb2312. we bang // it by hand, ignoring errors. List<HeaderField>::Iterator hf( h->fields() ); while ( hf ) { if ( !hf->valid() && hf->type() == HeaderField::Subject ) { // is it right to bang only Subject? c->reset(); hf->setValue( c->toUnicode( hf->unparsedValue() ) ); } ++hf; } // if the body was bad, we prefer the (unicode) in // bp->d->text and pretend it arrived as UTF-8: if ( bad ) { c = new Utf8Codec; body = c->fromUnicode( bp->d->text ); } } if ( ( !specified && ( !c->wellformed() || ct->subtype() == "html" ) ) || ( specified && ( !c->valid() ) ) ) { Codec * g = 0; if ( ct->subtype() == "html" ) g = guessHtmlCodec( body ); else g = guessTextCodec( body ); UString guessed; if ( g ) guessed = g->toUnicode( body.crlf() ); if ( !g ) { // if we couldn't guess anything, keep what we had if // it's valid or explicitly specified, else use // unknown-8bit. if ( !specified && !c->valid() ) { c = new Unknown8BitCodec; bp->d->text = c->toUnicode( body.crlf() ); } } else { // if we could guess something, is our guess better // than what we had? if ( g->wellformed() && !c->wellformed() ) { c = g; bp->d->text = guessed; } } } if ( specified && c->state() == Codec::Invalid ) { // the codec was specified, and the specified codec // resulted in an error, but did not abort conversion. we // respond by forgetting the error, using the conversion // result (probably including one or more U+FFFD) and // labelling the message as UTF-8. c = new Utf8Codec; body = c->fromUnicode( bp->d->text ); } else if ( !specified && c->state() == Codec::Invalid ) { // the codec was not specified, and we couldn't find // anything. we call it unknown-8bit. c = new Unknown8BitCodec; bp->d->text = c->toUnicode( body ); } // if we ended up using a 16-bit codec and were using q-p, we // need to reevaluate without any trailing CRLF if ( e == EString::QP && c->name().startsWith( "UTF-16" ) ) bp->d->text = c->toUnicode( body.stripCRLF() ); if ( !c->valid() && bp->d->error.isEmpty() ) { bp->d->error = "Could not convert body to Unicode"; if ( specified ) { EString cs; if ( ct ) cs = ct->parameter( "charset" ); if ( cs.isEmpty() ) cs = c->name(); bp->d->error.append( " from " + cs ); } if ( specified && unknown ) bp->d->error.append( ": Character set not implemented" ); else if ( !c->error().isEmpty() ) bp->d->error.append( ": " + c->error() ); } if ( c->name().lower() != "us-ascii" ) ct->addParameter( "charset", c->name().lower() ); else if ( ct ) ct->removeParameter( "charset" ); body = c->fromUnicode( bp->d->text ); bool qp = body.needsQP(); if ( cte ) { if ( !qp ) { h->removeField( HeaderField::ContentTransferEncoding ); cte = 0; } else if ( cte->encoding() != EString::QP ) { cte->setEncoding( EString::QP ); } } else if ( qp ) { h->add( "Content-Transfer-Encoding", "quoted-printable" ); cte = h->contentTransferEncoding(); } } else { bp->d->data = body; if ( ct->type() != "multipart" && ct->type() != "message" ) { e = EString::Base64; // there may be exceptions. cases where some format really // needs another content-transfer-encoding: if ( ct->type() == "application" && ct->subtype().startsWith( "pgp-" ) && !body.needsQP() ) { // seems some PGP things need "Version: 1" unencoded e = EString::Binary; } else if ( ct->type() == "application" && ct->subtype() == "octet-stream" && body.contains( "BEGIN PGP MESSAGE" ) ) { // mutt cannot handle PGP in base64 (what a crock) e = EString::Binary; } // change c-t-e to match the encoding decided above if ( e == EString::Binary ) { h->removeField( HeaderField::ContentTransferEncoding ); cte = 0; } else if ( cte ) { cte->setEncoding( e ); } else { h->add( "Content-Transfer-Encoding", "base64" ); cte = h->contentTransferEncoding(); } } } if ( ct->type() == "multipart" ) { parseMultipart( start, end, rfc2822, ct->parameter( "boundary" ), ct->subtype() == "digest", bp->children(), bp, false ); } else if ( ct->type() == "message" && ct->subtype() == "rfc822" ) { // There are sometimes blank lines before the message. while ( rfc2822[start] == 13 || rfc2822[start] == 10 ) start++; Message * m = new Message; m->setParent( bp ); m->parse( rfc2822.mid( start, end-start ) ); List<Bodypart>::Iterator it( m->children() ); while ( it ) { bp->children()->append( it ); it->setParent( bp ); ++it; } bp->setMessage( m ); body = m->rfc822( false ); } bp->d->numBytes = body.length(); if ( cte ) body = body.encoded( cte->encoding(), 72 ); bp->d->numEncodedBytes = body.length(); if ( bp->d->hasText || ( ct->type() == "message" && ct->subtype() == "rfc822" ) ) { uint n = 0; uint i = 0; uint l = body.length(); while ( i < l ) { if ( body[i] == '\n' ) n++; i++; } if ( l && body[l-1] != '\n' ) n++; bp->setNumEncodedLines( n ); } h->simplify(); return bp; }
void Bodypart::parseMultipart( uint i, uint end, const EString & rfc2822, const EString & divider, bool digest, List< Bodypart > * children, Multipart * parent, bool pgpSigned ) { bool isPgpSigned = pgpSigned; uint start = 0; bool last = false; uint pn = 1; while ( !last && i <= end ) { if ( i >= end || ( rfc2822[i] == '-' && rfc2822[i+1] == '-' && ( i == 0 || rfc2822[i-1] == 13 || rfc2822[i-1] == 10 ) && rfc2822[i+2] == divider[0] && rfc2822.mid( i+2, divider.length() ) == divider ) ) { uint j = i; bool l = false; if ( i >= end ) { l = true; } else { j = i + 2 + divider.length(); if ( rfc2822[j] == '-' && rfc2822[j+1] == '-' ) { j += 2; l = true; } } while ( rfc2822[j] == ' ' || rfc2822[j] == '\t' ) j++; if ( rfc2822[j] == 13 || rfc2822[j] == 10 || j >= rfc2822.length() ) { // finally. we accept that as a boundary line. if ( rfc2822[j] == 13 ) j++; if ( rfc2822[j] == 10 ) j++; if ( start > 0 ) { uint sigstart = start; // remember original start Header * h = Message::parseHeader( start, j, rfc2822, Header::Mime ); if ( digest ) h->setDefaultType( Header::MessageRfc822 ); h->repair(); // Strip the [CR]LF that belongs to the boundary. if ( rfc2822[i-1] == 10 ) { i--; if ( rfc2822[i-1] == 13 ) i--; } if ( isPgpSigned ) { // store the complete to-be-signed part, incl. header(s), to keep the unchanged version Bodypart * bpt = new Bodypart( 0, parent ); bpt->setData( rfc2822.mid(sigstart, i - sigstart) ); bpt->setNumBytes( i - sigstart ); children->append( bpt ); isPgpSigned = false; } Bodypart * bp = parseBodypart( start, i, rfc2822, h, parent ); bp->d->number = pn; children->append( bp ); pn++; h->repair( bp, "" ); } last = l; start = j; i = j; } } while ( i < end && rfc2822[i] != 13 && rfc2822[i] != 10 ) i++; while ( i < end && ( rfc2822[i] == 13 || rfc2822[i] == 10 ) ) i++; } }
void SieveCommand::parse( const EString & previous ) { if ( identifier().isEmpty() ) setError( "Command name is empty" ); bool test = false; bool blk = false; EString i = identifier(); if ( i == "if" || i == "elsif" ) { test = true; blk = true; if ( i == "elsif" && previous != "if" && previous != "elsif" ) setError( "elsif is only permitted after if/elsif" ); } else if ( i == "else" ) { blk = true; if ( previous != "if" && previous != "elsif" ) setError( "else is only permitted after if/elsif" ); } else if ( i == "require" ) { arguments()->numberRemainingArguments(); UStringList::Iterator i( arguments()->takeStringList( 1 ) ); EStringList a; EStringList e; while ( i ) { if ( supportedExtensions()->contains( i->ascii() ) ) a.append( i->ascii().quoted() ); else e.append( i->ascii().quoted() ); ++i; } if ( !e.isEmpty() ) setError( "Each string must be a supported " "sieve extension. " "These are not: " + e.join( ", " ) ); if ( !d->require ) setError( "require is only permitted as the first command." ); else if ( parent() ) parent()->addExtensions( &a ); } else if ( i == "stop" ) { // nothing needed } else if ( i == "reject" ) { require( "reject" ); if ( arguments()->arguments()->isEmpty() ) { // we accept reject without reason } else { // if there is an argument, it must be a string arguments()->numberRemainingArguments(); (void)arguments()->takeString( 1 ); } } else if ( i == "ereject" ) { require( "reject" ); arguments()->numberRemainingArguments(); (void)arguments()->takeString( 1 ); } else if ( i == "fileinto" ) { require( "fileinto" ); if ( arguments()->findTag( ":copy" ) ) require( "copy" ); if ( arguments()->findTag( ":flags" ) ) { require( "imap4flags" ); (void)arguments()->takeTaggedStringList( ":copy" ); } arguments()->numberRemainingArguments(); UString mailbox = arguments()->takeString( 1 ); UString p; p.append( "/" ); p.append( mailbox ); if ( !Mailbox::validName( mailbox ) && !Mailbox::validName( p ) ) { setError( "Expected mailbox name, but got: " + mailbox.utf8() ); } else if ( mailbox.startsWith( "INBOX." ) ) { // a sieve script which wants to reference a // mailbox called INBOX.X must use lower case // (inbox.x). UString aox = UStringList::split( '.', mailbox.mid( 6 ) )->join( "/" ); setError( mailbox.utf8().quoted() + " is Cyrus syntax. Archiveopteryx uses " + aox.utf8().quoted() ); } } else if ( i == "redirect" ) { (void)arguments()->findTag( ":copy" ); arguments()->numberRemainingArguments(); EString s = arguments()->takeString( 1 ).utf8(); AddressParser ap( s ); ap.assertSingleAddress(); if ( !ap.error().isEmpty() ) setError( "Expected one normal address (local@domain), but got: " + s ); } else if ( i == "keep" ) { // nothing needed } else if ( i == "discard" ) { // nothing needed } else if ( i == "vacation" ) { // vacation [":days" number] [":subject" string] // [":from" string] [":addresses" string-list] // [":mime"] [":handle" string] <reason: string> require( "vacation" ); // :days uint days = 7; if ( arguments()->findTag( ":days" ) ) days = arguments()->takeTaggedNumber( ":days" ); if ( days < 1 || days > 365 ) arguments()->tagError( ":days", "Number must be 1..365" ); // :subject (void)arguments()->takeTaggedString( ":subject" ); // anything is acceptable, right? // :from if ( arguments()->findTag( ":from" ) ) { parseAsAddress( arguments()->takeTaggedString( ":from" ), ":from" ); // XXX we don't enforce its being a local address. } // :addresses if ( arguments()->findTag( ":addresses" ) ) { UStringList * addresses = arguments()->takeTaggedStringList( ":addresses" ); UStringList::Iterator i( addresses ); while ( i ) { parseAsAddress( *i, ":addresses" ); ++i; } } // :mime bool mime = false; if ( arguments()->findTag( ":mime" ) ) mime = true; // :handle (void)arguments()->takeTaggedString( ":handle" ); // reason arguments()->numberRemainingArguments(); UString reason = arguments()->takeString( 1 ); if ( mime ) { if ( !reason.isAscii() ) setError( ":mime bodies must be all-ASCII, " "8-bit text is not permitted" ); // so says the RFC EString x = reason.utf8(); uint i = 0; Header * h = Message::parseHeader( i, x.length(), x, Header::Mime ); Bodypart * bp = Bodypart::parseBodypart( i, x.length(), x, h, 0 ); if ( !h->error().isEmpty() ) setError( "While parsing MIME header: " + h->error() ); else if ( !bp->error().isEmpty() ) setError( "While parsing MIME bodypart: " + bp->error() ); List<HeaderField>::Iterator f( h->fields() ); while ( f ) { if ( !f->name().startsWith( "Content-" ) ) setError( "Header field not permitted: " + f->name() ); ++f; } if ( bp->children()->isEmpty() && bp->text().isEmpty() ) setError( "Vacation reply does not contain any text" ); } else { if ( reason.isEmpty() ) setError( "Empty vacation text does not make sense" ); } } else if ( i == "setflag" || i == "addflags" || i == "removeflag" ) { arguments()->numberRemainingArguments(); (void)arguments()->takeStringList( 1 ); } else if ( i == "notify" ) { require( "enotify" ); UString from; if ( arguments()->findTag( ":from" )) from = arguments()->takeTaggedString( ":from" ); UString importance; importance.append( "2" ); if ( arguments()->findTag( ":importance" ) ) importance = arguments()->takeTaggedString( ":from" ); uint c = importance[0]; if ( c < '1' || c > '3' ) arguments()->tagError( ":importance", "Importance must be 1, 2 or 3" ); UStringList * options; if ( arguments()->findTag( ":options" ) ) options = arguments()->takeTaggedStringList( ":options" ); UString message; if ( arguments()->findTag( ":message" ) ) message = arguments()->takeTaggedString( ":message" ); arguments()->numberRemainingArguments(); UString method = arguments()->takeString( 1 ); SieveNotifyMethod * m = new SieveNotifyMethod( method, arguments()->takeArgument( 1 ), this ); if ( m->valid() ) { if ( arguments()->findTag( ":from" ) ) m->setFrom( from, arguments()->findTag( ":from" ) ); if ( arguments()->findTag( ":message" ) ) m->setMessage( message, arguments()->findTag( ":message" ) ); } } else { setError( "Command unknown: " + identifier() ); } arguments()->flagUnparsedAsBad(); if ( test ) { // we must have a test if ( !arguments() || arguments()->tests()->count() != 1 ) setError( "Command " + identifier() + " requires one test" ); if ( arguments() ) { List<SieveTest>::Iterator i( arguments()->tests() ); while ( i ) { i->parse(); if ( blk && block() ) { if ( i->ihaveFailed() ) block()->setIhaveFailed(); else block()->addExtensions( i->addedExtensions() ); } ++i; } } } else { // we cannot have a test if ( arguments() && arguments()->tests()->isEmpty() ) { List<SieveTest>::Iterator i( arguments()->tests() ); while ( i ) { i->setError( "Command " + identifier() + " does not use tests" ); ++i; } } } if ( blk ) { // we must have a subsidiary block if ( !block() ) { setError( "Command " + identifier() + " requires a subsidiary {..} block" ); } else { EString prev; List<SieveCommand>::Iterator i( block()->commands() ); while ( i ) { i->parse( prev ); prev = i->identifier(); ++i; } } } else { // we cannot have a subsidiary block if ( block() ) block()->setError( "Command " + identifier() + " does not use a subsidiary command block" ); // in this case we don't even bother syntax-checking the test // or block } }
/* * Send a rpc command to ABM to obtain the kinematicStructure of part of the body (using the joint info) * Send a rpc command to kinematicStructure if no kinematicStructure were provided * input: joint of the bodypart to be moved (e.g. m_joint_number) + body part type (e.g. left_arm, right_arm, ...) */ Bottle proactiveTagging::assignKinematicStructureByJoint(int BPjoint, std::string sBodyPartType, bool forcingKS) { //1. extract instance from singleJointAction for joint BPjoint, from ABM Bottle bResult, bOutput; ostringstream osRequest; osRequest << "SELECT max(main.instance) FROM main, contentarg WHERE main.instance = contentarg.instance AND activityname = 'singleJointBabbling' AND main.begin = TRUE AND contentarg.role = 'limb' AND contentarg.argument = '" << BPjoint << "' ;"; yInfo() << "assignKinematicStructureByJoint request: " << osRequest.str(); bResult = iCub->getABMClient()->requestFromString(osRequest.str().c_str()); if (bResult.toString() == "NULL") { yError() << " error in proactiveTagging::assignKinematicStructureByJoint | for joint " << BPjoint << " | No instance corresponding to singleJointBabbling for this part" ; bOutput.addString("error"); bOutput.addString("No instance corresponding to singleJointBabbling for this part"); return bOutput; } int ksInstance = atoi(bResult.get(0).asList()->get(0).asString().c_str()); Bottle bResultCheckKS = checkForKinematicStructure(ksInstance, forcingKS); if(bResultCheckKS.get(0).asString() == "error") { return bResultCheckKS; } yInfo() << " [assignKinematicStructureByJoint] | for joint " << BPjoint << " | instance found : " << ksInstance; //WRITE IN OPC iCub->opc->checkout(); list<Entity*> lEntities = iCub->opc->EntitiesCache(); Bottle bListEntChanged; for (auto& entity: lEntities) //go through all entity { yInfo() << "Checking if entity " << entity->name() << " has entitytype = bodypart : ----> " << entity->entity_type() ; if (entity->entity_type() == "bodypart") //check bodypart entity { //pb with the casting: BPtemp is empty Bodypart* BPtemp = dynamic_cast<Bodypart*>(entity); if(!BPtemp) { yDebug() << "Could not cast " << entity->name() << " to Bodypart"; continue; } if(BPtemp->m_joint_number == BPjoint) { //if corresponding joint : change it //BPtemp->m_kinStruct_instance = ksInstance; bListEntChanged.addString(BPtemp->name()); yInfo() << "Change" << BPtemp->name() << "to kinematic instance" << ksInstance; iCub->opc->commit(BPtemp); break; } } } yInfo() << "Out of the loop for checking entity in OPC, number of entityChanged : " << bListEntChanged.size() ; if(bListEntChanged.isNull()){ yWarning() << "assignKinematicStructureByJoint | for joint " << BPjoint << " | no bodypart has been found with this joint!"; bOutput.addString("warning"); bOutput.addString("no bodypart has been found with this joint!"); return bOutput; } bOutput.addString("ack"); bOutput.addInt(ksInstance); bOutput.addList() = bListEntChanged; return bOutput; }
/* * Explore an unknown tactile entity (e.g. fingertips), when knowing the name * @param: Bottle with (exploreTactileUnknownEntity entityType entityName) (eg: exploreUnknownEntity agent unknown_25) * @return Bottle with the result (error or ack?) */ yarp::os::Bottle proactiveTagging::exploreTactileEntityWithName(Bottle bInput) { Bottle bOutput; if (bInput.size() != 3) { yInfo() << " proactiveTagging::exploreTactileEntityWithName | Problem in input size."; bOutput.addString("Problem in input size"); iCub->say("Error in input size explore tactile with name"); return bOutput; } string sBodyPart = bInput.get(1).toString(); string sName = bInput.get(2).toString(); yInfo() << " EntityType : " << sBodyPart; //1. search through opc for the bodypart entity iCub->opc->checkout(); Bodypart* BPentity = dynamic_cast<Bodypart*>(iCub->opc->getEntity(sName, true)); if(!BPentity) { iCub->say("Could not cast to bodypart in tactile"); yError() << "Could not cast to bodypart in tactile"; bOutput.addString("nack"); return bOutput; } //2.Ask human to touch string sAsking = "I know how to move my " + sName + ", but how does it feel when I touch something? Can you touch my " + sName + " when I move it, please?"; yInfo() << " sAsking: " << sAsking; iCub->lookAtPartner(); iCub->say(sAsking, false); portFromTouchDetector.read(false); // clear buffer from previous readings //2.b Move also the bodypart to show it has been learnt. yInfo() << "Cast okay : name BP = " << BPentity->name(); int joint = BPentity->m_joint_number; //send rpc command to bodySchema to move the corresponding part yInfo() << "Start bodySchema"; double babbling_duration = 3.0; iCub->babbling(joint, babblingArm, babbling_duration); //3. Read until some tactile value are detected //TODO: Here, instead we should check the saliency given by pasar! bool gotTouch = false; Bottle *bTactile; int timeout = 0; while(!gotTouch && timeout<10) { bTactile = portFromTouchDetector.read(false); if(bTactile != NULL) { gotTouch = true; break; } else { yarp::os::Time::delay(0.5); timeout++; } } if(!gotTouch) { yError() << " error in proactiveTagging::exploreTactileEntityWithName | for " << sName << " | Touch not detected!" ; bOutput.addString("error"); bOutput.addString("I did not feel any touch."); iCub->say("I did not feel any touch."); iCub->home(); return bOutput; } //4. Assign m_tactile_number BPentity->m_tactile_number = bTactile->get(0).asInt(); bOutput.addString("ack"); bOutput.addInt(bTactile->get(0).asInt()); yDebug() << "Assigned" << BPentity->name() << "(id)" << BPentity->opc_id() << "tactile_number to" << bTactile->get(0).asInt(); iCub->opc->commit(BPentity); //4.Ask human to touch string sThank = " Thank you, now I know when I am touching object with my " + sName; yInfo() << " sThank: " << sThank; iCub->lookAtPartner(); iCub->say(sThank); iCub->home(); return bOutput; }
Injectee * DSN::result() const { Injectee * r = new Injectee; Bodypart * plainText = new Bodypart( 1, r ); Bodypart * dsn = new Bodypart( 2, r ); Bodypart * original = new Bodypart( 3, r ); plainText->setParent( r ); dsn->setParent( r ); original->setParent( r ); r->children()->append( plainText ); r->children()->append( dsn ); r->children()->append( original ); // set up the original message, either full or header-only if ( fullReport() ) { original->header()->add( "Content-Type", "text/rfc822-headers" ); original->setData( message()->header()->asText() ); // this is what we _should_ do, except that we don't. the body // of the message is lost, probably because original-> has a // null parent. //original->header()->add( "Content-Type", "message/rfc822" ); //original->setMessage( message() ); // and maybe we shouldn't anyway. sending a potentially big // body in a bounce is not necessarily a good idea. } else { // nasty mime name there original->header()->add( "Content-Type", "text/rfc822-headers" ); original->setData( message()->header()->asText() ); } // the from field has to contain... what? let's try this for now. Address * from = new Address( Configuration::hostname(), "postmaster", Configuration::hostname() ); // set up the top-level header Header * h = r->header(); if ( resultDate() ) { h->add( "Date", resultDate()->rfc822() ); } else { Date * now = new Date; now->setCurrentTime(); h->add( "Date", now->rfc822() ); } h->add( "From", from->toString() ); if ( sender() ) h->add( "To", sender()->toString() ); if ( allOk() ) h->add( "Subject", "Message delivered" ); else if ( allFailed() ) h->add( "Subject", "Message delivery failed" ); else h->add( "Subject", "Message delivery reports" ); h->add( "Mime-Version", "1.0" ); h->add( "Content-Type", "multipart/report; boundary=" + Message::acceptableBoundary( message()->rfc822() ) ); // set up the plaintext and DSN parts // what charset should we use for plainText? plainText->header()->add( "Content-Type", "text/plain; format=flowed" ); dsn->header()->add( "Content-Type", "message/delivery-status" ); plainText->setData( plainBody() ); dsn->setData( dsnBody() ); r->addMessageId(); return r; }