示例#1
0
BOOL COMotion::NormalizeKeys(float from_time, float to_time, float speed)
{
    if (to_time<from_time) return FALSE;
    CEnvelope* E = Envelope(ctPositionX);
    float new_tm = 0;
    float t0 = E->keys.front()->time;
    FloatVec tms;
    tms.push_back (t0);
    for (KeyIt it=E->keys.begin()+1; it!=E->keys.end(); it++)
    {
        if ((*it)->time>from_time)
        {
            if ((*it)->time<to_time+EPS)
            {
                float dist = 0;
                Fvector PT,T,R;
                _Evaluate (t0, PT, R);
                for (float tm=t0+1.f/fFPS; tm<=(*it)->time; tm+=EPS_L)
                {
                    _Evaluate (tm, T, R);
                    dist += PT.distance_to(T);
                    PT.set (T);
                }
                new_tm += dist / speed;
                t0 = (*it)->time;
                tms.push_back (new_tm);
            }
            else
            {
                float dt = (*it)->time-t0;
                t0 = (*it)->time;
                new_tm +=dt;
                tms.push_back (new_tm);
    }
}
    }
    for (int ch = 0; ch < ctMaxChannel; ch++)
    {
        E = Envelope(EChannelType(ch));
        FloatIt f_it = tms.begin();
        VERIFY(tms.size()==E->keys.size());
        for (KeyIt k_it=E->keys.begin(); k_it!=E->keys.end(); k_it++,f_it++)
            (*k_it)->time = *f_it;
    }

    /*
     CEnvelope* E = Envelope();
     for (KeyIt it=E->keys.begin(); it!=E->keys.end(); it++){
     if (((*it)->time>from_time)&&((*it)->time<to_time)){
     for (float tm=from_time; tm<=to_time; tm+=1.f/fFPS){

     }
     }
     */
    return TRUE;
}
示例#2
0
void testall(double length, bool is_fade_in){
  Envelope linear = Envelope(Envelope::Shape::FadeLinear, length, is_fade_in);
  Envelope fast = Envelope(Envelope::Shape::FadeFast, length, is_fade_in);
  Envelope slow = Envelope(Envelope::Shape::FadeSlow, length, is_fade_in);
  Envelope constant_power = Envelope(Envelope::Shape::FadeConstantPower, length, is_fade_in);
  Envelope symmetric = Envelope(Envelope::Shape::FadeSymmetric, length, is_fade_in);

  display(linear, "Linear", is_fade_in);
  display(fast, "Fast", is_fade_in);
  display(slow, "Slow", is_fade_in);
  display(constant_power, "Constant Power", is_fade_in);
  display(symmetric, "Symmetric", is_fade_in);
}
示例#3
0
void Server::run() {
  std::string result;
  Envelope receivedEnv;
  Envelope broadcastEnv;

  while (true) {
    // Receive any incoming request
    receivedEnv = Envelope(retrieveSerialData());
    FILE_LOG(logDEBUG) << "Retrieved Envelope: '" << receivedEnv.toString() << "'";

    // Verify request is intended for this server
    FILE_LOG(logDEBUG) << "Verifying Request is from Server.";
    if  (receivedEnv.getServer() != name && receivedEnv.getServer() != "") {
      FILE_LOG(logDEBUG) << "NOT for this server CONFIRMED, SKIPPING";
      continue;
    }

    // Make sure the request is sensible and allowed
    FILE_LOG(logDEBUG) << "For this server CONFIRMED";
    FILE_LOG(logDEBUG) << "Attempting to verfiy the request";
    result = validateRequest(receivedEnv);

    // Request is for the server
    if (result == "server") {
      FILE_LOG(logDEBUG) << "Envelope passed verification as server request...";
      result = IRCHandler(receivedEnv.getExpression());
      FILE_LOG(logDEBUG) << "IRCHandler Result: '" << result << "'" ;
      // Setup broadcast with result, from "server" to requester
      broadcastEnv = Envelope(name, receivedEnv.getSender(), "server", result);
    }
    // Request is targeted at a channel
    else if (result == "channel") {
      FILE_LOG(logDEBUG) << "Envelope passed verification as channel request ...";
      result = IRCHandler(receivedEnv.getExpression());
      FILE_LOG(logDEBUG) << "IRCHandler Result: '" << result << "'";
      broadcastEnv = Envelope(name, receivedEnv.getDestination(),
                              receivedEnv.getSender(), result);
    }
    else {
      FILE_LOG(logDEBUG) << "Envelope failed verification...";
      broadcastEnv = Envelope(name, receivedEnv.getSender(), "server", result);
      FILE_LOG(logDEBUG) << "Failure notification sent...";
    }

    // Broadcast the result of the request
    broadcastSerialData(broadcastEnv.toString());
  }
}
Envelope TileBoundsCalculator::_toEnvelope(const PixelBox& pb)
{
  return Envelope(_envelope.MinX + pb.minX * _pixelSize,
    _envelope.MinX + (pb.maxX + 1) * _pixelSize,
    _envelope.MinY + pb.minY * _pixelSize,
    _envelope.MinY + (pb.maxY + 1) * _pixelSize);
}
示例#5
0
Grid::Grid():
    _data(),
    _limits( Envelope( 0.0,1.0,0.0,1.0 ) ),
    _pixelConvention( PIXEL_IS_POINT )
{

}
示例#6
0
Envelope BaseCommand::parseEnvelope(QString envStr) const
{
  QStringList envArr = envStr.split(",");

  if (envArr.size() != 4)
  {
    throw HootException("Invalid bounds format, requires 4 values: " + envStr);
  }

  bool ok, allOk = true;
  double left = envArr[0].toDouble(&ok);
  allOk &= ok;
  double bottom = envArr[1].toDouble(&ok);
  allOk &= ok;
  double right = envArr[2].toDouble(&ok);
  allOk &= ok;
  double top = envArr[3].toDouble(&ok);
  allOk &= ok;

  if (allOk == false)
  {
    throw HootException("Invalid bounds format: " + envStr);
  }

  return Envelope(left, right, bottom, top);
}
示例#7
0
      Envelope operator()(const Edge& edge) const
      {
	const double m = cicada::dot_product(edge.features, direction);
	const double y = cicada::dot_product(edge.features, origin);
	
	return Envelope(boost::shared_ptr<line_type>(new line_type(m, y, edge)));
      }
