Example #1
0
/*
 * function: main()
 */
int main(int argc, char *argv[]) {
    int lookup_key;
    char str1[] = "foobar";
    char str2[] = "chicken soup";
    const void *pbuf;
    int *pkey;
    int *pkey2;
    int result;
    sgs_map *map;
    
    map = sgs_map_create(compare_ints);
    
    if (map == NULL) {
        fprintf(stderr, "Could not create sgs_map.\n");
        exit(-1);
    }
    
    pkey = malloc(sizeof(int));
    *pkey = 100;
    pbuf = sgs_map_get(map, pkey);
    print_get(*pkey, pbuf);
    
    result = sgs_map_put(map, pkey, str1);
    printf("Added element {%d, %s}.  result=%d\n", *pkey, str1, result);
    
    pbuf = sgs_map_get(map, pkey);
    print_get(*pkey, pbuf);
    
    pkey2 = malloc(sizeof(int));
    *pkey2 = 200;
    pbuf = sgs_map_get(map, pkey2);
    print_get(*pkey2, pbuf);
    
    result = sgs_map_put(map, pkey2, str2);
    printf("Added element {%d, %s}.  result=%d\n", *pkey2, str2, result);
    
    pbuf = sgs_map_get(map, pkey2);
    print_get(*pkey2, pbuf);
    
    lookup_key = 100;
    pbuf = sgs_map_get(map, &lookup_key);
    print_get(lookup_key, pbuf);
    
    lookup_key = 300;
    result = sgs_map_remove(map, &lookup_key);
    printf("REMOVE(%d) == %d\n", lookup_key, result);
    
    lookup_key = 100;
    result = sgs_map_remove(map, &lookup_key);
    printf("REMOVE(%d) == %d\n", lookup_key, result);
    
    lookup_key = 100;
    pbuf = sgs_map_get(map, &lookup_key);
    print_get(lookup_key, pbuf);
    
    lookup_key = 200;
    pbuf = sgs_map_get(map, &lookup_key);
    print_get(lookup_key, pbuf);
  
    sgs_map_clear(map);
    printf("EMPTY()\n");
  
    lookup_key = 100;
    pbuf = sgs_map_get(map, &lookup_key);
    print_get(lookup_key, pbuf);
  
    lookup_key = 200;
    pbuf = sgs_map_get(map, &lookup_key);
    print_get(lookup_key, pbuf);
  
    sgs_map_destroy(map);
    free(pkey2);
    free(pkey);
  
    printf("Goodbye!\n");
  
    return 0;
}
Example #2
0
/*
 * sgs_session_impl_recv_msg()
 */
