/*
 * Test MessageSerializer with nested variable groups, this should never
 * extract.
 */
void MessageDeserializerTest::testWithNestedVariableGroups() {
  vector<const FieldDescriptor*> fields, group_fields, group_fields2;
  group_fields.push_back(new BoolFieldDescriptor("bool"));
  group_fields2.push_back(new Int16FieldDescriptor("uint16"));
  group_fields2.push_back(new FieldDescriptorGroup("bar", group_fields, 0, 2));
  fields.push_back(new FieldDescriptorGroup("", group_fields2, 0, 4));
  Descriptor descriptor("Test Descriptor", fields);

  // an empty message would be valid.
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      NULL,
      0));

  const uint8_t data[] = {0, 1, 0, 1};
  // none of these are valid
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      data,
      1));
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      data,
      2));
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      data,
      3));
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      data,
      4));
}
/**
 * Check that strings do the right thing
 */
void MessageDeserializerTest::testString() {
  vector<const FieldDescriptor*> fields;
  fields.push_back(new StringFieldDescriptor("string", 10, 10));
  fields.push_back(new StringFieldDescriptor("string", 0, 32));
  Descriptor descriptor("Test Descriptor", fields);

  // now setup the data
  const uint8_t data[] = "0123456789this is a longer string";

  // try to inflate with too little
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      data,
      0));
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      data,
      9));

  // try to inflat with too much data
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      data,
      43));

  // now to the right amount
  auto_ptr<const Message> message(m_deserializer.InflateMessage(
      &descriptor,
      data,
      sizeof(data)));
  CPPUNIT_ASSERT(message.get());
  CPPUNIT_ASSERT_EQUAL(2u, message->FieldCount());

  const string expected = (
      "string: 0123456789\nstring: this is a longer string\n");
  CPPUNIT_ASSERT_EQUAL(expected, m_printer.AsString(message.get()));

  // now try with different sizes
  auto_ptr<const Message> message2(m_deserializer.InflateMessage(
      &descriptor,
      data,
      19));
  CPPUNIT_ASSERT(message2.get());
  CPPUNIT_ASSERT_EQUAL(2u, message2->FieldCount());

  const string expected2 = (
      "string: 0123456789\nstring: this is a\n");
  CPPUNIT_ASSERT_EQUAL(expected2, m_printer.AsString(message2.get()));
}
/**
 * Test that simple (no variable sized fields) work big endian style.
 */
void MessageDeserializerTest::testSimpleBigEndian() {
  // build the descriptor
  vector<const FieldDescriptor*> fields;
  // All multi-byte fields default to big endian
  fields.push_back(new BoolFieldDescriptor("bool"));
  fields.push_back(new UInt8FieldDescriptor("uint8"));
  fields.push_back(new Int8FieldDescriptor("int8"));
  fields.push_back(new UInt16FieldDescriptor("uint16"));
  fields.push_back(new Int16FieldDescriptor("int16"));
  fields.push_back(new UInt32FieldDescriptor("uint32"));
  fields.push_back(new Int32FieldDescriptor("int32"));
  Descriptor descriptor("Test Descriptor", fields);

  // now setup the data
  const uint8_t big_endian_data[] = {
    0, 10, -10, 1, 0x2c, 0xfe, 10,
    1, 2, 3, 4, 0xfe, 6, 7, 8};

  // try to inflate with no data
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      NULL,
      0));

  // now inflate with too little data
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      big_endian_data,
      1));

  // now inflate with too much data
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      big_endian_data,
      sizeof(big_endian_data) + 1));

  // now the correct amount & verify
  auto_ptr<const Message> message(m_deserializer.InflateMessage(
      &descriptor,
      big_endian_data,
      sizeof(big_endian_data)));
  CPPUNIT_ASSERT(message.get());
  CPPUNIT_ASSERT_EQUAL(7u, message->FieldCount());

  const string expected = (
      "bool: false\nuint8: 10\nint8: -10\nuint16: 300\nint16: -502\n"
      "uint32: 16909060\nint32: -33159416\n");
  CPPUNIT_ASSERT_EQUAL(expected, m_printer.AsString(message.get()));
}
/**
 * Test that simple (no variable sized fields) work little endian style.
 */
