ProtoAssembly.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include <stdlib.h> | ||
| 2 | #include <string.h> | ||
| 3 | #include "ProtoAssembly.h" | ||
| 4 | |||
| 5 | 29 | void MessageAssembler::release() { | |
| 6 | 29 | free(this->buf); | |
| 7 | 29 | this->buf = nullptr; | |
| 8 | 29 | this->len = 0; | |
| 9 | 29 | this->owner = 0; | |
| 10 | 29 | } | |
| 11 | 2 | void MessageAssembler::drop(uint32_t clientId) { | |
| 12 | 2 | if(this->owner == clientId) this->release(); | |
| 13 | 2 | } | |
| 14 | 4 | uint32_t MessageAssembler::expire(uint32_t now) { | |
| 15 | 4 | if(!this->owner || now - this->startedAt < PROTO_ASSEMBLY_TIMEOUT_MS) return 0; | |
| 16 | 1 | const uint32_t stalled = this->owner; | |
| 17 | 1 | this->release(); | |
| 18 | 1 | return stalled; | |
| 19 | } | ||
| 20 | 7 | char *MessageAssembler::take(size_t &len) { | |
| 21 | 7 | char *message = this->buf; | |
| 22 | 7 | len = this->len; | |
| 23 | 7 | this->buf = nullptr; | |
| 24 | 7 | this->release(); | |
| 25 | 7 | return message; | |
| 26 | } | ||
| 27 | 23 | assembly_t MessageAssembler::add(const proto_piece_t &piece, uint32_t now) { | |
| 28 | 23 | if(piece.first) { | |
| 29 | // Refused without taking the buffer from anyone. | ||
| 30 | 13 | if(!piece.text) return assembly_t::notText; | |
| 31 | 11 | if(this->owner && this->owner != piece.clientId) return assembly_t::busy; | |
| 32 | 10 | this->release(); | |
| 33 | 10 | this->buf = static_cast<char *>(malloc(this->limit + 1)); | |
| 34 | 10 | if(!this->buf) return assembly_t::noMemory; | |
| 35 | 10 | this->owner = piece.clientId; | |
| 36 | 10 | this->startedAt = now; | |
| 37 | } | ||
| 38 | // The rest of a message that was already answered. | ||
| 39 | 10 | else if(this->owner != piece.clientId) return assembly_t::ignored; | |
| 40 | 16 | if(this->len + piece.len > this->limit) { | |
| 41 | 1 | this->release(); | |
| 42 | 1 | return assembly_t::tooLarge; | |
| 43 | } | ||
| 44 | 15 | memcpy(this->buf + this->len, piece.data, piece.len); | |
| 45 | 15 | this->len += piece.len; | |
| 46 | 15 | if(!piece.last) return assembly_t::more; | |
| 47 | 7 | this->buf[this->len] = '\0'; | |
| 48 | 7 | return assembly_t::complete; | |
| 49 | } | ||
| 50 |