|
||||||||||||||||||||
1 : /* 2 : * $Id: ScatterMessage.cc 1135 2007-11-30 07:15:08Z dfs $ 3 : * 4 : * Copyright 2006,2007 Savarese Software Research Corporation 5 : * 6 : * Licensed under the Apache License, Version 2.0 (the "License"); 7 : * you may not use this file except in compliance with the License. 8 : * You may obtain a copy of the License at 9 : * 10 : * http://www.savarese.com/software/ApacheLicense-2.0 11 : * 12 : * Unless required by applicable law or agreed to in writing, software 13 : * distributed under the License is distributed on an "AS IS" BASIS, 14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 : * See the License for the specific language governing permissions and 16 : * limitations under the License. 17 : */ 18 : 19 : #include <sava/spread/ScatterMessage.h> 20 : 21 : __BEGIN_NS_SAVA_SPREAD 22 : 23 : /** 24 : * Handles auto-resizing prior to a receive. Each message part that 25 : * is a Message instance is resized to its capacity so that it may be 26 : * completely filled if necessary. The size of the ScatterMessage is 27 : * adjusted accordingly. 28 : */ 29 8 : void ScatterMessage::init_pre_receive() { 30 8 : int size = _messages.size(); 31 : 32 17 : for(int i = 0; i < size; ++i) { 33 9 : value_type & value = _messages[i]; 34 9 : Message *m = value.first; 35 : 36 9 : if(value.second >= _scatter.num_elements) 37 0 : break; 38 : 39 9 : _size-=m->size(); 40 9 : m->resize(m->capacity()); 41 9 : _size+=m->size(); 42 9 : _scatter.elements[value.second].len = m->size(); 43 : } 44 8 : } 45 : 46 : /** 47 : * Handles auto-resizing after a receive. Each message part that is a 48 : * Message instance is resized to reflect the number of bytes that was 49 : * stored in it by the receive. The type, service, endian mismatch, 50 : * and sender of eatch Message is set to that of the message (copied 51 : * from the ScatterMessage). 52 : * 53 : * @param bytes_received The total number of bytes received. May be 54 : * negative in case of an error. 55 : */ 56 8 : void ScatterMessage::init_post_receive(int bytes_received) { 57 8 : int index = 0, i, len; 58 8 : int size = _messages.size(); 59 : Message *m; 60 : 61 8 : if(bytes_received > 0) 62 7 : _size = bytes_received; 63 : else 64 1 : _size = 0; 65 : 66 15 : for(i = 0; i < size && bytes_received > 0; ++i) { 67 7 : value_type & value = _messages[i]; 68 7 : int mindex = value.second; 69 7 : if(mindex >= _scatter.num_elements) 70 0 : break; 71 : 72 14 : while(index < mindex) 73 0 : bytes_received-=_scatter.elements[index++].len; 74 : 75 7 : if(bytes_received <= 0) 76 0 : break; 77 : 78 7 : len = _scatter.elements[mindex].len; 79 7 : m = value.first; 80 : 81 7 : m->set_type(type()); 82 7 : m->set_service(service()); 83 7 : m->set_endian_mismatch(endian_mismatch()); 84 7 : m->set_sender(_sender); 85 : 86 7 : if(len <= bytes_received) 87 1 : m->resize(len); 88 : else 89 6 : m->resize(bytes_received); 90 : 91 7 : bytes_received-=len; 92 : } 93 : 94 : // Anything left over gets a size of zero. 95 10 : for(; i < size; ++i) { 96 2 : m = _messages[i].first; 97 2 : m->resize(0); 98 2 : m->set_type(type()); 99 2 : m->set_service(service()); 100 2 : m->set_endian_mismatch(endian_mismatch()); 101 2 : m->set_sender(_sender); 102 : } 103 8 : } 104 : 105 : /** 106 : * Adds a message part to the ScatterMessage with a designated number 107 : * of bytes indicating either the capacity of the buffer (for 108 : * receiving) or the length of its contents (for sending). 109 : * 110 : * @param data A pointer to the data buffer to add. 111 : * @param size The number of bytes to be filled in to or read from the 112 : * data buffer. 113 : * @return true if the message part was added, false if there's no 114 : * more parts can be added. 115 : */ 116 21 : bool ScatterMessage::add(const void *data, const unsigned int size) { 117 21 : int i = _scatter.num_elements; 118 : 119 21 : if(i >= MaxScatterElements) 120 0 : return false; 121 : 122 21 : ++_scatter.num_elements; 123 : _scatter.elements[i].buf = 124 21 : const_cast<char *>(static_cast<const char *>(data)); 125 21 : _scatter.elements[i].len = size; 126 21 : _size+=size; 127 : 128 21 : return true; 129 : } 130 : 131 : __END_NS_SAVA_SPREAD |