void MessageDeserializerTest::testSimpleLittleEndian() {
  // build the descriptor
  vector<const FieldDescriptor*> fields;
  fields.push_back(new BoolFieldDescriptor("bool"));
  fields.push_back(new UInt8FieldDescriptor("uint8"));
  fields.push_back(new Int8FieldDescriptor("int8"));
  fields.push_back(new UInt16FieldDescriptor("uint16", true));
  fields.push_back(new Int16FieldDescriptor("int16", true));
  fields.push_back(new UInt32FieldDescriptor("uint32", true));
  fields.push_back(new Int32FieldDescriptor("int32", true));
  Descriptor descriptor("Test Descriptor", fields);

  // now setup the data
  const uint8_t little_endian_data[] = {
    1, 10, 246, 0x2c, 1, 10, 0xfe,
    4, 3, 2, 1, 8, 7, 6, 0xfe};

  // try to inflate with no data
  OLA_ASSERT_NULL(m_deserializer.InflateMessage(
      &descriptor,
      NULL,
      0));

  // now inflate with too little data
  OLA_ASSERT_NULL(m_deserializer.InflateMessage(
      &descriptor,
      little_endian_data,
      1));

  // now inflate with too much data
  OLA_ASSERT_NULL(m_deserializer.InflateMessage(
      &descriptor,
      little_endian_data,
      sizeof(little_endian_data) + 1));

  // now the correct amount & verify
  auto_ptr<const Message> message(m_deserializer.InflateMessage(
      &descriptor,
      little_endian_data,
      sizeof(little_endian_data)));
  OLA_ASSERT_NOT_NULL(message.get());
  OLA_ASSERT_EQ(7u, message->FieldCount());

  const string expected = (
      "bool: true\nuint8: 10\nint8: -10\nuint16: 300\nint16: -502\n"
      "uint32: 16909060\nint32: -33159416\n");
  OLA_ASSERT_EQ(expected, m_printer.AsString(message.get()));
}
Exemple #5
0
void ChatClient::receiveUntypedMessage(const MessageDeserializer& deserializer) {

    if (!isConnected()) {
        std::cerr << "chat connection is invalid" << std::endl;
        return;
    }
    
    if (!deserializer.isInitialized())
        return;

    if (deserializer.type() == USER_JOIN_RESPONSE) {
        receiveMessage(deserializer.getMessage<UserJoinResponse>());
    }
    else if (deserializer.type() == USER_LIST_RESPONSE) {
        receiveMessage(deserializer.getMessage<UserListResponse>());
    }
    else if (deserializer.type() == USER_CHANGE) {
        receiveMessage(deserializer.getMessage<UserChange>());
    }
    else if (deserializer.type() == CHAT_MESSAGE) {
        receiveMessage(deserializer.getMessage<ChatMessage>());
    }
    else if(deserializer.type() == CHATROOM_CHANGE) {
        receiveMessage(deserializer.getMessage<ChatroomChange>());
    }
    else if(deserializer.type() == GENERIC_CHAT_RESPONSE) {
        receiveMessage(deserializer.getMessage<GenericChatResponse>());
    }
}
/**
 * Check that empty messages work.
 */
void MessageDeserializerTest::testEmpty() {
  vector<const FieldDescriptor*> fields;
  Descriptor descriptor("Empty Descriptor", fields);

  auto_ptr<const Message> empty_message(m_deserializer.InflateMessage(
      &descriptor,
      NULL,
      0));
  CPPUNIT_ASSERT(empty_message.get());
  CPPUNIT_ASSERT_EQUAL(0u, empty_message->FieldCount());

  // now and try to pass in too much data
  const uint8_t data[] = {0, 1, 2};
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      data,
      sizeof(data)));
}
/**
 * Test UID inflation.
 */
void MessageDeserializerTest::testUID() {
  // build the descriptor
  vector<const FieldDescriptor*> fields;
  fields.push_back(new UIDFieldDescriptor("Address"));
  Descriptor descriptor("Test Descriptor", fields);

  // now setup the data
  const uint8_t big_endian_data[] = {0x70, 0x7a, 0, 0, 0, 1};

  // now the correct amount & verify
  auto_ptr<const Message> message(m_deserializer.InflateMessage(
      &descriptor,
      big_endian_data,
      sizeof(big_endian_data)));
  CPPUNIT_ASSERT(message.get());
  CPPUNIT_ASSERT_EQUAL(1u, message->FieldCount());

  const string expected = "Address: 707a:00000001\n";
  CPPUNIT_ASSERT_EQUAL(expected, m_printer.AsString(message.get()));
}
/*
 * Test MessageSerializer with nested fixed groups.
 */
