blob: ca39a846606f7604344d5ea5e483df15076fb0ec [file] [log] [blame]
#ifndef __message_private_h__
#define __message_private_h__ 1
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <qpid/dispatch/message.h>
#include <qpid/dispatch/alloc.h>
#include <qpid/dispatch/threading.h>
/**
* Architecture of the message module:
*
* +--------------+ +----------------------+
* | | | |
* | dx_message_t |----------->| dx_message_content_t |
* | | +----->| |
* +--------------+ | +----------------------+
* | |
* +--------------+ | | +-------------+ +-------------+ +-------------+
* | | | +--->| dx_buffer_t |-->| dx_buffer_t |-->| dx_buffer_t |--/
* | dx_message_t |-----+ +-------------+ +-------------+ +-------------+
* | |
* +--------------+
*
* The message module provides chained-fixed-sized-buffer storage of message content with multiple
* references. If a message is received and is to be queued for multiple destinations, there is only
* one copy of the message content in memory but multiple lightweight references to the content.
*
*/
typedef struct {
dx_buffer_t *buffer; // Buffer that contains the first octet of the field, null if the field is not present
size_t offset; // Offset in the buffer to the first octet
size_t length; // Length of the field or zero if unneeded
int parsed; // non-zero iff the buffer chain has been parsed to find this field
} dx_field_location_t;
// TODO - consider using pointers to dx_field_location_t below to save memory
// TODO - we need a second buffer list for modified annotations and header
// There are three message scenarios:
// 1) Received message is held and forwarded unmodified - single buffer list
// 2) Received message is held and modified before forwarding - two buffer lists
// 3) Message is composed internally - single buffer list
typedef struct {
sys_mutex_t *lock;
uint32_t ref_count; // The number of qmessages referencing this
dx_buffer_list_t buffers; // The buffer chain containing the message
pn_delivery_t *in_delivery; // The delivery on which the message arrived
dx_field_location_t section_message_header; // The message header list
dx_field_location_t section_delivery_annotation; // The delivery annotation map
dx_field_location_t section_message_annotation; // The message annotation map
dx_field_location_t section_message_properties; // The message properties list
dx_field_location_t section_application_properties; // The application properties list
dx_field_location_t section_body; // The message body: Data
dx_field_location_t section_footer; // The footer
dx_field_location_t field_user_id; // The string value of the user-id
dx_field_location_t field_to; // The string value of the to field
dx_field_location_t field_reply_to; // The string value of the reply_to field
dx_field_location_t body; // The body of the message
dx_buffer_t *parse_buffer;
unsigned char *parse_cursor;
dx_message_depth_t parse_depth;
} dx_message_content_t;
typedef struct {
DEQ_LINKS(dx_message_t); // Deq linkage that overlays the dx_message_t
dx_message_content_t *content;
pn_delivery_t *out_delivery;
} dx_message_pvt_t;
ALLOC_DECLARE(dx_message_t);
ALLOC_DECLARE(dx_message_content_t);
#define MSG_CONTENT(m) (((dx_message_pvt_t*) m)->content)
#endif