void scroller::dragger_area(int &x1, int &y1, int &x2, int &y2) { if (vert) { x1 = x + l; y1 = y + bh(); x2 = x + l + bw() - 1; y2 = y + h - bh() - 1; } else { x1 = x + bw(); y1 = y + h; x2 = x + l - bw(); y2 = y + h + bh() - 1; } }
bool BackendHelper::DumpAllRegisters(const QString& filename) { FileIoBackend b(filename, QString::fromStdString(m_soc.GetSoc().name)); BackendHelper bh(&b, m_soc); for(size_t i = 0; i < m_soc.GetSoc().dev.size(); i++) { const soc_dev_t& dev = m_soc.GetSoc().dev[i]; for(size_t j = 0; j < dev.addr.size(); j++) { QString devname = QString::fromStdString(dev.addr[j].name); for(size_t k = 0; k < dev.reg.size(); k++) { const soc_reg_t& reg = dev.reg[k]; for(size_t l = 0; l < reg.addr.size(); l++) { QString regname = QString::fromStdString(reg.addr[l].name); soc_word_t val; if(!ReadRegister(devname, regname, val)) return false; if(!bh.WriteRegister(devname, regname, val)) return false; } } } } return b.Commit(); }
bool GCache::discard_seqno (int64_t seqno) { // seqno = std::min(seqno, seqno_released); for (seqno2ptr_t::iterator i = seqno2ptr.begin(); i != seqno2ptr.end() && i->first <= seqno;) { seqno2ptr_t::iterator j(i); ++i; BufferHeader* bh(ptr2BH (j->second)); if (gu_likely(BH_is_released(bh))) { assert (bh->seqno_g <= seqno); seqno2ptr.erase (j); bh->seqno_g = SEQNO_ILL; // will never be reused switch (bh->store) { case BUFFER_IN_MEM: mem.discard (bh); break; case BUFFER_IN_RB: rb.discard (bh); break; case BUFFER_IN_PAGE: ps.discard (bh); break; default: log_fatal << "Corrupt buffer header: " << bh; abort(); } } else { return false; } } return true; }
int scroller::mouse_to_drag(int mx, int my) { int x1, y1, x2, y2; dragger_area(x1, y1, x2, y2); if (vert) { int h = (y2 - y1 + 1 - bh()); if (h) return (my - y - bh() - bh() / 2) * (t - 1) / h; else return 0; } else { int w = (x2 - x1 + 1 - bw()); if (w) return (mx - x - bw() - bw() / 2) * (t - 1) / w; else return 0; } }
void scroller::draw_first(image *screen) { if (sx >= t) sx = t - 1; draw(0, screen); screen->widget_bar(b1x(), b1y(), b1x() + bw() - 1, b1y() + bh() - 1, wm->bright_color(), wm->medium_color(), wm->dark_color()); screen->widget_bar(b2x(), b2y(), b2x() + bw() - 1, b2y() + bh() - 1, wm->bright_color(), wm->medium_color(), wm->dark_color()); show_icon(screen, b1x() + 2, b1y() + 2, bw() - 4, bh() - 4, b1()); show_icon(screen, b2x() + 2, b2y() + 2, bw() - 4, bh() - 4, b2()); int x1, y1, x2, y2; dragger_area(x1, y1, x2, y2); screen->bar(x1, y1, x2, y2, wm->black()); screen->bar(x1 + 1, y1 + 1, x2 - 1, y2 - 1, wm->medium_color()); draw_widget(screen, 0); scroll_event(sx, screen); }
void scroller::area(int &x1, int &y1, int &x2, int &y2) { area_config(); x1=m_pos.x-1; y1=m_pos.y-1; if (vert) { x2=m_pos.x+l+bw(); y2=m_pos.y+h; } else { x2=m_pos.x+l; y2=m_pos.y+h+bh(); } }
GfVec4f GfHomogeneousCross(const GfVec4f &a, const GfVec4f &b) { GfVec4f ah(GfGetHomogenized(a)); GfVec4f bh(GfGetHomogenized(b)); GfVec3f prod = GfCross(GfVec3f(ah[0], ah[1], ah[2]), GfVec3f(bh[0], bh[1], bh[2])); return GfVec4f(prod[0], prod[1], prod[2], 1); }
GfVec4d GfHomogeneousCross(const GfVec4d &a, const GfVec4d &b) { GfVec4d ah(GfGetHomogenized(a)); GfVec4d bh(GfGetHomogenized(b)); GfVec3d prod = GfCross(GfVec3d(ah[0], ah[1], ah[2]), GfVec3d(bh[0], bh[1], bh[2])); return GfVec4d(prod[0], prod[1], prod[2], 1); }
void scroller::wig_area(int &x1, int &y1, int &x2, int &y2) { int sx1, sy1, sx2, sy2; dragger_area(sx1, sy1, sx2, sy2); if (vert) { x1 = x + l + 1; if (t < 2) y1 = y + bh() + 1; else y1 = y + bh() + 1 + sx * (sy2 - sy1 + 1 - bh()) / (t - 1); } else { if (t < 2) x1 = x + bw() + 1; else x1 = x + bw() + 1 + sx * (sx2 - sx1 + 1 - bw()) / (t - 1); y1 = y + h + 1; } x2 = x1 + bw() - 3; y2 = y1 + bh() - 3; }
typename Foam::BlockSolverPerformance<Type> Foam::BlockGMRESSolver<Type>::solve ( Field<Type>& x, const Field<Type>& b ) { // Create local references to avoid the spread this-> ugliness const BlockLduMatrix<Type>& matrix = this->matrix_; // Prepare solver performance BlockSolverPerformance<Type> solverPerf ( typeName, this->fieldName() ); scalar norm = this->normFactor(x, b); // Multiplication helper typename BlockCoeff<Type>::multiply mult; Field<Type> wA(x.size()); // Calculate initial residual matrix.Amul(wA, x); Field<Type> rA(b - wA); solverPerf.initialResidual() = gSum(cmptMag(rA))/norm; solverPerf.finalResidual() = solverPerf.initialResidual(); // Check convergence, solve if not converged if (!solverPerf.checkConvergence(this->tolerance(), this->relTolerance())) { // Create the Hesenberg matrix scalarSquareMatrix H(nDirs_, 0); // Create y and b for Hessenberg matrix scalarField yh(nDirs_, 0); scalarField bh(nDirs_ + 1, 0); // Givens rotation vectors scalarField c(nDirs_, 0); scalarField s(nDirs_, 0); // Allocate Krylov space vectors FieldField<Field, Type> V(nDirs_ + 1); forAll (V, i) { V.set(i, new Field<Type>(x.size(), pTraits<Type>::zero)); }
int main() { bh(); void *av = i(); cp->b = av; bb(cm); cn = cu(cm); if (cn) { printf("mpz_lucnum_ui0 wrong\n"); abort(); } exit(0); }
int AbstractStatement::exec(AbstractQoreNode **return_value, ExceptionSink *xsink) { printd(1, "AbstractStatement::exec() this: %p file: %s line: %d\n", this, loc.file, loc.start_line); QoreProgramLocationHelper l(loc); #ifdef QORE_MANAGE_STACK if (check_stack(xsink)) return 0; #endif pthread_testcancel(); QoreProgramBlockParseOptionHelper bh(pwo.parse_options); return execImpl(return_value, xsink); }
char * aes64encrypt(char *in) { if(setkey == 0) { aes_set_key( &ctx, key, KEYLEN); setkey=1;} unsigned char iv[16]; memcpy(iv,iv_key,16); len=aes_cbc_encrypt(&ctx,iv,(unsigned char*)in,(unsigned char*)out,len); bh(); printf("%s\n\n",out); snprintf(out,BLOCK,"%s",base64); return out; }
BinaryNode *SSH2Channel::readBinary(qore_size_t size, int stream_id, int timeout_ms, ExceptionSink *xsink) { AutoLocker al(parent->m); if (check_open(xsink)) return 0; SimpleRefHolder<BinaryNode> bin(new BinaryNode); BlockingHelper bh(parent); qore_offset_t rc; // bytes read qore_size_t b_read = 0; // bytes remaining qore_size_t b_remaining = size; while (true) { char buffer[QSSH2_BUFSIZE]; qore_size_t to_read = QSSH2_BUFSIZE < b_remaining ? QSSH2_BUFSIZE : b_remaining; rc = libssh2_channel_read_ex(channel, stream_id, buffer, to_read); //printd(5, "SSH2Channel::read() rc=%lld (EAGAIN=%d)\n", rc, LIBSSH2_ERROR_EAGAIN); if (rc > 0) { bin->append(buffer, rc); b_read += rc; b_remaining -= rc; if (b_read >= size) break; continue; } if (!rc || rc == LIBSSH2_ERROR_EAGAIN) { rc = parent->waitSocketUnlocked(timeout_ms); if (!rc) { xsink->raiseException(SSH2CHANNEL_TIMEOUT, "read timeout after %dms reading %lld byte%s of %lld requested", timeout_ms, b_read, b_read == 1 ? "" : "s", size); return 0; } if (rc < 0) { xsink->raiseException(SSH2CHANNEL_TIMEOUT, strerror(errno)); return 0; } } } if (rc < 0 && rc != LIBSSH2_ERROR_EAGAIN) { parent->doSessionErrUnlocked(xsink); return 0; } return bin.release(); }
void graph::dijkstra ( string source ) { //intialize binary heap heap bh ( this->vertexList.size() + 1 ); list <vertex * > :: iterator a; //initialize all nodes; for( a = this->vertexList.begin(); a != this->vertexList.end(); a++ ) { if( (*a)->name == source ) { (*a)->distance = 0; } else { (*a)->distance = INT_MAX; } (*a)->known = false; (*a)->prev = NULL; bh.insert( (*a)->name, (*a)->distance, (*a) ); } vertex * d; while( bh.deleteMin( NULL, NULL, &d ) != 1 ) { d->known = true; if( d->distance == INT_MAX ) // No path to vertex continue; list < edge * > :: iterator b; int cost; for ( b = d->adjacent.begin(); b!= d->adjacent.end(); b++ ) { cost = d->distance + (*b)->cost; if( cost < (*b)->destination->distance ) { // If cost is better than best cost so far (*b)->destination->distance = cost; // Update cost in vertex bh.setKey( (*b)->destination->name, cost ); // Update cost in heap to percolate (*b)->destination->prev = d; // Best known vertex } } } return; }
qore_size_t SSH2Channel::write(ExceptionSink *xsink, const void *buf, qore_size_t buflen, int stream_id, int timeout_ms) { assert(buflen); AutoLocker al(parent->m); if (check_open(xsink)) return -1; BlockingHelper bh(parent); qore_size_t b_sent = 0; while (true) { qore_offset_t rc; while (true) { rc = libssh2_channel_write_ex(channel, stream_id, (char *)buf + b_sent, buflen - b_sent); //printd(5, "SSH2Channel::write(len=%lu) buf=%p buflen=%lu stream_id=%d timeout_ms=%d rc=%ld b_sent=%lu\n", buflen - b_sent, buf, buflen, stream_id, timeout_ms, rc, b_sent); if (rc && rc != LIBSSH2_ERROR_EAGAIN) break; rc = parent->waitSocketUnlocked(timeout_ms); if (!rc) { xsink->raiseException(SSH2CHANNEL_TIMEOUT, "write timeout after %dms writing %lu byte%s of %lu", timeout_ms, b_sent, b_sent == 1 ? "" : "s", buflen); return -1; } if (rc < 0) { xsink->raiseException("SSH2CHANNEL-WRITE-ERROR", strerror(errno)); return -1; } } if (rc < 0) parent->doSessionErrUnlocked(xsink); b_sent += rc; if (b_sent >= buflen) break; } return b_sent; }
int SSH2Channel::setenv(const char *name, const char *value, int timeout_ms, ExceptionSink *xsink) { AutoLocker al(parent->m); if (check_open(xsink)) return -1; BlockingHelper bh(parent); int rc; while (true) { rc = libssh2_channel_setenv(channel, (char *)name, value); if (rc == LIBSSH2_ERROR_EAGAIN) { if ((rc = parent->waitSocketUnlocked(xsink, SSH2CHANNEL_TIMEOUT, "SSH2CHANNEL-SETENV-ERROR", "SSH2Channel::setenv", timeout_ms))) break; continue; } if (rc) parent->doSessionErrUnlocked(xsink); break; } return rc; }
int SSH2Channel::shell(ExceptionSink *xsink, int timeout_ms) { AutoLocker al(parent->m); if (check_open(xsink)) return -1; BlockingHelper bh(parent); int rc; while (true) { rc = libssh2_channel_shell(channel); if (rc == LIBSSH2_ERROR_EAGAIN) { if ((rc = parent->waitSocketUnlocked(xsink, SSH2CHANNEL_TIMEOUT, "SSH2CHANNEL-SHELL-ERROR", "SSH2Channel::shell", timeout_ms))) break; continue; } if (rc) parent->doSessionErrUnlocked(xsink); break; } return rc; }
int SSH2Channel::requestPty(ExceptionSink *xsink, const QoreString &term, const QoreString &modes, int width, int height, int width_px, int height_px, int timeout_ms) { AutoLocker al(parent->m); if (check_open(xsink)) return -1; BlockingHelper bh(parent); int rc; while (true) { rc = libssh2_channel_request_pty_ex(channel, term.getBuffer(), term.strlen(), modes.strlen() ? modes.getBuffer() : 0, modes.strlen(), width, height, width_px, height_px); if (rc == LIBSSH2_ERROR_EAGAIN) { if ((rc = parent->waitSocketUnlocked(xsink, SSH2CHANNEL_TIMEOUT, "SSH2CHANNEL-REQUESTPTY-ERROR", "SSH2Channel::requestPty", timeout_ms))) break; continue; } if (rc) parent->doSessionErrUnlocked(xsink); break; } return rc; }
int SSH2Channel::requestX11Forwarding(ExceptionSink *xsink, int screen_number, bool single_connection, const char *auth_proto, const char *auth_cookie, int timeout_ms) { AutoLocker al(parent->m); if (check_open(xsink)) return -1; BlockingHelper bh(parent); //printd(5, "SSH2Channel::requestX11Forwarding() screen_no=%d, single=%s, ap=%s, ac=%s\n", screen_number, single_connection ? "true" : "false", auth_proto ? auth_proto : "n/a", auth_cookie ? auth_cookie : "n/a"); int rc; while (true) { rc = libssh2_channel_x11_req_ex(channel, (int)single_connection, auth_proto, auth_cookie, screen_number); if (rc == LIBSSH2_ERROR_EAGAIN) { if ((rc = parent->waitSocketUnlocked(xsink, SSH2CHANNEL_TIMEOUT, "SSH2CHANNEL-REQUESTX11FORWARDING-ERROR", "SSH2Channel::requestX11Forwarding", timeout_ms))) break; continue; } if (rc < 0) parent->doSessionErrUnlocked(xsink); break; } return rc; }
int SSH2Channel::subsystem(const char *command, int timeout_ms, ExceptionSink *xsink) { AutoLocker al(parent->m); if (check_open(xsink)) return -1; BlockingHelper bh(parent); int rc; while (true) { rc = libssh2_channel_subsystem(channel, command); //printd(5, "SSH2Channel::subsystem() cmd=%s rc=%d\n", command, rc); if (rc == LIBSSH2_ERROR_EAGAIN) { if ((rc = parent->waitSocketUnlocked(xsink, SSH2CHANNEL_TIMEOUT, "SSH2CHANNEL-SUBSYSTEM-ERROR", "SSH2Channel::subsystem", timeout_ms))) break; continue; } if (rc) parent->doSessionErrUnlocked(xsink); break; } return rc; }
void* realloc (void* ptr, ssize_t size) { BufferHeader* bh(0); ssize_t old_size(0); if (ptr) { bh = ptr2BH(ptr); assert (SEQNO_NONE == bh->seqno_g); old_size = bh->size; } ssize_t const diff_size(size - old_size); if (size > max_size_ || have_free_space(diff_size) == false) return 0; assert (size_ + diff_size <= max_size_); void* tmp = ::realloc (bh, size); if (tmp) { allocd_.erase(bh); allocd_.insert(tmp); bh = BH_cast(tmp); assert (bh->size == old_size); bh->size = size; size_ += diff_size; return (bh + 1); } return 0; }
QoreStringNode *SSH2Channel::read(ExceptionSink *xsink, int stream_id, int timeout_ms) { AutoLocker al(parent->m); if (check_open(xsink)) return 0; QoreStringNodeHolder str(new QoreStringNode(enc)); BlockingHelper bh(parent); qore_offset_t rc; bool first = true; do { loop0: char buffer[QSSH2_BUFSIZE]; rc = libssh2_channel_read_ex(channel, stream_id, buffer, QSSH2_BUFSIZE); //printd(0, "SSH2Channel::read() rc=%ld (EAGAIN=%d)\n", rc, LIBSSH2_ERROR_EAGAIN); if (rc > 0) { str->concat(buffer, rc); } else if (rc == LIBSSH2_ERROR_EAGAIN && !str->strlen() && first) { first = false; if ((rc = parent->waitSocketUnlocked(xsink, SSH2CHANNEL_TIMEOUT, "SSH2CHANNEL-READ-ERROR", "SSH2Channel::read", timeout_ms))) return 0; goto loop0; } } while (rc > 0); if (rc < 0 && rc != LIBSSH2_ERROR_EAGAIN) { parent->doSessionErrUnlocked(xsink); return 0; } return str.release(); }
BinaryNode *SSH2Channel::readBinary(ExceptionSink *xsink, int stream_id, int timeout_ms) { AutoLocker al(parent->m); if (check_open(xsink)) return 0; SimpleRefHolder<BinaryNode> bin(new BinaryNode); BlockingHelper bh(parent); qore_offset_t rc; bool first = true; do { loop0: char buffer[QSSH2_BUFSIZE]; rc = libssh2_channel_read_ex(channel, stream_id, buffer, QSSH2_BUFSIZE); //printd(5, "SSH2Channel::readBinary() rc=%ld (EAGAIN=%d)\n", rc, LIBSSH2_ERROR_EAGAIN); if (rc > 0) { bin->append(buffer, rc); } else if (rc == LIBSSH2_ERROR_EAGAIN && !bin->size() && first) { first = false; if ((rc = parent->waitSocketUnlocked(xsink, SSH2CHANNEL_TIMEOUT, "SSH2CHANNEL-READBINARY-ERROR", "SSH2Channel::readBinary", timeout_ms))) return 0; goto loop0; } } while (rc > 0); if (rc < 0 && rc != LIBSSH2_ERROR_EAGAIN) { parent->doSessionErrUnlocked(xsink); return 0; } return bin.release(); }
OutputInfo RBM::initialize(std::vector<double*>& parameterPointers, std::vector<double*>& parameterDerivativePointers) { if(backprop) { for(int j = 0; j < H; j++) { for(int i = 0; i < D; i++) { parameterPointers.push_back(&W(j, i)); parameterDerivativePointers.push_back(&Wd(j, i)); } } for(int j = 0; j < H; j++) { parameterPointers.push_back(&bh(j)); parameterDerivativePointers.push_back(&bhd(j)); } } OutputInfo info; info.dimensions.push_back(H); return info; }
void RingBuffer::seqno_reset() { if (size_cache_ == size_free_) return; /* Find the last seqno'd RB buffer. It is likely to be close to the * end of released buffers chain. */ BufferHeader* bh(0); for (seqno2ptr_t::reverse_iterator r(seqno2ptr_.rbegin()); r != seqno2ptr_.rend(); ++r) { BufferHeader* const b(ptr2BH(r->second)); if (BUFFER_IN_RB == b->store) { #ifndef NDEBUG if (!BH_is_released(b)) { log_fatal << "Buffer " << reinterpret_cast<const void*>(r->second) << ", seqno_g " << b->seqno_g << ", seqno_d " << b->seqno_d << " is not released."; assert(0); } #endif bh = b; break; } } if (!bh) return; assert(bh->size > 0); assert(BH_is_released(bh)); /* Seek the first unreleased buffer. * This should be called in isolation, when all seqno'd buffers are * freed, and the only unreleased buffers should come only from new * configuration. There should be no seqno'd buffers after it. */ ssize_t const old(size_free_); assert (0 == size_trail_ || first_ > next_); first_ = reinterpret_cast<uint8_t*>(bh); while (BH_is_released(bh)) // next_ is never released - no endless loop { first_ = reinterpret_cast<uint8_t*>(BH_next(bh)); if (gu_unlikely (0 == bh->size && first_ != next_)) { // rollover assert (first_ > next_); first_ = start_; } bh = BH_cast(first_); } BH_assert_clear(BH_cast(next_)); if (first_ == next_) { log_info << "GCache DEBUG: RingBuffer::seqno_reset(): full reset"; /* empty RB, reset it completely */ reset(); return; } assert ((BH_cast(first_))->size > 0); assert (first_ != next_); assert ((BH_cast(first_))->seqno_g == SEQNO_NONE); assert (!BH_is_released(BH_cast(first_))); /* Estimate how much space remains */ if (first_ < next_) { /* start_ first_ next_ end_ * | |###########| | */ size_used_ = next_ - first_; size_free_ = size_cache_ - size_used_; size_trail_ = 0; } else { /* start_ next_ first_ end_ * |#######| |#####| | * ^size_trail_ */ assert(size_trail_ > 0); size_free_ = first_ - next_ + size_trail_ - sizeof(BufferHeader); size_used_ = size_cache_ - size_free_; } assert_sizes(); assert(size_free_ < size_cache_); log_info << "GCache DEBUG: RingBuffer::seqno_reset(): discarded " << (size_free_ - old) << " bytes"; /* There is a small but non-0 probability that some released buffers * are locked within yet unreleased aborted local actions. * Seek all the way to next_, invalidate seqnos and update size_free_ */ assert(first_ != next_); assert(bh == BH_cast(first_)); long total(1); long locked(0); bh = BH_next(bh); while (bh != BH_cast(next_)) { if (gu_likely (bh->size > 0)) { total++; if (bh->seqno_g != SEQNO_NONE) { // either released or already discarded buffer assert (BH_is_released(bh)); bh->seqno_g = SEQNO_ILL; discard (bh); locked++; } else { assert(!BH_is_released(bh)); } bh = BH_next(bh); } else // rollover { assert (BH_cast(next_) < bh); bh = BH_cast(start_); } } log_info << "GCache DEBUG: RingBuffer::seqno_reset(): found " << locked << '/' << total << " locked buffers"; assert_sizes(); }
void scroller::handle_event(Event &ev, image *screen, InputManager *inm) { int mx=ev.mouse_move.x,my=ev.mouse_move.y; switch (ev.type) { case EV_MOUSE_BUTTON : { if (ev.mouse_button && drag==-1) { if (mx>=b1x() && mx<b1x()+bw() && my>=b1y()-2 && my<b1y()+bh()) { if (sx>0) { draw_widget(screen,1); sx--; draw_widget(screen,0); scroll_event(sx,screen); } } else if (mx>=b2x() && mx<b2x()+bw() && my>=b2y() && my<=b2y()+bh()) { if (sx<t-1) { draw_widget(screen,1); sx++; draw_widget(screen,0); scroll_event(sx,screen); } } else { int dx1,dy1,dx2,dy2; dragger_area(dx1,dy1,dx2,dy2); if (mx>=dx1 && mx<=dx2 && my>=dy1 && my<=dy2) { int x1,y1,x2,y2; wig_area(x1,y1,x2,y2); if (mx>=x1 && mx<=x2 && my>=y1 && my<=y2) { drag=sx; inm->grab_focus(this); } else if (t>1) { int nx=mouse_to_drag(mx,my); if (nx!=sx && nx>=0 && nx<t) { draw_widget(screen,1); sx=nx; draw_widget(screen,0); scroll_event(sx,screen); } } } else handle_inside_event(ev,screen,inm); } } else if (!ev.mouse_button && drag!=-1) { inm->release_focus(); drag=-1; } } break; case EV_MOUSE_MOVE : { if (drag!=-1) { int nx=mouse_to_drag(mx,my); if (nx<0) nx=0; else if (nx>=t) nx=t-1; if (nx!=sx) { draw_widget(screen,1); sx=nx; draw_widget(screen,0); scroll_event(sx,screen); } } else if ( activate_on_mouse_move()) { int x1,y1,x2,y2; wig_area(x1,y1,x2,y2); if (mx>=m_pos.x && mx<=m_pos.x+l-1 && my>=m_pos.y && my<=m_pos.y+h-1) handle_inside_event(ev,screen,inm); } } break; case EV_KEY : { switch (ev.key) { case JK_LEFT : { handle_left(screen,inm); } break; case JK_RIGHT : { handle_right(screen,inm); } break; case JK_UP : { handle_up(screen,inm); } break; case JK_DOWN : { handle_down(screen,inm); } break; default : handle_inside_event(ev,screen,inm); } } break; } }
int main(int argc, char** argv) { const double PI(3.141592653589793); if (argc != 4) { std::cout << "usage:" << std::endl; std::cout << "package_scene path_scene output" << std::endl; return 0; } ros::init(argc, argv, "dart_test"); ros::NodeHandle nh_; std::string package_name( argv[1] ); std::string scene_urdf( argv[2] ); ros::Rate loop_rate(400); ros::Publisher joint_state_pub_; joint_state_pub_ = nh_.advertise<sensor_msgs::JointState>("/joint_states", 10); tf::TransformBroadcaster br; MarkerPublisher markers_pub(nh_); std::string package_path_barrett = ros::package::getPath("barrett_hand_defs"); std::string package_path = ros::package::getPath(package_name); // Load the Skeleton from a file dart::utils::DartLoader loader; loader.addPackageDirectory("barrett_hand_defs", package_path_barrett); loader.addPackageDirectory("barrett_hand_sim_dart", package_path); boost::shared_ptr<GraspSpecification > gspec = GraspSpecification::readFromUrdf(package_path + scene_urdf); dart::dynamics::SkeletonPtr scene( loader.parseSkeleton(package_path + scene_urdf) ); scene->enableSelfCollision(true); dart::dynamics::SkeletonPtr bh( loader.parseSkeleton(package_path_barrett + "/robots/barrett_hand.urdf") ); Eigen::Isometry3d tf; tf = scene->getBodyNode("gripper_mount_link")->getRelativeTransform(); bh->getJoint(0)->setTransformFromParentBodyNode(tf); dart::simulation::World* world = new dart::simulation::World(); world->addSkeleton(scene); world->addSkeleton(bh); Eigen::Vector3d grav(0,0,-1); world->setGravity(grav); GripperController gc; double Kc = 400.0; double KcDivTi = Kc / 1.0; gc.addJoint("right_HandFingerOneKnuckleOneJoint", Kc, KcDivTi, 0.0, 0.001, 50.0, true, false); gc.addJoint("right_HandFingerOneKnuckleTwoJoint", Kc, KcDivTi, 0.0, 0.001, 50.0, false, true); gc.addJoint("right_HandFingerTwoKnuckleTwoJoint", Kc, KcDivTi, 0.0, 0.001, 50.0, false, true); gc.addJoint("right_HandFingerThreeKnuckleTwoJoint", Kc, KcDivTi, 0.0, 0.001, 50.0, false, true); gc.addJointMimic("right_HandFingerTwoKnuckleOneJoint", 2.0*Kc, KcDivTi, 0.0, 0.001, 50.0, true, "right_HandFingerOneKnuckleOneJoint", 1.0, 0.0); gc.addJointMimic("right_HandFingerOneKnuckleThreeJoint", 2.0*Kc, KcDivTi, 0.0, 0.001, 50.0, false, "right_HandFingerOneKnuckleTwoJoint", 0.333333, 0.0); gc.addJointMimic("right_HandFingerTwoKnuckleThreeJoint", 2.0*Kc, KcDivTi, 0.0, 0.001, 50.0, false, "right_HandFingerTwoKnuckleTwoJoint", 0.333333, 0.0); gc.addJointMimic("right_HandFingerThreeKnuckleThreeJoint", 2.0*Kc, KcDivTi, 0.0, 0.001, 50.0, false, "right_HandFingerThreeKnuckleTwoJoint", 0.333333, 0.0); gc.setGoalPosition("right_HandFingerOneKnuckleOneJoint", gspec->getGoalPosition("right_HandFingerOneKnuckleOneJoint")); gc.setGoalPosition("right_HandFingerOneKnuckleTwoJoint", gspec->getGoalPosition("right_HandFingerOneKnuckleTwoJoint")); gc.setGoalPosition("right_HandFingerTwoKnuckleTwoJoint", gspec->getGoalPosition("right_HandFingerTwoKnuckleTwoJoint")); gc.setGoalPosition("right_HandFingerThreeKnuckleTwoJoint", gspec->getGoalPosition("right_HandFingerThreeKnuckleTwoJoint")); std::map<std::string, double> joint_q_map; joint_q_map["right_HandFingerOneKnuckleOneJoint"] = gspec->getInitPosition("right_HandFingerOneKnuckleOneJoint"); joint_q_map["right_HandFingerTwoKnuckleOneJoint"] = gspec->getInitPosition("right_HandFingerOneKnuckleOneJoint"); joint_q_map["right_HandFingerOneKnuckleTwoJoint"] = gspec->getInitPosition("right_HandFingerOneKnuckleTwoJoint"); joint_q_map["right_HandFingerOneKnuckleThreeJoint"] = 0.333333 * gspec->getInitPosition("right_HandFingerOneKnuckleTwoJoint"); joint_q_map["right_HandFingerTwoKnuckleTwoJoint"] = gspec->getInitPosition("right_HandFingerTwoKnuckleTwoJoint"); joint_q_map["right_HandFingerTwoKnuckleThreeJoint"] = 0.333333 * gspec->getInitPosition("right_HandFingerTwoKnuckleTwoJoint"); joint_q_map["right_HandFingerThreeKnuckleTwoJoint"] = gspec->getInitPosition("right_HandFingerThreeKnuckleTwoJoint"); joint_q_map["right_HandFingerThreeKnuckleThreeJoint"] = 0.333333 * gspec->getInitPosition("right_HandFingerThreeKnuckleTwoJoint"); for (std::vector<std::string >::const_iterator it = gc.getJointNames().begin(); it != gc.getJointNames().end(); it++) { dart::dynamics::Joint *j = bh->getJoint((*it)); j->setActuatorType(dart::dynamics::Joint::FORCE); j->setPositionLimited(true); j->setPosition(0, joint_q_map[(*it)]); } int counter = 0; while (ros::ok()) { world->step(false); for (std::map<std::string, double>::iterator it = joint_q_map.begin(); it != joint_q_map.end(); it++) { dart::dynamics::Joint *j = bh->getJoint(it->first); it->second = j->getPosition(0); } gc.controlStep(joint_q_map); // Compute the joint forces needed to compensate for Coriolis forces and // gravity const Eigen::VectorXd& Cg = bh->getCoriolisAndGravityForces(); for (std::map<std::string, double>::iterator it = joint_q_map.begin(); it != joint_q_map.end(); it++) { dart::dynamics::Joint *j = bh->getJoint(it->first); int qidx = j->getIndexInSkeleton(0); double u = gc.getControl(it->first); double dq = j->getVelocity(0); if (!gc.isBackdrivable(it->first)) { j->setPositionLowerLimit(0, std::max(j->getPositionLowerLimit(0), it->second-0.01)); } if (gc.isStopped(it->first)) { j->setPositionLowerLimit(0, std::max(j->getPositionLowerLimit(0), it->second-0.01)); j->setPositionUpperLimit(0, std::min(j->getPositionUpperLimit(0), it->second+0.01)); // std::cout << it->first << " " << "stopped" << std::endl; } j->setForce(0, 0.02*(u-dq) + Cg(qidx)); } for (int bidx = 0; bidx < bh->getNumBodyNodes(); bidx++) { dart::dynamics::BodyNode *b = bh->getBodyNode(bidx); const Eigen::Isometry3d &tf = b->getTransform(); KDL::Frame T_W_L; EigenTfToKDL(tf, T_W_L); // std::cout << b->getName() << std::endl; publishTransform(br, T_W_L, b->getName(), "world"); } int m_id = 0; for (int bidx = 0; bidx < scene->getNumBodyNodes(); bidx++) { dart::dynamics::BodyNode *b = scene->getBodyNode(bidx); const Eigen::Isometry3d &tf = b->getTransform(); KDL::Frame T_W_L; EigenTfToKDL(tf, T_W_L); publishTransform(br, T_W_L, b->getName(), "world"); for (int cidx = 0; cidx < b->getNumCollisionShapes(); cidx++) { dart::dynamics::ConstShapePtr sh = b->getCollisionShape(cidx); if (sh->getShapeType() == dart::dynamics::Shape::MESH) { std::shared_ptr<const dart::dynamics::MeshShape > msh = std::static_pointer_cast<const dart::dynamics::MeshShape >(sh); m_id = markers_pub.addMeshMarker(m_id, KDL::Vector(), 0, 1, 0, 1, 1, 1, 1, msh->getMeshUri(), b->getName()); } } } markers_pub.publish(); ros::spinOnce(); loop_rate.sleep(); counter++; if (counter < 3000) { } else if (counter == 3000) { dart::dynamics::Joint::Properties prop = bh->getJoint(0)->getJointProperties(); dart::dynamics::FreeJoint::Properties prop_free; prop_free.mName = prop_free.mName; prop_free.mT_ParentBodyToJoint = prop.mT_ParentBodyToJoint; prop_free.mT_ChildBodyToJoint = prop.mT_ChildBodyToJoint; prop_free.mIsPositionLimited = false; prop_free.mActuatorType = dart::dynamics::Joint::VELOCITY; bh->getRootBodyNode()->changeParentJointType<dart::dynamics::FreeJoint >(prop_free); } else if (counter < 4000) { bh->getDof("Joint_pos_z")->setVelocity(-0.1); } else { break; } } // // generate models // const std::string ob_name( "graspable" ); scene->getBodyNode(ob_name)->setFrictionCoeff(0.001); // calculate point clouds for all links and for the grasped object std::map<std::string, pcl::PointCloud<pcl::PointNormal>::Ptr > point_clouds_map; std::map<std::string, pcl::PointCloud<pcl::PrincipalCurvatures>::Ptr > point_pc_clouds_map; std::map<std::string, KDL::Frame > frames_map; std::map<std::string, boost::shared_ptr<std::vector<KDL::Frame > > > features_map; std::map<std::string, boost::shared_ptr<pcl::VoxelGrid<pcl::PointNormal> > > grids_map; for (int skidx = 0; skidx < world->getNumSkeletons(); skidx++) { dart::dynamics::SkeletonPtr sk = world->getSkeleton(skidx); for (int bidx = 0; bidx < sk->getNumBodyNodes(); bidx++) { dart::dynamics::BodyNode *b = sk->getBodyNode(bidx); const Eigen::Isometry3d &tf = b->getTransform(); const std::string &body_name = b->getName(); if (body_name.find("right_Hand") != 0 && body_name != ob_name) { continue; } KDL::Frame T_W_L; EigenTfToKDL(tf, T_W_L); std::cout << body_name << " " << b->getNumCollisionShapes() << std::endl; for (int cidx = 0; cidx < b->getNumCollisionShapes(); cidx++) { dart::dynamics::ConstShapePtr sh = b->getCollisionShape(cidx); if (sh->getShapeType() == dart::dynamics::Shape::MESH) { std::shared_ptr<const dart::dynamics::MeshShape > msh = std::static_pointer_cast<const dart::dynamics::MeshShape >(sh); std::cout << "mesh path: " << msh->getMeshPath() << std::endl; std::cout << "mesh uri: " << msh->getMeshUri() << std::endl; const Eigen::Isometry3d &tf = sh->getLocalTransform(); KDL::Frame T_L_S; EigenTfToKDL(tf, T_L_S); KDL::Frame T_S_L = T_L_S.Inverse(); const aiScene *sc = msh->getMesh(); if (sc->mNumMeshes != 1) { std::cout << "ERROR: sc->mNumMeshes = " << sc->mNumMeshes << std::endl; } int midx = 0; // std::cout << "v: " << sc->mMeshes[midx]->mNumVertices << " f: " << sc->mMeshes[midx]->mNumFaces << std::endl; pcl::PointCloud<pcl::PointNormal>::Ptr cloud_1 (new pcl::PointCloud<pcl::PointNormal>); uniform_sampling(sc->mMeshes[midx], 1000000, *cloud_1); for (int pidx = 0; pidx < cloud_1->points.size(); pidx++) { KDL::Vector pt_L = T_L_S * KDL::Vector(cloud_1->points[pidx].x, cloud_1->points[pidx].y, cloud_1->points[pidx].z); cloud_1->points[pidx].x = pt_L.x(); cloud_1->points[pidx].y = pt_L.y(); cloud_1->points[pidx].z = pt_L.z(); } // Voxelgrid boost::shared_ptr<pcl::VoxelGrid<pcl::PointNormal> > grid_(new pcl::VoxelGrid<pcl::PointNormal>); pcl::PointCloud<pcl::PointNormal>::Ptr res(new pcl::PointCloud<pcl::PointNormal>); grid_->setDownsampleAllData(true); grid_->setSaveLeafLayout(true); grid_->setInputCloud(cloud_1); grid_->setLeafSize(0.004, 0.004, 0.004); grid_->filter (*res); point_clouds_map[body_name] = res; frames_map[body_name] = T_W_L; grids_map[body_name] = grid_; std::cout << "res->points.size(): " << res->points.size() << std::endl; pcl::search::KdTree<pcl::PointNormal>::Ptr tree (new pcl::search::KdTree<pcl::PointNormal>); // Setup the principal curvatures computation pcl::PrincipalCurvaturesEstimation<pcl::PointNormal, pcl::PointNormal, pcl::PrincipalCurvatures> principalCurvaturesEstimation; // Provide the original point cloud (without normals) principalCurvaturesEstimation.setInputCloud (res); // Provide the point cloud with normals principalCurvaturesEstimation.setInputNormals(res); // Use the same KdTree from the normal estimation principalCurvaturesEstimation.setSearchMethod (tree); principalCurvaturesEstimation.setRadiusSearch(0.02); // Actually compute the principal curvatures pcl::PointCloud<pcl::PrincipalCurvatures>::Ptr principalCurvatures (new pcl::PointCloud<pcl::PrincipalCurvatures> ()); principalCurvaturesEstimation.compute (*principalCurvatures); point_pc_clouds_map[body_name] = principalCurvatures; features_map[body_name].reset( new std::vector<KDL::Frame >(res->points.size()) ); for (int pidx = 0; pidx < res->points.size(); pidx++) { KDL::Vector nx, ny, nz(res->points[pidx].normal[0], res->points[pidx].normal[1], res->points[pidx].normal[2]); if ( std::fabs( principalCurvatures->points[pidx].pc1 - principalCurvatures->points[pidx].pc2 ) > 0.001) { nx = KDL::Vector(principalCurvatures->points[pidx].principal_curvature[0], principalCurvatures->points[pidx].principal_curvature[1], principalCurvatures->points[pidx].principal_curvature[2]); } else { if (std::fabs(nz.z()) < 0.7) { nx = KDL::Vector(0, 0, 1); } else { nx = KDL::Vector(1, 0, 0); } } ny = nz * nx; nx = ny * nz; nx.Normalize(); ny.Normalize(); nz.Normalize(); (*features_map[body_name])[pidx] = KDL::Frame( KDL::Rotation(nx, ny, nz), KDL::Vector(res->points[pidx].x, res->points[pidx].y, res->points[pidx].z) ); } } } } } const double sigma_p = 0.01;//05; const double sigma_q = 10.0/180.0*PI;//100.0; const double sigma_r = 0.2;//05; double sigma_c = 5.0/180.0*PI; int m_id = 101; // generate object model boost::shared_ptr<ObjectModel > om(new ObjectModel); for (int pidx = 0; pidx < point_clouds_map[ob_name]->points.size(); pidx++) { if (point_pc_clouds_map[ob_name]->points[pidx].pc1 > 1.1 * point_pc_clouds_map[ob_name]->points[pidx].pc2) { // e.g. pc1=1, pc2=0 // edge om->addPointFeature((*features_map[ob_name])[pidx] * KDL::Frame(KDL::Rotation::RotZ(PI)), point_pc_clouds_map[ob_name]->points[pidx].pc1, point_pc_clouds_map[ob_name]->points[pidx].pc2); om->addPointFeature((*features_map[ob_name])[pidx], point_pc_clouds_map[ob_name]->points[pidx].pc1, point_pc_clouds_map[ob_name]->points[pidx].pc2); } else { for (double angle = 0.0; angle < 359.0/180.0*PI; angle += 20.0/180.0*PI) { om->addPointFeature((*features_map[ob_name])[pidx] * KDL::Frame(KDL::Rotation::RotZ(angle)), point_pc_clouds_map[ob_name]->points[pidx].pc1, point_pc_clouds_map[ob_name]->points[pidx].pc2); } } } std::cout << "om.getPointFeatures().size(): " << om->getPointFeatures().size() << std::endl; KDL::Frame T_W_O = frames_map[ob_name]; // generate collision model std::map<std::string, std::list<std::pair<int, double> > > link_pt_map; boost::shared_ptr<CollisionModel > cm(new CollisionModel); cm->setSamplerParameters(sigma_p, sigma_q, sigma_r); std::list<std::string > gripper_link_names; for (int bidx = 0; bidx < bh->getNumBodyNodes(); bidx++) { const std::string &link_name = bh->getBodyNode(bidx)->getName(); gripper_link_names.push_back(link_name); } double dist_range = 0.01; for (std::list<std::string >::const_iterator nit = gripper_link_names.begin(); nit != gripper_link_names.end(); nit++) { const std::string &link_name = (*nit); if (point_clouds_map.find( link_name ) == point_clouds_map.end()) { continue; } cm->addLinkContacts(dist_range, link_name, point_clouds_map[link_name], frames_map[link_name], om->getPointFeatures(), T_W_O); } // generate hand configuration model boost::shared_ptr<HandConfigurationModel > hm(new HandConfigurationModel); std::map<std::string, double> joint_q_map_before( joint_q_map ); double angleDiffKnuckleTwo = 15.0/180.0*PI; joint_q_map_before["right_HandFingerOneKnuckleTwoJoint"] -= angleDiffKnuckleTwo; joint_q_map_before["right_HandFingerTwoKnuckleTwoJoint"] -= angleDiffKnuckleTwo; joint_q_map_before["right_HandFingerThreeKnuckleTwoJoint"] -= angleDiffKnuckleTwo; joint_q_map_before["right_HandFingerOneKnuckleThreeJoint"] -= angleDiffKnuckleTwo*0.333333; joint_q_map_before["right_HandFingerTwoKnuckleThreeJoint"] -= angleDiffKnuckleTwo*0.333333; joint_q_map_before["right_HandFingerThreeKnuckleThreeJoint"] -= angleDiffKnuckleTwo*0.333333; hm->generateModel(joint_q_map_before, joint_q_map, 1.0, 10, sigma_c); writeToXml(argv[3], cm, hm); return 0; }
QoreHashNode* qore_httpclient_priv::send_internal(ExceptionSink* xsink, const char* mname, const char* meth, const char* mpath, const QoreHashNode* headers, const void* data, unsigned size, const ResolvedCallReferenceNode* send_callback, bool getbody, QoreHashNode* info, int timeout_ms, const ResolvedCallReferenceNode* recv_callback, QoreObject* obj) { assert(!(data && send_callback)); // check if method is valid method_map_t::const_iterator i = method_map.find(meth); if (i == method_map.end()) { i = additional_methods_map.find(meth); if (i == additional_methods_map.end()) { xsink->raiseException("HTTP-CLIENT-METHOD-ERROR", "HTTP method (%s) not recognized.", meth); return 0; } } // make sure the capitalized version is used meth = i->first.c_str(); bool bodyp = i->second; // use the default timeout value if a zero value is given in the call if (!timeout_ms) timeout_ms = timeout; SafeLocker sl(msock->m); Queue* cb_queue = msock->socket->getQueue(); ReferenceHolder<QoreHashNode> nh(new QoreHashNode, xsink); bool keep_alive = true; bool transfer_encoding = false; if (headers) { ConstHashIterator hi(headers); while (hi.next()) { // if one of the mandatory headers is found, then ignore it strcase_set_t::iterator si = header_ignore.find(hi.getKey()); if (si != header_ignore.end()) continue; // otherwise set the value in the hash const AbstractQoreNode* n = hi.getValue(); if (!is_nothing(n)) { if (!strcasecmp(hi.getKey(), "transfer-encoding")) transfer_encoding = true; nh->setKeyValue(hi.getKey(), n->refSelf(), xsink); if (!strcasecmp(hi.getKey(), "connection") || (proxy_connection.has_url() && !strcasecmp(hi.getKey(), "proxy-connection"))) { const char* conn = get_string_header(xsink, **nh, hi.getKey(), true); if (*xsink) { disconnect_unlocked(); return 0; } if (conn && !strcasecmp(conn, "close")) keep_alive = false; } } } } // add default headers if they weren't overridden for (header_map_t::const_iterator hdri = default_headers.begin(), e = default_headers.end(); hdri != e; ++hdri) { // look in original headers to see if the key was already given if (headers) { bool skip = false; ConstHashIterator hi(headers); while (hi.next()) { if (!strcasecmp(hi.getKey(), hdri->first.c_str())) { skip = true; break; } } if (skip) continue; } // if there is no message body then do not send the "content-type" header if (!data && !send_callback && !strcmp(hdri->first.c_str(), "Content-Type")) continue; nh->setKeyValue(hdri->first.c_str(), new QoreStringNode(hdri->second.c_str()), xsink); } // set Transfer-Encoding: chunked if used with a send callback if (send_callback && !transfer_encoding) nh->setKeyValue("Transfer-Encoding", new QoreStringNode("chunked"), xsink); if (!connection.username.empty()) { // check for "Authorization" header bool auth_found = false; if (headers) { ConstHashIterator hi(headers); while (hi.next()) { if (!strcasecmp(hi.getKey(), "Authorization")) { auth_found = true; break; } } } if (!auth_found) { QoreString tmp; tmp.sprintf("%s:%s", connection.username.c_str(), connection.password.c_str()); QoreStringNode* auth_str = new QoreStringNode("Basic "); auth_str->concatBase64(&tmp); nh->setKeyValue("Authorization", auth_str, xsink); } } // save original HTTP method in case we have to issue a CONNECT request to a proxy for an HTTPS connection const char* meth_orig = meth; bool use_proxy_connect = false; const char* proxy_path = 0; ReferenceHolder<QoreHashNode> proxy_headers(xsink); QoreString hostport; if (!proxy_connected && proxy_connection.has_url()) { // use CONNECT if we need to make an HTTPS connection from the proxy if (!proxy_connection.ssl && connection.ssl) { meth = "CONNECT"; use_proxy_connect = true; hostport.concat(connection.host); if (connection.port) hostport.sprintf(":%d", connection.port); proxy_path = hostport.getBuffer(); proxy_headers = new QoreHashNode; proxy_headers->setKeyValue("Host", new QoreStringNode(hostport), xsink); addProxyAuthorization(headers, **proxy_headers, xsink); } else addProxyAuthorization(headers, **nh, xsink); } bool host_override = headers ? (bool)headers->getKeyValue("Host") : false; int code; ReferenceHolder<QoreHashNode> ans(xsink); int redirect_count = 0; const char* location = 0; // flag for aborted chunked sends bool send_aborted = false; while (true) { // set host field automatically if not overridden if (!host_override) nh->setKeyValue("Host", getHostHeaderValue(), xsink); if (info) { info->setKeyValue("headers", nh->copy(), xsink); if (*xsink) return 0; } //printd(5, "qore_httpclient_priv::send_internal() meth=%s proxy_path=%s mpath=%s upc=%d\n", meth, proxy_path ? proxy_path : "n/a", mpath, use_proxy_connect); // send HTTP message and get response header if (use_proxy_connect) ans = sendMessageAndGetResponse(meth, proxy_path, *(*proxy_headers), 0, 0, 0, info, true, timeout_ms, code, send_aborted, xsink); else ans = sendMessageAndGetResponse(meth, mpath, *(*nh), data, size, send_callback, info, false, timeout_ms, code, send_aborted, xsink); if (!ans) return 0; if (info) { info->setKeyValue("response-headers", ans->refSelf(), xsink); if (*xsink) return 0; } if (code >= 300 && code < 400) { disconnect_unlocked(); host_override = false; const QoreStringNode* mess = reinterpret_cast<QoreStringNode*>(ans->getKeyValue("status_message")); const QoreStringNode* loc = get_string_header_node(xsink, **ans, "location"); if (*xsink) return 0; const char* location = loc && !loc->empty() ? loc->getBuffer() : 0; if (!location) { sl.unlock(); const char* msg = mess ? mess->getBuffer() : "<no message>"; xsink->raiseException("HTTP-CLIENT-REDIRECT-ERROR", "no redirect location given for status code %d: message: '%s'", code, msg); return 0; } if (cb_queue) do_redirect_event(cb_queue, msock->socket->getObjectIDForEvents(), loc, mess); if (++redirect_count > max_redirects) break; if (set_url_unlocked(location, xsink)) { sl.unlock(); const char* msg = mess ? mess->getBuffer() : "<no message>"; xsink->raiseException("HTTP-CLIENT-REDIRECT-ERROR", "exception occurred while setting URL for new location '%s' (code %d: message: '%s')", location, code, msg); return 0; } // set redirect info in info hash if present if (info) { QoreString tmp; tmp.sprintf("redirect-%d", redirect_count); info->setKeyValue(tmp.getBuffer(), loc->refSelf(), xsink); if (*xsink) return 0; tmp.clear(); tmp.sprintf("redirect-message-%d", redirect_count); info->setKeyValue(tmp.getBuffer(), mess ? mess->refSelf() : 0, xsink); } // FIXME: reset send callback and send_aborted here // set mpath to NULL so that the new path will be taken mpath = 0; continue; } else if (use_proxy_connect) { meth = meth_orig; use_proxy_connect = false; proxy_path = 0; if (msock->socket->upgradeClientToSSL(0, 0, xsink)) { disconnect_unlocked(); return 0; } proxy_connected = true; // remove "Proxy-Authorization" header nh->removeKey("Proxy-Authorization", xsink); if (*xsink) return 0; // try again as if we are talking directly to the client continue; } break; } if (code >= 300 && code < 400) { sl.unlock(); const char* mess = get_string_header(xsink, **ans, "status_message"); if (!mess) mess = "<no message>"; if (!location) location = "<no location>"; xsink->raiseException("HTTP-CLIENT-MAXIMUM-REDIRECTS-EXCEEDED", "maximum redirections (%d) exceeded; redirect code %d to '%s' ignored (message: '%s')", max_redirects, code, location, mess); return 0; } // process content-type const QoreStringNode* v = get_string_header_node(xsink, **ans, "content-type"); if (*xsink) { disconnect_unlocked(); return 0; } //ans->getKeyValue("content-type"); // see if there is a character set specification in the content-type header if (v) { // save original content-type header before processing ans->setKeyValue("_qore_orig_content_type", v->refSelf(), xsink); const char* str = v->getBuffer(); const char* p = strstr(str, "charset="); if (p && (p == str || *(p - 1) == ';' || *(p - 1) == ' ')) { // move p to start of encoding const char* c = p + 8; char quote = '\0'; if (*c == '\'' || *c == '"') { quote = *c; ++c; } QoreString enc; while (*c && *c != ';' && *c != ' ' && *c != quote) enc.concat(*(c++)); if (quote && *c == quote) ++c; printd(5, "QoreHttpClientObject::send_intern() setting encoding to '%s' from content-type header: '%s' (cs=%p c=%p %d)\n", enc.getBuffer(), str, p + 8, c); // set new encoding msock->socket->setEncoding(QEM.findCreate(&enc)); // strip from content-type QoreStringNode* nc = new QoreStringNode(); // skip any spaces before the charset= while (p != str && (*(p - 1) == ' ' || *(p - 1) == ';')) p--; if (p != str) nc->concat(str, p - str); if (*c) nc->concat(c); ans->setKeyValue("content-type", nc, xsink); str = nc->getBuffer(); } // split into a list if ";" characters are present p = strchr(str, ';'); if (p) { bool multipart = false; QoreListNode* l = new QoreListNode(); do { // skip whitespace while (*str == ' ') str++; if (str != p) { int len = p - str; check_headers(str, len, multipart, *(*ans), msock->socket->getEncoding(), xsink); l->push(new QoreStringNode(str, len, msock->socket->getEncoding())); } str = p + 1; } while ((p = strchr(str, ';'))); // skip whitespace while (*str == ' ') str++; // add last field if (*str) { check_headers(str, strlen(str), multipart, *(*ans), msock->socket->getEncoding(), xsink); l->push(new QoreStringNode(str, msock->socket->getEncoding())); } ans->setKeyValue("content-type", l, xsink); } } // send headers to recv_callback if (recv_callback && msock->socket->priv->runHeaderCallback(xsink, mname, *recv_callback, &msock->m, *ans, send_aborted, obj)) return 0; AbstractQoreNode* body = 0; const char* content_encoding = 0; // do not read any message body for messages that cannot have one // rfc 2616 4.4 p1 (http://tools.ietf.org/html/rfc2616#section-4.4) /* 1.Any response message which "MUST NOT" include a message-body (such as the 1xx, 204, and 304 responses and any response to a HEAD request) is always terminated by the first empty line after the header fields, regardless of the entity-header fields present in the message. */ //printd(5, "qore_httpclient_priv::send_internal() this: %p bodyp: %d code: %d\n", this, bodyp, code); qore_uncompress_to_string_t dec = 0; // code >= 300 && < 400 is already handled above if (bodyp && (code < 100 || code >= 200) && code != 204) { // see if we should do a binary or string read content_encoding = get_string_header(xsink, **ans, "content-encoding"); if (*xsink) { disconnect_unlocked(); return 0; } if (content_encoding) { // check for misuse (? not sure: check RFCs again) of this field by including a character encoding value if (!strncasecmp(content_encoding, "iso", 3) || !strncasecmp(content_encoding, "utf-", 4)) { msock->socket->setEncoding(QEM.findCreate(content_encoding)); content_encoding = 0; } else if (!recv_callback) { // only decode message bodies automatically if there is no receive callback if (!strcasecmp(content_encoding, "deflate") || !strcasecmp(content_encoding, "x-deflate")) dec = qore_inflate_to_string; else if (!strcasecmp(content_encoding, "gzip") || !strcasecmp(content_encoding, "x-gzip")) dec = qore_gunzip_to_string; else if (!strcasecmp(content_encoding, "bzip2") || !strcasecmp(content_encoding, "x-bzip2")) dec = qore_bunzip2_to_string; } } const char* te = get_string_header(xsink, **ans, "transfer-encoding"); if (*xsink) { disconnect_unlocked(); return 0; } // get response body, if any const char* cl = get_string_header(xsink, **ans, "content-length"); if (*xsink) { disconnect_unlocked(); return 0; } int len = cl ? atoi(cl) : 0; if (cl && cb_queue) do_content_length_event(cb_queue, msock->socket->getObjectIDForEvents(), len); if (te && !strcasecmp(te, "chunked")) { // check for chunked response body if (cb_queue) do_event(cb_queue, msock->socket->getObjectIDForEvents(), QORE_EVENT_HTTP_CHUNKED_START); ReferenceHolder<QoreHashNode> nah(xsink); if (recv_callback) { if (content_encoding) msock->socket->priv->readHttpChunkedBodyBinary(timeout_ms, xsink, QORE_SOURCE_HTTPCLIENT, recv_callback, &msock->m, obj); else msock->socket->priv->readHttpChunkedBody(timeout_ms, xsink, QORE_SOURCE_HTTPCLIENT, recv_callback, &msock->m, obj); } else { if (content_encoding) nah = msock->socket->priv->readHttpChunkedBodyBinary(timeout_ms, xsink, QORE_SOURCE_HTTPCLIENT); else nah = msock->socket->priv->readHttpChunkedBody(timeout_ms, xsink, QORE_SOURCE_HTTPCLIENT); } if (cb_queue) do_event(cb_queue, msock->socket->getObjectIDForEvents(), QORE_EVENT_HTTP_CHUNKED_END); if (!nah && !recv_callback) { if (!msock->socket->isOpen()) disconnect_unlocked(); return 0; } if (info) { info->setKeyValue("chunked", &True, xsink); if (*xsink) return 0; } if (!recv_callback) { body = nah->takeKeyValue("body"); ans->merge(*nah, xsink); } } else if (getbody || len) { if (content_encoding) { SimpleRefHolder<BinaryNode> bobj(msock->socket->recvBinary(len, timeout_ms, xsink)); if (!(*xsink) && bobj) body = bobj.release(); } else { QoreStringNodeHolder bstr(msock->socket->recv(len, timeout_ms, xsink)); if (!(*xsink) && bstr) body = bstr.release(); } if (*xsink && !msock->socket->isOpen()) disconnect_unlocked(); //printf("body=%p\n", body); } } // check for connection: close header if (!keep_alive) disconnect_unlocked(); else { const char* conn = get_string_header(xsink, **ans, "connection", true); if (*xsink) { disconnect_unlocked(); return 0; } if (conn && !strcasecmp(conn, "close")) disconnect_unlocked(); } sl.unlock(); // for content-encoding processing we can run unlocked // add body to result hash and process content encoding if necessary if (body) { if (content_encoding) { if (!dec) { if (!recv_callback) { xsink->raiseException("HTTP-CLIENT-RECEIVE-ERROR", "don't know how to handle content-encoding '%s'", content_encoding); ans = 0; } } else { BinaryNode* bobj = reinterpret_cast<BinaryNode*>(body); QoreStringNode* str = dec(bobj, msock->socket->getEncoding(), xsink); bobj->deref(); body = str; } } if (body) { // send data to recv_callback (already unlocked) if (recv_callback) { ReferenceHolder<> bh(body, xsink); if (msock->socket->priv->runDataCallback(xsink, mname, *recv_callback, 0, body, false) || msock->socket->priv->runHeaderCallback(xsink, mname, *recv_callback, 0, 0, send_aborted, obj)) return 0; } else ans->setKeyValue("body", body, xsink); } } // do not throw an exception if a receive callback is used if (!recv_callback && !*xsink && (code < 100 || code >= 300)) { const char* mess = get_string_header(xsink, **ans, "status_message"); if (!mess) mess = "<no message>"; assert(!*xsink); xsink->raiseExceptionArg("HTTP-CLIENT-RECEIVE-ERROR", ans.release(), "HTTP status code %d received: message: %s", code, mess); return 0; } return *xsink || recv_callback ? 0 : ans.release(); }