void MessageDeserializerTest::testWithNestedFixedGroups() {
  vector<const FieldDescriptor*> fields, group_fields, group_fields2;
  group_fields.push_back(new BoolFieldDescriptor("bool"));
  group_fields2.push_back(new UInt8FieldDescriptor("uint8"));
  group_fields2.push_back(new FieldDescriptorGroup("bar", group_fields, 2, 2));
  fields.push_back(new FieldDescriptorGroup("", group_fields2, 0, 4));
  Descriptor descriptor("Test Descriptor", fields);

  // now setup the inputs
  const uint8_t data[] = {0, 0, 0, 1, 0, 1, 2, 1, 0, 3, 1, 1};

  // an empty mesage
  auto_ptr<const Message> message(m_deserializer.InflateMessage(
      &descriptor,
      data,
      0));
  CPPUNIT_ASSERT(message.get());
  CPPUNIT_ASSERT_EQUAL(0u, message->FieldCount());

  // message with not enough data
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      data,
      1));
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      data,
      2));

  // a single instance of a group
  auto_ptr<const Message> message2(m_deserializer.InflateMessage(
      &descriptor,
      data,
      3));
  CPPUNIT_ASSERT(message2.get());
  CPPUNIT_ASSERT_EQUAL(1u, message2->FieldCount());

  const string expected = (
      " {\n  uint8: 0\n  bar {\n    bool: false\n  }\n  bar {\n"
      "    bool: false\n  }\n}\n");
  CPPUNIT_ASSERT_EQUAL(expected, m_printer.AsString(message2.get()));

  // four instances
  auto_ptr<const Message> message3(m_deserializer.InflateMessage(
      &descriptor,
      data,
      sizeof(data)));
  CPPUNIT_ASSERT(message3.get());
  CPPUNIT_ASSERT_EQUAL(4u, message3->FieldCount());

  const string expected2 = (
      " {\n  uint8: 0\n  bar {\n    bool: false\n  }\n  bar {\n"
      "    bool: false\n  }\n}\n"
      " {\n  uint8: 1\n  bar {\n    bool: false\n  }\n  bar {\n"
      "    bool: true\n  }\n}\n"
      " {\n  uint8: 2\n  bar {\n    bool: true\n  }\n  bar {\n"
      "    bool: false\n  }\n}\n"
      " {\n  uint8: 3\n  bar {\n    bool: true\n  }\n  bar {\n"
      "    bool: true\n  }\n}\n");
  CPPUNIT_ASSERT_EQUAL(expected2, m_printer.AsString(message3.get()));

  // too much data
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      data,
      sizeof(data) + 1));
}
/*
 * Check the MessageSerializer works with variable sized groups.
 */
void MessageDeserializerTest::testWithGroups() {
  // build the descriptor
  vector<const FieldDescriptor*> group_fields;
  group_fields.push_back(new BoolFieldDescriptor("bool"));
  group_fields.push_back(new UInt8FieldDescriptor("uint8"));

  vector<const FieldDescriptor*> fields;
  fields.push_back(new FieldDescriptorGroup("group", group_fields, 0, 3));
  Descriptor descriptor("Test Descriptor", fields);

  // now setup the inputs
  const uint8_t data[] = {0, 10, 1, 3, 0, 20, 1, 40};

  // an empty message
  auto_ptr<const Message> message(m_deserializer.InflateMessage(
      &descriptor,
      data,
      0));
  CPPUNIT_ASSERT(message.get());
  CPPUNIT_ASSERT_EQUAL(0u, message->FieldCount());

  // message with not enough data
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      data,
      1));

  // a single instance of a group
  auto_ptr<const Message> message2(m_deserializer.InflateMessage(
      &descriptor,
      data,
      2));
  CPPUNIT_ASSERT(message2.get());
  CPPUNIT_ASSERT_EQUAL(1u,
                       message2->FieldCount());

  const string expected = "group {\n  bool: false\n  uint8: 10\n}\n";
  CPPUNIT_ASSERT_EQUAL(expected, m_printer.AsString(message2.get()));

  // another message with not enough data
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      data,
      3));

  // two instances of the group
  auto_ptr<const Message> message3(m_deserializer.InflateMessage(
      &descriptor,
      data,
      4));
  CPPUNIT_ASSERT(message3.get());
  CPPUNIT_ASSERT_EQUAL(2u, message3->FieldCount());

  const string expected2 = (
      "group {\n  bool: false\n  uint8: 10\n}\n"
      "group {\n  bool: true\n  uint8: 3\n}\n");
  CPPUNIT_ASSERT_EQUAL(expected2, m_printer.AsString(message3.get()));

  // trhee instances of the group
  auto_ptr<const Message> message4(m_deserializer.InflateMessage(
      &descriptor,
      data,
      6));
  CPPUNIT_ASSERT(message4.get());
  CPPUNIT_ASSERT_EQUAL(3u,
                       message4->FieldCount());

  const string expected3 = (
      "group {\n  bool: false\n  uint8: 10\n}\n"
      "group {\n  bool: true\n  uint8: 3\n}\n"
      "group {\n  bool: false\n  uint8: 20\n}\n");
  CPPUNIT_ASSERT_EQUAL(expected3, m_printer.AsString(message4.get()));

  // message with too much data
  CPPUNIT_ASSERT(!m_deserializer.InflateMessage(
      &descriptor,
      data,
      sizeof(data)));
}