Beispiel #1
0
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;
	}
}
Beispiel #2
0
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();
}
Beispiel #3
0
    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;
    }
Beispiel #4
0
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;
	}
}
Beispiel #5
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(); }
}
Beispiel #7
0
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);
}
Beispiel #8
0
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);
}
Beispiel #9
0
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;

}
Beispiel #10
0
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);
}
Beispiel #12
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();
}
Beispiel #25
0
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();
}