示例#8
0
void PointEditWindow::drawBack(DrawBuf buf,bool) const
 {
  SmoothDrawArt art(buf);

  Pane pane=Envelope(pos,pos+getPoint());

  MCoord width=+cfg.width;

  FigureBox fig(pane);

  fig.loop(art,HalfPos,width,+cfg.line);
 }
示例#9
0
	void object::test<1>()
	{
		//Create a subdivision centered at (0,0)
		QuadEdgeSubdivision sub(Envelope(-100, 100, -100, 100), .00001);
		//make a triagulaor to work on sub
		IncrementalDelaunayTriangulator triangulator(&sub);

		triangulator.insertSite(Vertex(0, 0));

		//extract the triangles from the subdivision
		GeometryFactory geomFact;
		std::auto_ptr<GeometryCollection> tris = sub.getTriangles(geomFact);
	}
示例#10
0
bool Client::GetStoreInfo(StoreInfoCallback * callback, void *data)
{
    if (!callback) {
        throw invalid_argument("callback parameter not defined");
    }

    Envelope e = Envelope();
    protocol::request::GetStoreInfoV1 req;
    req.add_to_envelope(&e);

    OutstandingRequest info = OutstandingRequest();
    info.cb_store_info = callback;
    info.data = data;

    return this->SendRequest(e, info);
}
示例#11
0
    /// Validates that a protocol request message has been sent
    ///
    /// Expects the request message to have a single protocol envelope with a
    /// single embedded message of the enumeration specified and serialized to
    /// exactly what we specify
    void ExpectRequestMessage(uint32 type, ::google::protobuf::Message &expected)
    {
        ASSERT_TRUE(this->socket != NULL);

        ::zmq::pollitem_t pollitem;
        pollitem.events = ZMQ_POLLIN;
        pollitem.socket = *this->socket;
        pollitem.fd = 0;
        pollitem.revents = 0;

        ASSERT_EQ(1, ::zmq::poll(&pollitem, 1, 1000))
            << "Request message sent in orderly manner";

        MessageContainer messages;
        ASSERT_TRUE(zeromq::ReceiveMessage(*this->socket, messages));

        ASSERT_EQ(1, messages.IdentitiesSize()) << "client sent identities as part of request";
        ASSERT_EQ(1, messages.MessagesSize()) << "client sent 1 message with content";

        message_t msg;
        msg.copy(messages[0]);

        ASSERT_GT(msg.size(), 1) << "sent message has content";

        char msg_version = 0;
        memcpy(&msg_version, msg.data(), 1);
        EXPECT_EQ(0x01, msg_version) << "sent message has protocol header";

        Envelope e;

        EXPECT_NO_THROW(e = Envelope(msg, 1)) << "envelope could be deserialized";

        EXPECT_EQ(1, e.MessageCount()) << "envelope contains one message";
        EXPECT_EQ(::zippylog::message_namespace, e.MessageNamespace(0)) << "message of proper namespace";
        EXPECT_EQ(type, e.MessageType(0)) << "message of proper type";

        EXPECT_EQ(1, e.TagSize()) << "envelope has tag";

        ::google::protobuf::Message *sent = (::google::protobuf::Message *)e.GetMessage(0);
        ASSERT_TRUE(sent != NULL) << "able to deserialize embedded message";

        string serialized_expected, serialized_actual;
        EXPECT_TRUE(expected.SerializeToString(&serialized_expected));
        EXPECT_TRUE(sent->SerializeToString(&serialized_actual));

        EXPECT_EQ(serialized_expected, serialized_actual) << "sent request message matches expected";
    }
