unit_tests/logicdata.cpp
| Line | Branch | Decision | Exec | Source |
|---|---|---|---|---|
| 1 | /* | |||
| 2 | * @file logicdata.cpp | |||
| 3 | * | |||
| 4 | * Based on LogicdataStreamFile.java by andreika | |||
| 5 | * | |||
| 6 | * Created on: Jul 19, 2020 | |||
| 7 | * @author Andrey Belomutskiy, (c) 2012-2020 | |||
| 8 | */ | |||
| 9 | ||||
| 10 | #include "logicdata.h" | |||
| 11 | #include <stdio.h> | |||
| 12 | #include <stdlib.h> | |||
| 13 | #include <cstdint> | |||
| 14 | #include <string.h> | |||
| 15 | ||||
| 16 | #define frequency 1000000 | |||
| 17 | #define frequencyDiv 10 | |||
| 18 | #define magic 0x7f | |||
| 19 | ||||
| 20 | #define BLOCK 0x15 | |||
| 21 | #define CHANNEL_BLOCK 0x16 | |||
| 22 | #define SUB 0x54 | |||
| 23 | ||||
| 24 | #define title "Data save2" | |||
| 25 | ||||
| 26 | #define FLAG_NOTEMPTY 2 | |||
| 27 | #define FLAG_NOTEMPTY_LONG 3 | |||
| 28 | #define FLAG_EMPTY 5 | |||
| 29 | ||||
| 30 | #define LOGIC4 0x40FD | |||
| 31 | #define LOGIC8 0x673B | |||
| 32 | ||||
| 33 | #define SIGN_FLAG 0x80000000L | |||
| 34 | ||||
| 35 | // todo: numChannels 7 or numChannels 8 does not work? :( | |||
| 36 | #define numChannels 6 | |||
| 37 | #define reservedDurationInSamples 10 | |||
| 38 | ||||
| 39 | static const char *channelNames[] = { "Primary", "Secondary", "TDC", | |||
| 40 | "Sync", "Coil", "Injector", "Channel 6", "Channel 7" }; | |||
| 41 | ||||
| 42 | static int CHANNEL_FLAGS[] = { 0x13458b, 0x0000ff, 0x00a0f9, 0x00ffff, 0x00ff00, | |||
| 43 | 0xff0000, 0xf020a0, }; | |||
| 44 | ||||
| 45 | static FILE *ptr; | |||
| 46 | ||||
| 47 | static uint32_t realDurationInSamples; | |||
| 48 | static uint32_t scaledDurationInSamples; | |||
| 49 | ||||
| 50 | 441256 | static void writeByte(uint8_t value) { | ||
| 51 | 441256 | fwrite(&value, 1, sizeof(value), ptr); | ||
| 52 | 441256 | } | ||
| 53 | ||||
| 54 | 28430 | static void writeAs(int64_t value, int numBytes) { | ||
| 55 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 28430 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 28430 times.
|
28430 | if (value == 0) { |
| 56 | ✗ | writeByte(0); | ||
| 57 | } else { | |||
| 58 | 28430 | writeByte(numBytes); | ||
| 59 |
2/2✓ Branch 0 taken 40841 times.
✓ Branch 1 taken 28430 times.
|
2/2✓ Decision 'true' taken 40841 times.
✓ Decision 'false' taken 28430 times.
|
69271 | for (int i = 0; i < numBytes; i++) { |
| 60 | 40841 | writeByte((uint8_t) ((value >> (i * 8)) & 0xff)); | ||
| 61 | } | |||
| 62 | } | |||
| 63 | 28430 | } | ||
| 64 | ||||
| 65 | // This is the main secret of this format! :) | |||
| 66 | 69606 | static void write(int64_t value) { | ||
| 67 |
3/4✓ Branch 0 taken 69461 times.
✓ Branch 1 taken 145 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 69461 times.
|
2/2✓ Decision 'true' taken 145 times.
✓ Decision 'false' taken 69461 times.
|
69606 | if (value < 0 || value > 0xFFFFFFFFL) { |
| 68 | 145 | writeAs(value, 8); | ||
| 69 |
2/2✓ Branch 0 taken 41176 times.
✓ Branch 1 taken 28285 times.
|
2/2✓ Decision 'true' taken 41176 times.
✓ Decision 'false' taken 28285 times.
|
69461 | } else if (value == 0) { |
| 70 | 41176 | writeByte(0); | ||
| 71 |
2/2✓ Branch 0 taken 21964 times.
✓ Branch 1 taken 6321 times.
|
2/2✓ Decision 'true' taken 21964 times.
✓ Decision 'false' taken 6321 times.
|
28285 | } else if (value <= 0xff) { |
| 72 | 21964 | writeAs(value, 1); | ||
| 73 |
2/2✓ Branch 0 taken 3310 times.
✓ Branch 1 taken 3011 times.
|
2/2✓ Decision 'true' taken 3310 times.
✓ Decision 'false' taken 3011 times.
|
6321 | } else if (value <= 0xffff) { |
| 74 | 3310 | writeAs(value, 2); | ||
| 75 |
2/2✓ Branch 0 taken 947 times.
✓ Branch 1 taken 2064 times.
|
2/2✓ Decision 'true' taken 947 times.
✓ Decision 'false' taken 2064 times.
|
3011 | } else if (value <= 0xffffff) { |
| 76 | 947 | writeAs(value, 3); | ||
| 77 | } else { | |||
| 78 | 2064 | writeAs(value, 4); | ||
| 79 | } | |||
| 80 | 69606 | } | ||
| 81 | ||||
| 82 | 1130 | static void writeString(const char *value) { | ||
| 83 | 1130 | int len = strlen(value); | ||
| 84 | 1130 | write(len); | ||
| 85 |
2/2✓ Branch 0 taken 7571 times.
✓ Branch 1 taken 1130 times.
|
2/2✓ Decision 'true' taken 7571 times.
✓ Decision 'false' taken 1130 times.
|
8701 | for (int i = 0; i < len; i++) { |
| 86 | 7571 | writeByte(value[i]); | ||
| 87 | } | |||
| 88 | 1130 | } | ||
| 89 | ||||
| 90 | // todo: some C++ magic would allow us to drop 'count' parameter | |||
| 91 | // todo: Look at efi::size in util | |||
| 92 | 452 | static void write(int values[], int count) { | ||
| 93 |
2/2✓ Branch 0 taken 2034 times.
✓ Branch 1 taken 452 times.
|
2/2✓ Decision 'true' taken 2034 times.
✓ Decision 'false' taken 452 times.
|
2486 | for (int i = 0; i < count; i++) { |
| 94 | 2034 | write(values[i]); | ||
| 95 | } | |||
| 96 | 452 | } | ||
| 97 | ||||
| 98 | 5763 | static void write(int value, int num) { | ||
| 99 |
2/2✓ Branch 0 taken 31794 times.
✓ Branch 1 taken 5763 times.
|
2/2✓ Decision 'true' taken 31794 times.
✓ Decision 'false' taken 5763 times.
|
37557 | for (int i = 0; i < num; i++) |
| 100 | 31794 | write(value); | ||
| 101 | 5763 | } | ||
| 102 | ||||
| 103 | 3164 | static void writeId(int i1, int i2) { | ||
| 104 | 3164 | write((numChannels == 4) ? LOGIC4 : LOGIC8); | ||
| 105 | 3164 | write(i1); | ||
| 106 | 3164 | write(i2); | ||
| 107 | 3164 | } | ||
| 108 | ||||
| 109 | 113 | static void writeHeader() { | ||
| 110 | 113 | writeByte(magic); | ||
| 111 | 113 | write(strlen(title)); | ||
| 112 | 113 | writeString(title); | ||
| 113 | ||||
| 114 | 113 | write(BLOCK); | ||
| 115 | 113 | write(SUB); | ||
| 116 | 113 | write(frequency); | ||
| 117 | 113 | write(0); | ||
| 118 | 113 | write(reservedDurationInSamples); | ||
| 119 | 113 | write(frequency / frequencyDiv); | ||
| 120 | 113 | write(0, 2); | ||
| 121 | 113 | write(numChannels); | ||
| 122 | ||||
| 123 | 113 | write(BLOCK); | ||
| 124 | 113 | write(0); | ||
| 125 | ||||
| 126 | 113 | write(BLOCK); | ||
| 127 |
2/2✓ Branch 0 taken 678 times.
✓ Branch 1 taken 113 times.
|
2/2✓ Decision 'true' taken 678 times.
✓ Decision 'false' taken 113 times.
|
791 | for (int i = 0; i < numChannels; i++) { |
| 128 | 678 | writeId(i, 1); | ||
| 129 | } | |||
| 130 | 113 | write(0); | ||
| 131 | ||||
| 132 | 113 | write(BLOCK); | ||
| 133 | ||||
| 134 | 113 | writeId(0, 0); | ||
| 135 | 113 | write(0); | ||
| 136 | 113 | write(0); | ||
| 137 | ||||
| 138 | 113 | } | ||
| 139 | ||||
| 140 | 2147 | static void writeDouble(double value) { | ||
| 141 | static_assert(sizeof(double) == 8); | |||
| 142 | ||||
| 143 |
2/2✓ Branch 0 taken 1356 times.
✓ Branch 1 taken 791 times.
|
2/2✓ Decision 'true' taken 1356 times.
✓ Decision 'false' taken 791 times.
|
2147 | if (value == 0.0) { |
| 144 | 1356 | writeByte(0); | ||
| 145 | } else { | |||
| 146 | 791 | writeByte(8); | ||
| 147 | 791 | char *ptr = (char*) (void*) &value; | ||
| 148 | ||||
| 149 |
2/2✓ Branch 0 taken 6328 times.
✓ Branch 1 taken 791 times.
|
2/2✓ Decision 'true' taken 6328 times.
✓ Decision 'false' taken 791 times.
|
7119 | for (int i = 0; i < 8; i++) { |
| 150 | 6328 | writeByte(ptr[i]); | ||
| 151 | } | |||
| 152 | } | |||
| 153 | 2147 | } | ||
| 154 | ||||
| 155 | 678 | static void writeChannelHeader(int ch) { | ||
| 156 | 678 | write(0xff); | ||
| 157 | 678 | write(ch); | ||
| 158 | 678 | writeString(channelNames[ch]); | ||
| 159 | 678 | write(0, 2); | ||
| 160 | 678 | writeDouble(1.0); | ||
| 161 | 678 | write(0); | ||
| 162 | 678 | writeDouble(0.0); | ||
| 163 | 678 | write(1); // or 2 | ||
| 164 | 678 | writeDouble(0.0); // or 1.0 | ||
| 165 | ||||
| 166 | // this part sounds like the 'next' pointer? | |||
| 167 |
2/2✓ Branch 0 taken 113 times.
✓ Branch 1 taken 565 times.
|
2/2✓ Decision 'true' taken 113 times.
✓ Decision 'false' taken 565 times.
|
678 | if (ch == numChannels - 1) { |
| 168 | 113 | write(0); | ||
| 169 | } else { | |||
| 170 | 565 | writeId(1 + ch, 1); | ||
| 171 |
2/2✓ Branch 0 taken 1695 times.
✓ Branch 1 taken 565 times.
|
2/2✓ Decision 'true' taken 1695 times.
✓ Decision 'false' taken 565 times.
|
2260 | for (int i = 0; i < 3; i++) { |
| 172 | 1695 | write((CHANNEL_FLAGS[ch] >> (i * 8)) & 0xff); | ||
| 173 | } | |||
| 174 | } | |||
| 175 | 678 | } | ||
| 176 | ||||
| 177 | 678 | static void writeEdges(int64_t *chDeltas, bool useLongDeltas, int numEdges) { | ||
| 178 |
2/2✓ Branch 0 taken 77086 times.
✓ Branch 1 taken 678 times.
|
2/2✓ Decision 'true' taken 77086 times.
✓ Decision 'false' taken 678 times.
|
77764 | for (int i = 0; i < numEdges; i++) { |
| 179 | 77086 | uint64_t d = chDeltas[i]; | ||
| 180 | ||||
| 181 | // set 16-bit 'sign' flag | |||
| 182 |
4/4✓ Branch 0 taken 10 times.
✓ Branch 1 taken 77076 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 5 times.
|
2/2✓ Decision 'true' taken 5 times.
✓ Decision 'false' taken 77081 times.
|
77086 | if (!useLongDeltas && (d & SIGN_FLAG) == SIGN_FLAG) |
| 183 | 5 | d = (d & 0x7fff) | (SIGN_FLAG >> 16); | ||
| 184 | 77086 | writeByte((uint8_t) (d & 0xff)); | ||
| 185 | 77086 | writeByte((uint8_t) ((d >> 8) & 0xff)); | ||
| 186 |
2/2✓ Branch 0 taken 77076 times.
✓ Branch 1 taken 10 times.
|
2/2✓ Decision 'true' taken 77076 times.
✓ Decision 'false' taken 10 times.
|
77086 | if (useLongDeltas) { |
| 187 | 77076 | writeByte((uint8_t) ((d >> 16) & 0xff)); | ||
| 188 | 77076 | writeByte((uint8_t) ((d >> 24) & 0xff)); | ||
| 189 | } | |||
| 190 | } | |||
| 191 | 678 | writeByte(0x00); | ||
| 192 | 678 | } | ||
| 193 | ||||
| 194 | 1059 | static void writeRaw(int value, int num) { | ||
| 195 |
2/2✓ Branch 0 taken 5648 times.
✓ Branch 1 taken 1059 times.
|
2/2✓ Decision 'true' taken 5648 times.
✓ Decision 'false' taken 1059 times.
|
6707 | for (int i = 0; i < num; i++) { |
| 196 | 5648 | writeByte(value); | ||
| 197 | } | |||
| 198 | 1059 | } | ||
| 199 | ||||
| 200 | 678 | static void writeChannelData(int ch, int64_t *chDeltas, int chLastState, | ||
| 201 | int lastRecord, bool useLongDeltas, int numEdges) { | |||
| 202 |
2/2✓ Branch 0 taken 325 times.
✓ Branch 1 taken 353 times.
|
2/2✓ Decision 'true' taken 325 times.
✓ Decision 'false' taken 353 times.
|
678 | if (numEdges == 0) |
| 203 | 325 | lastRecord = 0; | ||
| 204 | 678 | write(CHANNEL_BLOCK); | ||
| 205 | // channel#0 is somehow special... | |||
| 206 |
2/2✓ Branch 0 taken 113 times.
✓ Branch 1 taken 565 times.
|
2/2✓ Decision 'true' taken 113 times.
✓ Decision 'false' taken 565 times.
|
678 | if (ch == 0) { |
| 207 | 113 | write(SUB); | ||
| 208 | 113 | write(BLOCK); | ||
| 209 | } | |||
| 210 | ||||
| 211 | 678 | write(ch + 1); | ||
| 212 | 678 | write(0); | ||
| 213 | 678 | write(realDurationInSamples); | ||
| 214 | 678 | write(1); | ||
| 215 | 678 | write(lastRecord); | ||
| 216 | ||||
| 217 | 678 | uint32_t numSamplesLeft = realDurationInSamples - lastRecord; | ||
| 218 | 678 | write(numSamplesLeft); | ||
| 219 | ||||
| 220 | 678 | write(chLastState); | ||
| 221 | ||||
| 222 | 678 | int chFlag = | ||
| 223 |
2/2✓ Branch 0 taken 353 times.
✓ Branch 1 taken 325 times.
|
1031 | (numEdges == 0) ? | |
| 224 | FLAG_EMPTY : | |||
| 225 |
2/2✓ Branch 0 taken 351 times.
✓ Branch 1 taken 2 times.
|
353 | (useLongDeltas ? FLAG_NOTEMPTY_LONG : FLAG_NOTEMPTY); | |
| 226 | 678 | write(chFlag); | ||
| 227 | ||||
| 228 |
2/2✓ Branch 0 taken 113 times.
✓ Branch 1 taken 565 times.
|
2/2✓ Decision 'true' taken 113 times.
✓ Decision 'false' taken 565 times.
|
678 | if (ch == 0) { |
| 229 | 113 | write(0); | ||
| 230 | 113 | write(BLOCK); | ||
| 231 | 113 | write(0, 11); | ||
| 232 |
2/2✓ Branch 0 taken 111 times.
✓ Branch 1 taken 2 times.
|
2/2✓ Decision 'true' taken 111 times.
✓ Decision 'false' taken 2 times.
|
113 | if (useLongDeltas) { |
| 233 | 111 | write(BLOCK); | ||
| 234 | 111 | write(0, 6); | ||
| 235 | } | |||
| 236 | 113 | write(BLOCK); | ||
| 237 | } else { | |||
| 238 | 565 | write(0, 10); | ||
| 239 |
2/2✓ Branch 0 taken 558 times.
✓ Branch 1 taken 7 times.
|
2/2✓ Decision 'true' taken 558 times.
✓ Decision 'false' taken 7 times.
|
565 | if (useLongDeltas) { |
| 240 | 558 | write(0, 5); | ||
| 241 | } | |||
| 242 | } | |||
| 243 | ||||
| 244 | 678 | write(numEdges); | ||
| 245 | 678 | write(0); | ||
| 246 | 678 | write(numEdges); | ||
| 247 | 678 | write(0); | ||
| 248 | 678 | write(numEdges); | ||
| 249 | ||||
| 250 | 678 | writeEdges(chDeltas, useLongDeltas, numEdges); | ||
| 251 | ||||
| 252 |
2/2✓ Branch 0 taken 113 times.
✓ Branch 1 taken 565 times.
|
2/2✓ Decision 'true' taken 113 times.
✓ Decision 'false' taken 565 times.
|
678 | if (ch == 0) { |
| 253 | 113 | write(BLOCK); | ||
| 254 | 113 | write(0, 6); | ||
| 255 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 111 times.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 111 times.
|
113 | if (!useLongDeltas) { |
| 256 | 2 | write(BLOCK); | ||
| 257 | 2 | write(0, 6); | ||
| 258 | } | |||
| 259 | 113 | write(BLOCK); | ||
| 260 | } else { | |||
| 261 | 565 | write(0, 4); | ||
| 262 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 558 times.
|
2/2✓ Decision 'true' taken 7 times.
✓ Decision 'false' taken 558 times.
|
565 | if (!useLongDeltas) { |
| 263 | 7 | write(0, 5); | ||
| 264 | } | |||
| 265 | } | |||
| 266 | ||||
| 267 |
2/2✓ Branch 0 taken 325 times.
✓ Branch 1 taken 353 times.
|
2/2✓ Decision 'true' taken 325 times.
✓ Decision 'false' taken 353 times.
|
678 | if (numEdges == 0) { |
| 268 | 325 | write(0, 5); | ||
| 269 | 325 | return; | ||
| 270 | } | |||
| 271 | ||||
| 272 | 353 | write(1); | ||
| 273 | 353 | write(0); | ||
| 274 | 353 | write(1); | ||
| 275 | 353 | write(0); | ||
| 276 | 353 | write(1); | ||
| 277 | 353 | write(0, 16); | ||
| 278 | ||||
| 279 | 353 | writeRaw(0xFF, 8); | ||
| 280 | 353 | writeRaw(chFlag, 1); | ||
| 281 | 353 | writeRaw(0x00, 7); | ||
| 282 | } | |||
| 283 | ||||
| 284 | 113 | static void writeChannelDataHeader() { | ||
| 285 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(BLOCK); | |
| 286 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(scaledDurationInSamples); | |
| 287 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0, 5); | |
| 288 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(numChannels); | |
| 289 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0, 3); | |
| 290 |
1/1✓ Branch 1 taken 113 times.
|
113 | writeId(0, 1); | |
| 291 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0); | |
| 292 | ||||
| 293 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(BLOCK); | |
| 294 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0, 3); | |
| 295 | ||||
| 296 |
2/2✓ Branch 0 taken 678 times.
✓ Branch 1 taken 113 times.
|
2/2✓ Decision 'true' taken 678 times.
✓ Decision 'false' taken 113 times.
|
791 | for (int i = 0; i < numChannels; i++) { |
| 297 |
1/1✓ Branch 1 taken 678 times.
|
678 | writeChannelHeader(i); | |
| 298 | } | |||
| 299 | ||||
| 300 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(BLOCK); | |
| 301 | 113 | int SUB_ARRAY[] = { SUB, SUB, 0, SUB, 0, SUB }; | ||
| 302 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(SUB_ARRAY, 6); | |
| 303 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0, 6); | |
| 304 | ||||
| 305 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(BLOCK); | |
| 306 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0, 2); | |
| 307 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(realDurationInSamples); | |
| 308 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0); | |
| 309 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(SUB); | |
| 310 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(reservedDurationInSamples); | |
| 311 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(frequency / frequencyDiv); | |
| 312 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0, 2); | |
| 313 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(SUB); | |
| 314 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0, 2); | |
| 315 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(1); | |
| 316 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0, 3); | |
| 317 |
1/1✓ Branch 1 taken 113 times.
|
113 | writeId(0, 0); | |
| 318 | ||||
| 319 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(BLOCK); | |
| 320 | 113 | int SAM_ARRAY[] = { (int)realDurationInSamples, (int)realDurationInSamples, | ||
| 321 | 113 | (int)realDurationInSamples }; | ||
| 322 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(SAM_ARRAY, 3); | |
| 323 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0); | |
| 324 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(SUB); | |
| 325 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0); | |
| 326 | ||||
| 327 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(BLOCK); | |
| 328 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0); | |
| 329 | ||||
| 330 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(BLOCK); | |
| 331 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(SUB, 4); | |
| 332 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0); | |
| 333 | ||||
| 334 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(BLOCK); | |
| 335 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(frequency); | |
| 336 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0, 3); | |
| 337 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(1); | |
| 338 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0, 3); | |
| 339 |
1/1✓ Branch 1 taken 113 times.
|
113 | writeId(0, 0); | |
| 340 | 113 | int ARR_6[] = { 0, 1, 1, 0, 1, 0x13 }; | ||
| 341 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(ARR_6, 6); | |
| 342 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(SUB); | |
| 343 | ||||
| 344 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(BLOCK); | |
| 345 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0); | |
| 346 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(realDurationInSamples); | |
| 347 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(0, 2); | |
| 348 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(numChannels); | |
| 349 | 113 | int ARR_3[] = { 1, 0, 1 }; | ||
| 350 |
1/1✓ Branch 1 taken 113 times.
|
113 | write(ARR_3, 3); | |
| 351 | 113 | } | ||
| 352 | ||||
| 353 | 113 | static void writeTimingMarker() { | ||
| 354 | 113 | write(BLOCK); | ||
| 355 | 113 | write(numChannels + 2); | ||
| 356 | 113 | write(0, 4); | ||
| 357 | 113 | writeString("Timing Marker Pair"); | ||
| 358 | 113 | writeString("A1"); | ||
| 359 | 113 | writeString("A2"); | ||
| 360 | 113 | write(0, 2); | ||
| 361 | 113 | write(SUB); | ||
| 362 | 113 | write(0, 9); | ||
| 363 | 113 | } | ||
| 364 | ||||
| 365 | 113 | static void writeChannelDataFooter() { | ||
| 366 | 113 | write(0, 3); | ||
| 367 | 113 | write(1); | ||
| 368 | 113 | write(1); | ||
| 369 | 113 | write(0); | ||
| 370 | 113 | write(numChannels); | ||
| 371 | 113 | } | ||
| 372 | ||||
| 373 | 997920 | int getChannelState(int ch, const CompositeEvent* event) { | ||
| 374 |
6/7✓ Branch 0 taken 166320 times.
✓ Branch 1 taken 166320 times.
✓ Branch 2 taken 166320 times.
✓ Branch 3 taken 166320 times.
✓ Branch 4 taken 166320 times.
✓ Branch 5 taken 166320 times.
✗ Branch 6 not taken.
|
997920 | switch (ch) { | |
| 375 |
1/1✓ Decision 'true' taken 166320 times.
|
166320 | case 0: | |
| 376 | 166320 | return event->primaryTrigger; | ||
| 377 |
1/1✓ Decision 'true' taken 166320 times.
|
166320 | case 1: | |
| 378 | 166320 | return event->secondaryTrigger; | ||
| 379 |
1/1✓ Decision 'true' taken 166320 times.
|
166320 | case 2: | |
| 380 | 166320 | return event->isTDC; | ||
| 381 |
1/1✓ Decision 'true' taken 166320 times.
|
166320 | case 3: | |
| 382 | 166320 | return event->sync; | ||
| 383 |
1/1✓ Decision 'true' taken 166320 times.
|
166320 | case 4: | |
| 384 | 166320 | return event->coil; | ||
| 385 |
1/1✓ Decision 'true' taken 166320 times.
|
166320 | case 5: | |
| 386 | 166320 | return event->injector; | ||
| 387 | } | |||
| 388 | ✗ | return -1; | ||
| 389 | } | |||
| 390 | ||||
| 391 | 113 | static void writeEvents(const std::vector<CompositeEvent>& events) { | ||
| 392 | 113 | size_t count = events.size(); | ||
| 393 | // we need at least 2 records | |||
| 394 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 113 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 113 times.
|
113 | if (count < 2) |
| 395 | ✗ | return; | ||
| 396 | 113 | uint32_t firstRecordTs = events[1].timestamp; | ||
| 397 | 113 | uint32_t lastRecordTs = events[count - 1].timestamp; | ||
| 398 | // we don't know the total duration, so we create a margin after the last record which equals to the duration of the first event | |||
| 399 | 113 | realDurationInSamples = lastRecordTs + firstRecordTs; | ||
| 400 | 113 | scaledDurationInSamples = realDurationInSamples / 4; | ||
| 401 | ||||
| 402 | 113 | writeChannelDataHeader(); | ||
| 403 | ||||
| 404 | 113 | int64_t *chDeltas = (int64_t*) malloc(sizeof(int64_t) * count); | ||
| 405 | ||||
| 406 | 113 | bool useLongDeltas = false; | ||
| 407 |
2/2✓ Branch 0 taken 678 times.
✓ Branch 1 taken 113 times.
|
2/2✓ Decision 'true' taken 678 times.
✓ Decision 'false' taken 113 times.
|
791 | for (int ch = 0; ch < numChannels; ch++) { |
| 408 | 678 | int chPrevState = -1; | ||
| 409 | 678 | uint32_t prevTs = 0; | ||
| 410 | 678 | int deltaCount = 0; | ||
| 411 | ||||
| 412 |
2/2✓ Branch 0 taken 498960 times.
✓ Branch 1 taken 678 times.
|
2/2✓ Decision 'true' taken 498960 times.
✓ Decision 'false' taken 678 times.
|
499638 | for (size_t i = 0; i < count; i++) { |
| 413 | 498960 | const CompositeEvent* event = &events[i]; | ||
| 414 | ||||
| 415 | 498960 | int chState = getChannelState(ch, event); | ||
| 416 | 498960 | uint32_t ts = event->timestamp; | ||
| 417 | ||||
| 418 |
2/2✓ Branch 0 taken 678 times.
✓ Branch 1 taken 498282 times.
|
2/2✓ Decision 'true' taken 678 times.
✓ Decision 'false' taken 498282 times.
|
498960 | if (chPrevState == -1) { |
| 419 | 678 | chPrevState = chState; | ||
| 420 | } | |||
| 421 |
2/2✓ Branch 0 taken 77086 times.
✓ Branch 1 taken 421874 times.
|
2/2✓ Decision 'true' taken 77086 times.
✓ Decision 'false' taken 421874 times.
|
498960 | if (chState != chPrevState) { |
| 422 | 77086 | int64_t delta = ts - prevTs; | ||
| 423 |
2/2✓ Branch 0 taken 69924 times.
✓ Branch 1 taken 7162 times.
|
2/2✓ Decision 'true' taken 69924 times.
✓ Decision 'false' taken 7162 times.
|
77086 | if (delta > 0x7fff) { |
| 424 | 69924 | useLongDeltas = true; | ||
| 425 | } | |||
| 426 | // encode state | |||
| 427 |
2/2✓ Branch 0 taken 38523 times.
✓ Branch 1 taken 38563 times.
|
2/2✓ Decision 'true' taken 38523 times.
✓ Decision 'false' taken 38563 times.
|
77086 | if (chState == 0) |
| 428 | 38523 | delta |= SIGN_FLAG; | ||
| 429 | ||||
| 430 | 77086 | chDeltas[deltaCount++] = delta; | ||
| 431 | ||||
| 432 | 77086 | prevTs = ts; | ||
| 433 | 77086 | chPrevState = chState; | ||
| 434 | } | |||
| 435 | } | |||
| 436 | 678 | writeChannelData(ch, chDeltas, chPrevState, prevTs, useLongDeltas, | ||
| 437 | deltaCount); | |||
| 438 | } | |||
| 439 | ||||
| 440 | 113 | free(chDeltas); | ||
| 441 | ||||
| 442 | 113 | writeChannelDataFooter(); | ||
| 443 | } | |||
| 444 | ||||
| 445 | 113 | static void writeFooter() { | ||
| 446 | 113 | write(BLOCK); | ||
| 447 |
2/2✓ Branch 0 taken 678 times.
✓ Branch 1 taken 113 times.
|
2/2✓ Decision 'true' taken 678 times.
✓ Decision 'false' taken 113 times.
|
791 | for (int i = 0; i < numChannels; i++) { |
| 448 | 678 | writeId(i, 1); | ||
| 449 | } | |||
| 450 | 113 | write(1); | ||
| 451 | 113 | writeId(numChannels, 0x15); | ||
| 452 |
2/2✓ Branch 0 taken 678 times.
✓ Branch 1 taken 113 times.
|
2/2✓ Decision 'true' taken 678 times.
✓ Decision 'false' taken 113 times.
|
791 | for (int i = 0; i < numChannels; i++) { |
| 453 | 678 | writeId(i, 1); | ||
| 454 | } | |||
| 455 | 113 | write(1); | ||
| 456 | 113 | write(0); | ||
| 457 | 113 | write(frequency); | ||
| 458 | 113 | write(0, 16); | ||
| 459 | 113 | write(0x01); | ||
| 460 | 113 | write(0x23); // ??? | ||
| 461 | 113 | write(SUB); | ||
| 462 | ||||
| 463 | 113 | write(BLOCK); | ||
| 464 | 113 | write(numChannels + 1); | ||
| 465 | 113 | write(0); | ||
| 466 | 113 | write(0xFFFFFFFFFFFFFFFFL); | ||
| 467 | 113 | write(0xFFFFFFFFL); | ||
| 468 | 113 | write(1); | ||
| 469 | 113 | write(0, 3); | ||
| 470 | ||||
| 471 | 113 | write(BLOCK); | ||
| 472 | 113 | write(0); | ||
| 473 | ||||
| 474 | 113 | write(BLOCK); | ||
| 475 | 113 | write(0); | ||
| 476 | 113 | writeDouble(1.0); | ||
| 477 | 113 | write(SUB); | ||
| 478 | 113 | write(0, 6); | ||
| 479 | 113 | write(1); | ||
| 480 | 113 | write(0, 4); | ||
| 481 | ||||
| 482 | 113 | write(1); | ||
| 483 | 113 | write(0x29); // ??? | ||
| 484 | 113 | write(SUB); | ||
| 485 | ||||
| 486 | 113 | writeTimingMarker(); | ||
| 487 | 113 | } | ||
| 488 | ||||
| 489 | 113 | void writeLogicDataFile(const char * fileName, const std::vector<CompositeEvent>& events) { | ||
| 490 | ||||
| 491 | 113 | ptr = fopen(fileName, "wb"); | ||
| 492 | ||||
| 493 | 113 | writeHeader(); | ||
| 494 | 113 | writeEvents(events); | ||
| 495 | 113 | writeFooter(); | ||
| 496 | ||||
| 497 | 113 | fclose(ptr); | ||
| 498 | ||||
| 499 | 113 | } | ||
| 500 |