int sgs_session_impl_recv_msg(sgs_session_impl *session) {
    int8_t result;
    ssize_t namelen, offset, offset2;
    sgs_id* channel_id;
    sgs_id* sender_id;
    sgs_message msg;
    const uint8_t* msg_data;
    sgs_channel* channel;
    size_t msg_datalen;
            
    
    if (sgs_msg_deserialize(&msg, session->msg_buf,
            sizeof(session->msg_buf)) == -1)
        return -1;

    //sgs_msg_dump(&msg);
    
    msg_datalen = sgs_msg_get_datalen(&msg);
    msg_data = sgs_msg_get_data(&msg);
    
    if (sgs_msg_get_version(&msg) != SGS_MSG_VERSION) {
        errno = SGS_ERR_BAD_MSG_VERSION;
        return -1;
    }
    
    if (sgs_msg_get_service(&msg) == SGS_APPLICATION_SERVICE) {
        switch (sgs_msg_get_opcode(&msg)) {
        case SGS_OPCODE_LOGIN_SUCCESS:
            /** field 1: session-id (compact-id format) */
            session->session_id =
                sgs_id_create(msg_data, msg_datalen, &offset);
            if (session->session_id == NULL) return -1;
            
            /** field 2: reconnection-key (compact-id format) */
            session->reconnect_key =
                sgs_id_create(msg_data + offset, msg_datalen - offset, NULL);
            if (session->reconnect_key == NULL) return -1;
            
            if (session->connection->ctx->logged_in_cb != NULL)
                session->connection->ctx->logged_in_cb(session->connection,
                    session);
            
            return 0;
            
        case SGS_OPCODE_LOGIN_FAILURE:
            /** field 1: error string (first 2 bytes = length of string) */
            if (session->connection->ctx->login_failed_cb != NULL)
                session->connection->ctx->login_failed_cb(session->connection,
                    msg_data + 2, read_len_header(msg_data));
      
            return 0;
      
        case SGS_OPCODE_SESSION_MESSAGE:
            /**
             * field 1: sequence number (8 bytes)
             * TODO first 8 bytes are a sequence number that is currently
             * ignored
             */
            offset = 8;
      
            /** field 2: message (first 2 bytes = length of message) */
            if (session->connection->ctx->recv_message_cb != NULL)
                session->connection->ctx->recv_message_cb(session->connection,
                    msg_data + offset + 2, read_len_header(msg_data + offset));
      
            return 0;
      
        case SGS_OPCODE_RECONNECT_SUCCESS:
            if (session->connection->ctx->reconnected_cb != NULL)
                session->connection->ctx->reconnected_cb(session->connection);
      
            return 0;
      
        case SGS_OPCODE_RECONNECT_FAILURE:
            sgs_connection_impl_disconnect(session->connection);
            return 0;
      
        case SGS_OPCODE_LOGOUT_SUCCESS:
            session->connection->expecting_disconnect = 1;
            return 0;
      
        default:
            errno = SGS_ERR_BAD_MSG_OPCODE;
            return -1;
        }
    }
    else if (sgs_msg_get_service(&msg) == SGS_CHANNEL_SERVICE) {
        switch (sgs_msg_get_opcode(&msg)) {
        case SGS_OPCODE_CHANNEL_JOIN:
            /** field 1: channel name (first 2 bytes = length of string) */
            namelen = read_len_header(msg_data);
            
            /** field 2: channel-id (compact-id format) */
            channel_id =
                sgs_id_create(msg_data + namelen + 2,
                    msg_datalen - namelen - 2, NULL);
            if (channel_id == NULL) return -1;
            
            if (sgs_map_contains(session->channels, channel_id)) {
                errno = SGS_ERR_ILLEGAL_STATE;
                sgs_id_destroy(channel_id);
                return -1;
            }
            
            channel = sgs_channel_impl_create(session, channel_id,
                (const char*)(msg_data + 2), namelen);
            
            if (channel == NULL) return -1;

            result = sgs_map_put(session->channels, channel_id, channel);
            
            if (result == -1) return -1;
            
            if (session->connection->ctx->channel_joined_cb != NULL)
                session->connection->ctx->channel_joined_cb(session->connection,
                    channel);
            
            return 0;
      
        case SGS_OPCODE_CHANNEL_LEAVE:
            /** field 1: channel-id (compact-id format) */
            channel_id = sgs_id_create(msg_data, msg_datalen, NULL);
            if (channel_id == NULL) return -1;
            
            channel = sgs_map_get(session->channels, channel_id);
            sgs_id_destroy(channel_id);

            if (channel == NULL) {
                errno = SGS_ERR_UNKNOWN_CHANNEL;
                return -1;
            }
 
            if (session->connection->ctx->channel_left_cb != NULL)
                session->connection->ctx->channel_left_cb(session->connection,
                    channel);
            
            sgs_map_remove(session->channels,
                sgs_channel_impl_get_id(channel));

            sgs_channel_impl_destroy(channel);
            
            return 0;
            
        case SGS_OPCODE_CHANNEL_MESSAGE:
            /** field 1: channel-id (compact-id format) */
            channel_id = sgs_id_create(msg_data, msg_datalen, &offset);
            if (channel_id == NULL) return -1;

            channel = sgs_map_get(session->channels, channel_id);
            sgs_id_destroy(channel_id);

            /**
             * field 2: sequence number (8 bytes)
             * TODO next 8 bytes are a sequence number that is currently ignored
             */
            offset += 8;

            /** field 3: session-id of sender (compact-id format) */
            sender_id = sgs_id_create(msg_data + offset, msg_datalen - offset,
                &offset2);
            if (sender_id == NULL) return -1;
                
            offset += offset2;
            
            if (channel == NULL) {
                errno = SGS_ERR_UNKNOWN_CHANNEL;
                return -1;
            }
            
            if (session->connection->ctx->channel_recv_msg_cb != NULL) {
                sender_id = sgs_id_is_server(sender_id) ? NULL : sender_id;
                
                /** field 4: message (first 2 bytes = length of message) */
                session->connection->ctx->channel_recv_msg_cb(session->connection,
                    channel, sender_id, msg_data + offset + 2,
                    read_len_header(msg_data + offset));
            }

            sgs_id_destroy(sender_id);
            
            return 0;
      
        default:
            errno = SGS_ERR_BAD_MSG_OPCODE;
            return -1;
        }
    }
    else {
        errno = SGS_ERR_BAD_MSG_SERVICE;
        return -1;
    }
}