示例#12
0
文件: Tree.cpp 项目: Tempest12/Trees
void Tree::reset(void)
{
	this->envelope = Envelope(Config::convertSettingToString("envelope", "file"));
	this->attractionPoints.clear();
	this->spawnAttractionPoints();

	while(this->nodes.size() > 0)
	{
		delete this->nodes[0];
        this->nodes.erase(this->nodes.begin() + 0);
	}

	Vector3f temp = Vector3f();
    this->root = new Node(&temp, NULL);
    this->nodes.push_back(this->root);

}
	void object::test<1>()
	{
		//create subdivision centered around (0,0)
		QuadEdgeSubdivision sub(Envelope(-100, 100, -100, 100), .00001);
		//stick a point in the middle
		QuadEdge& e = sub.insertSite(Vertex(0, 0));
		ensure(sub.isFrameEdge(e));
		ensure(sub.isOnEdge(e, e.orig().getCoordinate()));
		ensure(sub.isVertexOfEdge(e, e.orig()));

		ensure(!sub.isOnEdge(e, Coordinate(10, 10)));
		ensure(!sub.isVertexOfEdge(e, Vertex(10, 10)));

		GeometryFactory geomFact;
		std::auto_ptr<GeometryCollection> tris = sub.getTriangles(geomFact);
		tris.reset();
		//WKTWriter wkt;
		//printf("%s\n", wkt.writeFormatted(tris).c_str());
	}
