Example #1
0
/**
This function loads a protobuf object from a file using the assumption that it is proceeded with a 64 bit Poco::Int64 in network byte order that holds the size of the object to be loaded and deserialized.
@param inputPath: The path to the file to load from
@param inputMessageBuffer: The protobuf object to deserialize to
@return: true if the message could be loaded and deserialized and false otherwise
*/
bool pylongps::loadProtobufObjectFromFile(const std::string &inputPath, google::protobuf::Message &inputMessageBuffer)
{
//Read size of object in file
std::string sizeString;
if(readStringFromFile(sizeString, sizeof(Poco::Int64), inputPath) == false) 
{
return false;
}

Poco::Int64 objectSizeNetworkOrder = *((Poco::Int64 *) sizeString.c_str());
Poco::Int64 objectSize = Poco::ByteOrder::fromNetwork(objectSizeNetworkOrder);

//Read size+object
std::string sizeAndObjectString;
if(readStringFromFile(sizeAndObjectString, sizeof(Poco::Int64)+objectSize, inputPath) == false) 
{
return false;
}

//Clip off size
std::string objectString = sizeAndObjectString.substr(sizeof(Poco::Int64));

//Deserialize the protobuf object
inputMessageBuffer.ParseFromString(objectString);

if(!inputMessageBuffer.IsInitialized())
{
printf("Message not initialized\n");
return false;
}

return true;
}
Example #2
0
// Write out the given protobuf to the specified file descriptor by
// first writing out the length of the protobuf followed by the contents.
// NOTE: On error, this may have written partial data to the file.
inline Try<Nothing> write(int fd, const google::protobuf::Message& message)
{
  if (!message.IsInitialized()) {
    return Error("Uninitialized protocol buffer");
  }

  // First write the size of the protobuf.
  uint32_t size = message.ByteSize();
  std::string bytes = std::string((char*) &size, sizeof(size));

  Try<Nothing> result = os::write(fd, bytes);
  if (result.isError()) {
    return Error("Failed to write size: " + result.error());
  }

  if (!message.SerializeToFileDescriptor(fd)) {
    return Error("Failed to write/serialize message");
  }

  return Nothing();
}
Example #3
0
// Write out the given protobuf to the specified file descriptor by
// first writing out the length of the protobuf followed by the
// contents.
inline Result<bool> write(int fd, const google::protobuf::Message& message)
{
  if (!message.IsInitialized()) {
    LOG(ERROR) << "Failed to write protocol buffer to file, "
               << "protocol buffer is not initialized!";
    return false;
  }

  uint32_t size = message.ByteSize();

  ssize_t length = ::write(fd, (void*) &size, sizeof(size));

  if (length == -1) {
    std::string error = strerror(errno);
    error = error + " (" + __FILE__ + ":" + utils::stringify(__LINE__) + ")";
    return Result<bool>::error(error);
  }

  CHECK(length != 0);
  CHECK(length == sizeof(size)); // TODO(benh): Handle a non-blocking fd?

  return message.SerializeToFileDescriptor(fd);
}
Example #4
0
/**
This function is used to receive and deserialize a protobuf object from a ZMQ socket.
@param inputSocketToReceiveFrom: This is the socket to receive the object from
@param inputMessageBuffer: This is the buffer to place the received object in
@param inputFlags: The flags to pass to the ZMQ socket
@param inputPreappendedDataBuffer: The buffer to place x bytes before the message in
@param inputPreappendedDataSize: How much data to expect to be preappended
@param inputPostappendedDataBuffer: The buffer to place x bytes before the message in
@param inputPostappendedDataSize: How much data to expect to be postappended
@return: <true if message received, true if message deserialized correctly>

@throws: This function can throw exceptions
*/
std::tuple<bool, bool> pylongps::receiveProtobufMessage(zmq::socket_t &inputSocketToReceiveFrom, google::protobuf::Message &inputMessageBuffer, int inputFlags, char *inputPreappendedDataBuffer, int inputPreappendedDataSize, char *inputPostappendedDataBuffer, int inputPostappendedDataSize)
{
if(inputPreappendedDataSize < 0 || inputPostappendedDataSize < 0)
{
throw SOMException("Negative data size\n", INVALID_FUNCTION_INPUT, __FILE__, __LINE__);
}

if((inputPreappendedDataSize > 0 && inputPreappendedDataBuffer == nullptr) || (inputPostappendedDataSize < 0 && inputPostappendedDataBuffer == nullptr))
{
throw SOMException("Data size > 0 but buffer is nullptr\n", INVALID_FUNCTION_INPUT, __FILE__, __LINE__);
}

bool messageReceived = false;
bool messageDeserialized = false;

std::unique_ptr<zmq::message_t> messageBuffer;

SOM_TRY
messageBuffer.reset(new zmq::message_t);
SOM_CATCH("Error initializing ZMQ message")

SOM_TRY
messageReceived = inputSocketToReceiveFrom.recv(messageBuffer.get(), inputFlags);
SOM_CATCH("Error, unable to receive message\n")

if(messageReceived == false)
{ //Didn't get a message
return std::tuple<bool, bool>(messageReceived, messageDeserialized);
}

//Attempt to retrieve any preappended data
if(messageBuffer->size() < inputPreappendedDataSize)
{ //Message isn't valid (smaller than expected preappended data)
return std::tuple<bool, bool>(messageReceived, messageDeserialized);
}
else if(inputPreappendedDataSize > 0)
{ //Preappended data is expected and the message is large enough to get it
memcpy((void *) inputPreappendedDataBuffer, messageBuffer->data(), inputPreappendedDataSize);
}

//Deserialize message
inputMessageBuffer.ParseFromArray(((char *) messageBuffer->data())+inputPreappendedDataSize, messageBuffer->size()-inputPreappendedDataSize);

if(!inputMessageBuffer.IsInitialized())
{
return std::tuple<bool, bool>(messageReceived, messageDeserialized);
}

if(inputPostappendedDataSize > 0)
{
int protobufMessageSize = inputMessageBuffer.ByteSize();

if((protobufMessageSize+inputPreappendedDataSize+inputPostappendedDataSize) > messageBuffer->size())
{
return std::tuple<bool, bool>(messageReceived, messageDeserialized);
}
else
{
memcpy((void *) inputPostappendedDataBuffer, (void *) (((char *) messageBuffer->data()) + protobufMessageSize + inputPreappendedDataSize), inputPostappendedDataSize);
messageDeserialized = true;
}

}
else
{
messageDeserialized = true;
}

return std::tuple<bool, bool>(messageReceived, messageDeserialized);
}
Example #5
0
mori::TcpConnBuffer						Codec::Encode( const google::protobuf::Message& msg, const SEncodeContext& context )
{
	assert(msg.IsInitialized());

	CodecProtocol::Codec encodeMsg;
	encodeMsg.set_msgname(msg.GetDescriptor()->full_name());
	encodeMsg.set_clienttype(context.ClientType_);
	if ( context.UserID_ )
	{
		encodeMsg.set_userid(*context.UserID_);
	}
	if ( context.VerifyCode_ )
	{
		encodeMsg.set_verifycode(*context.VerifyCode_);
	}

	std::string msgBuf;
	msg.SerializeToString(&msgBuf);

	auto bContinue = true;
	auto step = 0;
	while ( bContinue )
	{	
		switch (step)
		{
		case 0:
			{
				if ( !context.AESKey_.empty() )
				{
					msgBuf = FastEncrypt::AES_CBCEncrypt(context.AESKey_, msgBuf);
					encodeMsg.set_aeskey(context.AESKey_);
				}

				++step;
			}break;
		case 1:
			{
				if ( !context.RSAKey_.empty() && !context.AESKey_.empty() )
				{
					auto EncryptAESKey = FastEncrypt::RSA_PubEncrypt(context.RSAKey_, context.AESKey_);
					encodeMsg.mutable_aeskey()->swap(EncryptAESKey);
					encodeMsg.set_rsaencode(true);
				}

				++step;
			}
			break;
		case 2:
			{
				if ( context.Compress_ )
				{
					auto compSize = compressBound(msgBuf.size());
					std::string tmpbuf;
					tmpbuf.resize(compSize);

					auto err = compress(reinterpret_cast<Bytef*>(&tmpbuf[0]), &compSize, reinterpret_cast<const Bytef*>(msgBuf.data()), msgBuf.size());
					if ( Z_OK != err )
					{
						assert(0);
						bContinue = false;
					}
					else
					{
						encodeMsg.set_rawsize(msgBuf.size());

						msgBuf.clear();
						tmpbuf.resize(compSize);
						
						msgBuf.swap(tmpbuf);
					}
				}

				++step;
			}
			break;
		default:
			{
				bContinue = false;
			}
			break;
		}
	}

	mori::TcpConnBuffer ret(sizeof(uint32_t)+encodeMsg.ByteSize());

	encodeMsg.SerializeToArray(ret.data()+sizeof(uint32_t), ret.size()-sizeof(uint32_t));
	
	uint32_t* pSize = reinterpret_cast<uint32_t*>(ret.data());
	*pSize = boost::asio::detail::socket_ops::host_to_network_long(encodeMsg.ByteSize());

	ret.reserve(ret.size()+msgBuf.size());
	std::copy(msgBuf.begin(), msgBuf.end(), std::back_inserter(ret));

	return std::move(ret);
}