| Directory: | ./ | 
|---|---|
| File: | pdserv/src/msrproto/Subscription.cpp | 
| Date: | 2025-10-26 04:10:09 | 
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 39 | 43 | 90.7% | 
| Branches: | 23 | 36 | 63.9% | 
| Line | Branch | Exec | Source | 
|---|---|---|---|
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * Copyright 2010 Richard Hacker (lerichi at gmx dot net) | ||
| 4 | * | ||
| 5 | * This file is part of the pdserv library. | ||
| 6 | * | ||
| 7 | * The pdserv library is free software: you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU Lesser General Public License as published | ||
| 9 | * by the Free Software Foundation, either version 3 of the License, or (at | ||
| 10 | * your option) any later version. | ||
| 11 | * | ||
| 12 | * The pdserv library is distributed in the hope that it will be useful, but | ||
| 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
| 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | ||
| 15 | * License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public License | ||
| 18 | * along with the pdserv library. If not, see <http://www.gnu.org/licenses/>. | ||
| 19 | * | ||
| 20 | ****************************************************************************/ | ||
| 21 | |||
| 22 | #include "../Signal.h" | ||
| 23 | #include "../Debug.h" | ||
| 24 | #include "XmlElement.h" | ||
| 25 | #include "Channel.h" | ||
| 26 | #include "SubscriptionManager.h" | ||
| 27 | #include "Subscription.h" | ||
| 28 | #include "../DataType.h" | ||
| 29 | |||
| 30 | #include <algorithm> | ||
| 31 | |||
| 32 | using namespace MsrProto; | ||
| 33 | |||
| 34 | ///////////////////////////////////////////////////////////////////////////// | ||
| 35 | 44 | Subscription::Subscription(const Channel *channel, | |
| 36 | size_t decimation, size_t blocksize, bool base64, | ||
| 37 | 44 | std::streamsize precision): | |
| 38 | channel(channel), | ||
| 39 | 2/2✓ Branch 0 taken 42 times. ✓ Branch 1 taken 2 times. | 44 | decimation(blocksize ? decimation : 1), | 
| 40 | blocksize(blocksize), | ||
| 41 | 44 | bufferOffset(channel->offset), | |
| 42 | 132 | trigger_start(decimation) | |
| 43 | { | ||
| 44 | 44 | trigger = 0; | |
| 45 | 44 | nblocks = 0; | |
| 46 | |||
| 47 | 44 | this->precision = precision; | |
| 48 | 44 | this->base64 = base64; | |
| 49 | |||
| 50 | 44 | size_t dataLen = (blocksize + !blocksize) * channel->memSize; | |
| 51 | |||
| 52 | 44 | data_bptr = new char[dataLen]; | |
| 53 | 44 | data_eptr = data_bptr + dataLen; | |
| 54 | |||
| 55 | 1/2✓ Branch 4 taken 44 times. ✗ Branch 5 not taken. | 44 | std::fill_n(data_bptr, dataLen, 0); | 
| 56 | |||
| 57 | 44 | data_pptr = data_bptr; | |
| 58 | 44 | } | |
| 59 | |||
| 60 | ///////////////////////////////////////////////////////////////////////////// | ||
| 61 | 88 | Subscription::~Subscription() | |
| 62 | { | ||
| 63 | 1/2✓ Branch 1 taken 44 times. ✗ Branch 2 not taken. | 44 | delete[] data_bptr; | 
| 64 | 44 | } | |
| 65 | |||
| 66 | ///////////////////////////////////////////////////////////////////////////// | ||
| 67 | 1179 | bool Subscription::newValue (const char *buf) | |
| 68 | { | ||
| 69 | 1179 | const size_t n = channel->memSize; | |
| 70 | 1179 | buf += bufferOffset; | |
| 71 | |||
| 72 | 2/2✓ Branch 1 taken 12 times. ✓ Branch 2 taken 1167 times. | 1179 | if (!blocksize) { | 
| 73 | 7/8✓ Branch 1 taken 6 times. ✓ Branch 2 taken 6 times. ✗ Branch 6 not taken. ✓ Branch 7 taken 6 times. ✓ Branch 10 taken 4 times. ✓ Branch 11 taken 2 times. ✓ Branch 12 taken 10 times. ✓ Branch 13 taken 2 times. | 12 | if ((trigger and --trigger) or std::equal(buf, buf + n, data_bptr)) | 
| 74 | 10 | return false; | |
| 75 | |||
| 76 | 2 | trigger = trigger_start; | |
| 77 | } | ||
| 78 | |||
| 79 | 1169 | std::copy(buf, buf + n, data_pptr); | |
| 80 | 1169 | data_pptr += n; | |
| 81 | 1169 | ++nblocks; | |
| 82 | |||
| 83 | 1169 | return true; | |
| 84 | } | ||
| 85 | |||
| 86 | ///////////////////////////////////////////////////////////////////////////// | ||
| 87 | 503 | void Subscription::print(XmlElement &parent) | |
| 88 | { | ||
| 89 | 1/2✓ Branch 2 taken 503 times. ✗ Branch 3 not taken. | 503 | if (nblocks >= blocksize) { | 
| 90 | 3/4✓ Branch 2 taken 501 times. ✓ Branch 3 taken 2 times. ✓ Branch 5 taken 503 times. ✗ Branch 6 not taken. | 1006 | XmlElement datum(parent.createChild(blocksize ? "F" : "E")); | 
| 91 | 2/4✓ Branch 2 taken 503 times. ✗ Branch 3 not taken. ✓ Branch 9 taken 503 times. ✗ Branch 10 not taken. | 503 | XmlElement::Attribute(datum, "c") << channel->index; | 
| 92 | |||
| 93 | 1/2✓ Branch 2 taken 503 times. ✗ Branch 3 not taken. | 1006 | XmlElement::Attribute value(datum, "d"); | 
| 94 | 2/4✗ Branch 1 not taken. ✓ Branch 2 taken 503 times. ✓ Branch 3 taken 503 times. ✗ Branch 4 not taken. | 503 | if (base64) | 
| 95 | 1/2✓ Branch 9 taken 503 times. ✗ Branch 10 not taken. | 503 | value.base64(data_bptr, nblocks * channel->memSize); | 
| 96 | else | ||
| 97 | ✗ | value.csv(channel, data_bptr, nblocks, precision); | |
| 98 | } | ||
| 99 | |||
| 100 | 503 | data_pptr = data_bptr; | |
| 101 | 503 | nblocks = 0; | |
| 102 | 503 | } | |
| 103 | |||
| 104 | ///////////////////////////////////////////////////////////////////////////// | ||
| 105 | ✗ | void Subscription::reset() | |
| 106 | { | ||
| 107 | ✗ | data_pptr = data_bptr; | |
| 108 | ✗ | nblocks = 0; | |
| 109 | } | ||
| 110 |