示例#14
0
bool Client::RenewSubscriptions(bool force)
{
    map<string, Subscription>::iterator iter = this->subscriptions.begin();

    protocol::request::SubscribeKeepaliveV1 msg;

    for (; iter != this->subscriptions.end(); iter++) {
        if (!force && !iter->second.expiration_timer.Signaled()) continue;

        // reset the timer
        iter->second.expiration_timer.Start();

        msg.add_id(iter->first);
    }

    Envelope e = Envelope();
    msg.add_to_envelope(&e);

    return zeromq::SendEnvelope(*this->client_sock, e, true, 0);
}
示例#15
0
bool Client::GetStreamSegment(::std::string const &path,
                              uint64 start_offset,
                              StreamSegmentCallback * callback,
                              void *data)
{
    if (!callback) {
        throw invalid_argument("callback parameter not defined");
    }

    Envelope e = Envelope();
    protocol::request::GetStreamSegmentV1 req;
    req.set_path(path);
    req.set_start_offset(start_offset);
    req.add_to_envelope(&e);

    OutstandingRequest info = OutstandingRequest();
    info.cb_stream_segment = callback;
    info.data = data;

    return this->SendRequest(e, info);
}
示例#16
0
文件: Tree.cpp 项目: Tempest12/Trees
Tree::Tree()
{
	this->attractionPoints = std::vector<AttractionPoint>();

	this->random = std::minstd_rand0();

	this->drawEnvelope = true;
	this->envelope = Envelope(Config::convertSettingToString("envelope", "file"));

	this->drawAttractionPoints = true;
    this->attractionPointsCount = Config::convertSettingToInt("tree", "points");
    this->spawnAttractionPoints();

    this->nodes = std::vector<Node*>();

    Vector3f temp = Vector3f();
    this->root = new Node(&temp, NULL);
    this->nodes.push_back(this->root);

    quadric = gluNewQuadric();
}
示例#17
0
bool Client::SubscribeEnvelopes(::std::string const &path,
                                ::std::string const &lua,
                                SubscriptionCallbackInfo &cb,
                                void *data)
{
    // @todo validate

    protocol::request::SubscribeEnvelopesV1 req;
    req.add_path(path);

    if (!lua.empty()) {
        req.set_lua_code(lua);
    }

    Envelope e = Envelope();
    req.add_to_envelope(&e);

    OutstandingRequest info = OutstandingRequest();
    info.data = data;
    info.callbacks = cb;

    return this->SendRequest(e, info);
}
bool
SegmentIntersectionTester::hasIntersectionWithEnvelopeFilter(
	const LineString &line, const LineString &testLine)
{
  typedef std::size_t size_type;

	const CoordinateSequence &seq0 = *(line.getCoordinatesRO());
  size_type seq0size = seq0.getSize();

  const CoordinateSequence &seq1 = *(testLine.getCoordinatesRO());
  size_type seq1size = seq1.getSize();

  const Envelope* lineEnv = line.getEnvelopeInternal();

  typedef std::size_t size_type;

  for (size_type i = 1; i<seq1size && !hasIntersectionVar; ++i)
	{
    seq1.getAt(i-1, pt10);
    seq1.getAt(i, pt11);

    // skip test if segment does not intersect query envelope
    if (! lineEnv->intersects(Envelope(pt10, pt11))) continue;

    for (size_type j = 1; j < seq0size && !hasIntersectionVar; ++j)
		{
      seq0.getAt(j - 1, pt00);
      seq0.getAt(j, pt01);

			li.computeIntersection(pt00, pt01, pt10, pt11);
			if (li.hasIntersection()) hasIntersectionVar = true;
		}
	}

	return hasIntersectionVar;
}
示例#19
0
bool Client::HandleSubscriptionResponse(Envelope &e, SubscriptionStartV1 &start, vector<message_t *> &messages)
{
    map<string, Subscription>::iterator iter = this->subscriptions.find(start.id());
    // subscription could have disappeared since it was validated
    if (iter == this->subscriptions.end()) return false;

    SubscriptionCallbackInfo cb = iter->second.cb;

    for (int i = 1; i < e.MessageCount(); i++) {
        switch (e.MessageType(i)) {
            case protocol::StoreChangeBucketAddedV1::zippylog_enumeration:
                if (cb.BucketAdded) {
                    protocol::StoreChangeBucketAddedV1 *added = (protocol::StoreChangeBucketAddedV1 *)e.GetMessage(i);
                    cb.BucketAdded(this, start.id(), *added, iter->second.data);
                }
                break;
            case protocol::StoreChangeBucketDeletedV1::zippylog_enumeration:
                if (cb.BucketDeleted) {
                    protocol::StoreChangeBucketDeletedV1 *deleted = (protocol::StoreChangeBucketDeletedV1 *)e.GetMessage(i);
                    cb.BucketDeleted(this, start.id(), *deleted, iter->second.data);
                }
                break;

            case protocol::StoreChangeStreamSetAddedV1::zippylog_enumeration:
                if (cb.StreamSetAdded) {
                    protocol::StoreChangeStreamSetAddedV1 *added = (protocol::StoreChangeStreamSetAddedV1 *)e.GetMessage(i);
                    cb.StreamSetAdded(this, start.id(), *added, iter->second.data);
                }
                break;

            case protocol::StoreChangeStreamSetDeletedV1::zippylog_enumeration:
                if (cb.StreamSetDeleted) {
                    protocol::StoreChangeStreamSetDeletedV1 *deleted = (protocol::StoreChangeStreamSetDeletedV1 *)e.GetMessage(i);
                    cb.StreamSetDeleted(this, start.id(), *deleted, iter->second.data);
                }
                break;

            case protocol::StoreChangeStreamAddedV1::zippylog_enumeration:
                if (cb.StreamAdded) {
                    protocol::StoreChangeStreamAddedV1 *added = (protocol::StoreChangeStreamAddedV1 *)e.GetMessage(i);
                    cb.StreamAdded(this, start.id(), *added, iter->second.data);
                }
                break;

            case protocol::StoreChangeStreamDeletedV1::zippylog_enumeration:
                if (cb.StreamDeleted) {
                    protocol::StoreChangeStreamDeletedV1 *deleted = (protocol::StoreChangeStreamDeletedV1 *)e.GetMessage(i);
                    cb.StreamDeleted(this, start.id(), *deleted, iter->second.data);
                }
                break;

            case protocol::StoreChangeStreamAppendedV1::zippylog_enumeration:
                if (cb.StreamAppended) {
                    protocol::StoreChangeStreamAppendedV1 *appended = (protocol::StoreChangeStreamAppendedV1 *)e.GetMessage(i);
                    cb.StreamAppended(this, start.id(), *appended, iter->second.data);
                }
                break;

            default:
                break;
        }
    }

    if (!cb.EnvelopeReceived) return true;

    // for now, assume additional messages envelopes that were streamed
    for (size_t i = 0; i < messages.size(); i++) {
        Envelope env = Envelope(messages[i]->data(), messages[i]->size());

        cb.EnvelopeReceived(this, start.id(), env, iter->second.data);
    }

    return true;
}
示例#20
0
void RequestProcessor::ProcessMessages(zeromq::MessageContainer &container, vector<Envelope> &output)
{
    // always clear the output list so we don't accidentally send leftovers
    output.clear();

    // we need to declare all our variables first b/c we use goto
    char msg_version = 0;
    bool have_request_envelope = false;
    Envelope request_envelope;
    RequestProcessorResponseStatus result;
    bool successful_process = false;

    /// @todo should we log?
    if (!container.MessagesSize()) return;

    message_t *initial = container.GetMessage(0);

    // we expect the first message to have an envelope of some kind
    if (!initial->size()) {
        ::zippylog::request_processor::ReceiveEmptyMessage log;
        LOG_MESSAGE(log, this->logger_sock);

        this->PopulateErrorResponse(
            protocol::response::EMPTY_MESSAGE,
            "empty 0MQ message received",
            output
        );
        goto CREATE_OUTPUT;
    }

    // the first byte of the message is the message format version
    // we currently only support 1, as it is the only defined version
    memcpy(&msg_version, initial->data(), sizeof(msg_version));

    if (msg_version != 0x01) {
        ::zippylog::request_processor::UnknownMessageVersion log;
        LOG_MESSAGE(log, this->logger_sock);

        this->PopulateErrorResponse(
            protocol::response::UNKNOWN_MESSAGE_FORMAT_VERSION,
            "protocol message version not understood. server only supports version 1",
            output
        );
        goto CREATE_OUTPUT;
    }

    // this is where we'd switch based on version
    // we only have version 1 now, so no branching is necessary

    // we expect to see data after the version byte. if we don't, something
    // is wrong
    if (initial->size() < 2) {
        this->PopulateErrorResponse(
            protocol::response::PROTOCOL_NO_ENVELOPE,
            "protocol version 1 0MQ message received without an envelope",
            output
        );
        goto CREATE_OUTPUT;
    }

    try {
        request_envelope = Envelope(*initial, 1);
    } catch ( ... ) {
        // we should only get an exception on parse error
        ::zippylog::request_processor::EnvelopeParseFailure log;
        LOG_MESSAGE(log, this->logger_sock);

        this->PopulateErrorResponse(
            protocol::response::ENVELOPE_PARSE_FAILURE,
            "error parsing envelope",
            output
        );
        goto CREATE_OUTPUT;
    }

    have_request_envelope = true;
    try {
        result = this->ProcessRequest(request_envelope, output);
    // @todo catch various types of exceptions
    } catch ( ... ) {
        this->PopulateErrorResponse(
            protocol::response::GENERAL_ERROR_PROCESSING,
            "exception when processing request",
            output
        );
        goto CREATE_OUTPUT;
    }

    successful_process = true;

    CREATE_OUTPUT:

    // if we couldn't process the request without throwing an exception, we
    // need to handle things ourselves
    if (!successful_process) {
        // if we have a request envelope and there were tags and we have an
        // output envelope, copy the tags over
        if (have_request_envelope && request_envelope.TagSize() && output.size()) {
            for (int i = 0; i < request_envelope.TagSize(); i++) {
                output[0].AddTag(request_envelope.GetTag(i));
            }
        }

        // not much more to do
        return;
    }

    if (result == AUTHORITATIVE) {
        assert(output.size());

        return;
    }

    return;
}
示例#21
0
RequestProcessorResponseStatus RequestProcessor::ProcessWriteEnvelope(Envelope &request, vector<Envelope> &output)
{
    {
        ::zippylog::request_processor::BeginProcessWriteEnvelope log;
        LOG_MESSAGE(log, this->logger_sock);
    }

    OBTAIN_MESSAGE(protocol::request::WriteEnvelopeV1, m, request, 0)

    if (!m->has_path()) {
        this->PopulateErrorResponse(
            protocol::response::EMPTY_FIELD,
            "required field 'path' missing",
            output
        );
        goto LOG_END;
    }

    // Path validation is a little tricky for write requests.
    // If the path is to a stream set, we require the set to exist. This
    // forces clients to look before they leap. But, they only need to look
    // once, assuming the set doesn't get deleted. For streams paths, we create
    // the path as necessary.
    {
        string path = m->path();
        string bucket, set, stream;
        if (!Store::ParsePath(path, bucket, set, stream)) {
            this->PopulateErrorResponse(
                protocol::response::INVALID_PATH,
                "invalid path: " + path,
                output
            );
            goto LOG_END;
        }

        if (!stream.length()) {
            if (!set.length()) {
                this->PopulateErrorResponse(
                    protocol::response::INVALID_PATH,
                    "path not to a stream set or stream: " + path,
                    output
                );
                goto LOG_END;
            }
            if (!this->CheckPath(path, output, true, true, false)) goto LOG_END;
        }
    }

    // there must be envelopes to write!
    if (m->envelope_size() < 1) {
        this->PopulateErrorResponse(
            protocol::response::EMPTY_FIELD,
            "no envelopes specified in request",
            output
        );
        goto LOG_END;
    }

    // at this point, we've validated the path is to an existing stream set or
    // a stream (we don't care which)
    {
        bool send_ack = m->acknowledge();
        bool synchronous = m->synchronous();

        // synchronous implies send_ack
        if (synchronous) send_ack = true;

        vector<Envelope> envs;
        for (int i = 0; i < m->envelope_size(); i++) {
            const string s = m->envelope(i);

            // catch parse failures and log then move on
            try { envs.push_back(Envelope(s.data(), s.size())); }
            catch (DeserializeException e) {
                ::zippylog::request_processor::EnvelopeParseFailure log;
                log.set_data(s);
                LOG_MESSAGE(log, this->logger_sock);
            }
        }

        RequestProcessorHandlerResult result;

        if (envs.size()) {
            result = this->impl->HandleWriteEnvelopes(m->path(), envs, synchronous);
        }

        if (send_ack && !result.deferred) {
            if (result.have_error) {
                /// @todo handle error in write handler
                throw Exception("not implemented");
            }

            if (!result.is_write) {
                throw Exception("return from request processor write envelopes implementation not sane");
            }

            protocol::response::WriteAckV1 ack;
            ack.set_envelopes_written(result.envelopes_written);

            Envelope e;
            ack.add_to_envelope(e);
            output.push_back(e);
        }
    }

LOG_END:

    ::zippylog::request_processor::EndProcessWriteEnvelope logend;
    LOG_MESSAGE(logend, this->logger_sock);

    // if we have data in the output, we are authoritative
    // else, we assume the user requested no ack, so we have no response
    if (output.size()) {
        return AUTHORITATIVE;
    }
    return DEFERRED;
}
示例#22
0
Vector<int64> DataSource::LowerEnvelope(Getdatafun getdataY, Getdatafun getdataX, double width) {return Envelope(getdataY, getdataX, width, LowerEqualThan);}
示例#23
0
bool LuaState::ExecuteLoadString(string const &s, LoadStringResult &result)
{
    if (!this->have_load_string) return false;

    int stack_size = lua_gettop(this->L);

    lua_getglobal(this->L, LOAD_STRING_FUNCTION);
    lua_pushlstring(this->L, s.c_str(), s.length());
    if (lua_pcall(this->L, 1, LUA_MULTRET, 0) != 0) {
        result.execution_success = false;
        size_t len = 0;
        const char *error = lua_tolstring(this->L, -1, &len);
        result.lua_error = string(error, len);
        lua_pop(this->L, 1);
        return true;
    }

    result.execution_success = true;

    int nresults = lua_gettop(L) - stack_size;
    if (nresults < 1) {
        result.return_type = result.INVALID;
        return true;
    }

    // as a refresher, the following type conventions are handled:
    //
    //  nil
    //  bool
    //  1 or more strings
    //  1 or more messages
    //  1 or more envelopes
    //  table, <any of above except nil>

    int stpos = -1 * nresults;
    int value_results = nresults;
    bool got_type = false;

    // handle the one off case for a single nil
    if (nresults == 1 && lua_isnil(this->L, -1)) {
        result.return_type = result.NIL;
        goto LOAD_STRING_POP_AND_RETURN;
    }

    // so we have a type that could be repeated
    // the first and only first one could be a table, so handle that
    if (lua_istable(this->L, stpos)) {
        value_results--;

        if (value_results < 1) {
            result.return_type = result.INVALID;
            goto LOAD_STRING_POP_AND_RETURN;
        }

        // @todo should we error if type is not a string?

        lua_getfield(this->L, stpos, "bucket");
        if (lua_isstring(this->L, -1)) {
            size_t len;
            const char *s = lua_tolstring(this->L, -1, &len);
            result.has_bucket = true;
            result.bucket = string(s, len);
        }
        lua_pop(this->L, 1);

        lua_getfield(this->L, stpos, "set");
        if (lua_isstring(this->L, -1)) {
            size_t len;
            const char *s = lua_tolstring(this->L, -1, &len);
            result.has_set = true;
            result.set = string(s, len);
        }
        lua_pop(this->L, 1);

        stpos++;
    }

    // ok, now iterate through the remaining values
    // make sure the types are consistent along the way
    for (int i = stpos; i < 0; i++) {
        if (lua_isboolean(this->L, i)) {
            // multiple booleans doesn't make any sense. catch it
            if (value_results > 1) {
                result.return_type = result.INVALID;
                goto LOAD_STRING_POP_AND_RETURN;
            }

            result.return_type = lua_toboolean(this->L, i) ? result.BOOLTRUE : result.BOOLFALSE;
            got_type = true;
            continue;
        }

        if (lua_isstring(this->L, i)) {
            // can't mix types
            if (got_type && result.return_type != result.STRING) {
                result.return_type = result.INVALID;
                goto LOAD_STRING_POP_AND_RETURN;
            }

            size_t len = 0;
            const char *s = lua_tolstring(this->L, i, &len);
            result.return_type = result.STRING;
            result.strings.push_back(string(s, len));
            got_type = true;
            continue;
        }

        void *ud = lua_touserdata(this->L, i);
        if (ud == NULL) {
            result.return_type = result.INVALID;
            break;
        }

        if (lua_getmetatable(this->L, i) == 0) {
            result.return_type = result.INVALID;
            break;
        }

        // is it an envelope type
        lua_getfield(this->L, LUA_REGISTRYINDEX, LUA_ENVELOPE_METHOD_TABLENAME);
        if (lua_rawequal(this->L, -2, -1)) {
            // don't need the metatables
            lua_pop(this->L, 2);

            if (got_type && result.return_type != result.ENVELOPE) {
                result.return_type = result.INVALID;
                goto LOAD_STRING_POP_AND_RETURN;
            }

            envelope_udata *ed = (envelope_udata *)ud;

            // we copy the envelope since poorly designed Lua scripts could
            // do evil things with the envelope in Lua land and we don't want
            // that to impact us here
            result.envelopes.push_back(Envelope(*ed->e));

            result.return_type = result.ENVELOPE;
            got_type = true;
            continue;
        }

        // remove metatables
        lua_pop(this->L, 2);

        // @todo handle message case

        result.return_type = result.INVALID;
        break;
    }

LOAD_STRING_POP_AND_RETURN:
    lua_pop(this->L, nresults);

    return true;
}
示例#24
0
 static inline Envelope one()  { return Envelope(boost::shared_ptr<Envelope::line_type>(new Envelope::line_type())); }
示例#25
0
 static inline Envelope zero() { return Envelope();  }