void Connector::assembleMessage( const util::Buffer &b ) { int offset = 0; int msgSize, need; int rcvLen=b.length(); while (offset < rcvLen) { int sLen=_msg.length(); // How many bytes need for complete message? if (sLen > MESSAGE_HEADER) { // Stored bytes already have header msgSize = MSG_SIZE(_msg.buffer()); need = msgSize - sLen; } else if (MESSAGE_HEADER-sLen <= (rcvLen-offset)) { // Stored bytes don't have the header, but with bytes received complete header! _msg.append( b.buffer()+offset, MESSAGE_HEADER-sLen ); offset += MESSAGE_HEADER-sLen; sLen = MESSAGE_HEADER; msgSize = MSG_SIZE(_msg.buffer()); need = msgSize-MESSAGE_HEADER; } else { // Can't complete the header _msg.append( b.buffer()+offset, rcvLen-offset ); offset = rcvLen; continue; } assert( need >= 0 ); // Copy bytes int rest = (rcvLen-offset); int copy = (rest > need) ? need : rest; // printf( "[Connector (%p)] rcvLen=%d, sLen=%d, msgSize=%d, need=%d, rest=%d, copy=%d\n", // this, rcvLen, sLen, msgSize, need, rest, copy ); _msg.append( b.buffer()+offset, copy ); offset += copy; // printf( "[Connector (%p)] msgLen=%d\n", this, _msg.length() ); // Is message complete? if (msgSize == _msg.length()) { messageReceived(&_msg); _msg.resize(0); } } }
void parseDescriptors( const util::Buffer &info, desc::MapOfDescriptors &descriptors ) { SIZE_T len = info.length(); BYTE *data = (BYTE *)info.buffer(); SSIZE_T offset = 0; while (offset < len) { BYTE dTag = RB(data,offset); BYTE dLen = RB(data,offset); SSIZE_T parsed = offset; printf( "[dsmcc::module] Parse tag descriptor: tag=%x, len=%d\n", dTag, dLen ); switch (dTag) { case MODULE_DESC_TYPE: // Type descriptor { std::string type( (char *)(data+parsed), dLen ); descriptors[dTag] = type; parsed += dLen; break; } case MODULE_DESC_NAME: // Name descriptor { std::string name( (char *)(data+parsed), dLen ); descriptors[dTag] = name; parsed += dLen; break; } case MODULE_DESC_INFO: // Info descriptor { module::InfoDescriptor desc; desc.language = std::string( (char *)(data+parsed), 3 ); desc.text = std::string( (char *)(data+parsed+3), dLen-3 ); descriptors[dTag] = desc; parsed += dLen; break; } case MODULE_DESC_LINK: // Module link descriptor { module::LinkDescriptor desc; desc.position = RB(data,parsed); desc.moduleID = RW(data,parsed); descriptors[dTag] = desc; break; } case MODULE_DESC_CRC32: // CRC32 descriptor { DWORD crc = RDW(data,parsed); descriptors[dTag] = crc; break; } case MODULE_DESC_LOCATION: // Location descriptor { BYTE location = RB(data,parsed); descriptors[dTag] = location; break; } case MODULE_DESC_EST_DOWNLOAD: // Estimated download time descriptor { DWORD est = RDW(data,parsed); descriptors[dTag] = est; break; } case MODULE_DESC_COMPRESSION: // Compression type descriptor case MODULE_DESC_COMPRESSED: { module::CompressionTypeDescriptor desc; desc.type = RB(data,parsed); desc.originalSize = RDW(data,parsed); descriptors[dTag] = desc; break; } }; offset += dLen; if (offset != parsed) { printf( "[dsmcc::module] Descriptor not parsed or parsed was incomplete: dTag=%x, len=%d, parsed=%ld\n", dTag, dLen, parsed ); } } //printf( "[dsmcc::module] Descriptors parsed: %d\n", descriptors.size() ); }