[webftr-js8-lab] command=data-frame-text-unpack-probe [webftr-js8-lab] root=/decoders/js8_decoder [webftr-js8-lab] log=/decoders/js8_decoder/logs/20260527T183331Z_data-frame-text-unpack-probe.log [webftr-js8-lab] manifest=/decoders/js8_decoder/logs/20260527T183331Z_data-frame-text-unpack-probe_manifest.json [webftr-js8-lab] utc=20260527T183331Z [webftr-js8-lab] rx-only guard: no TX / no PTT / no Tune / no Send [webftr-js8-lab] Step70 guarded JS8 data-frame text unpack probe [webftr-js8-lab] input Step66/Step68/Step69 JSON or source-dir argument: auto-detect latest logs/source [webftr-js8-lab] JSON output: /decoders/js8_decoder/logs/20260527T183331Z_jsc_decompress_source_audit_output.json [webftr-js8-lab] JSON timeout guard: 180s { "ok": true, "tool": "webftr-js8-jsc-decompress-source-audit-probe", "tool_version": "step69-jsc-decompress-source-audit-probe", "schema": "webftr-js8-jsc-decompress-source-audit-v1", "rx_only_guard": { "tx": false, "ptt": false, "tune": false, "send": false, "js8call_runtime_control": false, "webftr_productive_integration": false }, "no_gui_runtime_started": true, "root": "/decoders/js8_decoder", "log_dir": "/decoders/js8_decoder/logs", "source_resolution": { "source_dir": "/decoders/js8_decoder/runtime/src/JS8Call-improved", "source_found": true, "checked": [ { "path": "/decoders/js8_decoder/runtime/src/JS8Call-improved", "exists": true, "is_dir": true } ], "focused_files_present": [ "JS8_Main/Varicode.cpp", "JS8_Main/Varicode.h", "JS8_JSC/JSC.cpp", "JS8_JSC/JSC.h", "JS8_JSC/JSC_map.cpp", "JS8_JSC/JSC_list.cpp", "JS8_Mode/JS8.cpp", "JS8_Mode/JS8.h" ], "focused_files_missing": [ "JS8_JSC/jsc.cpp", "JS8_JSC/jsc.h" ] }, "input_reports": [ { "path": "/decoders/js8_decoder/logs/20260527T181644Z_webftr_rx_ui_contract_output.json", "exists": true, "selected_latest_step68": true } ], "frame_inventory": { "frame_type_counts": { "FrameHeartbeat": 2, "FrameDirected": 2 }, "data_frame_candidates": [], "data_frame_candidate_count": 0, "current_fixture_has_data_frames": false }, "jsc_decode_path_evidence": { "has_jsc_decompress_reference": true, "has_unpack_fast_data_message": true, "has_unpack_legacy_data_message": true, "has_huff_fallback_evidence": true, "expected_source_flow": [ "unpack72bits(message174_text) -> 72 bits", "FrameData/FrameDataCompressed bits are trimmed at the final zero padding marker", "compressed path calls JSC::decompress(bits)", "legacy non-compressed path uses Varicode::huffDecode(defaultHuffTable, bits)", "Step69 does not yet display free text; it only extracts and documents the source path for a safe Step70 port." ] }, "source_snippets": [ { "keyword": "JSC::decompress", "path": "JS8_Main/Varicode.cpp", "line": 1938, "context": { "start_line": 1933, "end_line": 1943, "lines": [ { "line": 1933, "text": " // trim off the pad bits" }, { "line": 1934, "text": " bits = bits.mid(1, n - 1);" }, { "line": 1935, "text": "" }, { "line": 1936, "text": " if (compressed) {" }, { "line": 1937, "text": " // partial word (s,c)-dense coding with code tables" }, { "line": 1938, "text": " unpacked = JSC::decompress(bits);" }, { "line": 1939, "text": " } else {" }, { "line": 1940, "text": " // huff decode the bits (without escapes)" }, { "line": 1941, "text": " unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);" }, { "line": 1942, "text": " }" }, { "line": 1943, "text": "" } ] } }, { "keyword": "JSC::decompress", "path": "JS8_Main/Varicode.cpp", "line": 2003, "context": { "start_line": 1998, "end_line": 2008, "lines": [ { "line": 1998, "text": " // trim off the pad bits" }, { "line": 1999, "text": " bits = bits.mid(1, n - 1);" }, { "line": 2000, "text": "" }, { "line": 2001, "text": " if (compressed) {" }, { "line": 2002, "text": " // partial word (s,c)-dense coding with code tables" }, { "line": 2003, "text": " unpacked = JSC::decompress(bits);" }, { "line": 2004, "text": " } else {" }, { "line": 2005, "text": " // huff decode the bits (without escapes)" }, { "line": 2006, "text": " unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);" }, { "line": 2007, "text": " }" }, { "line": 2008, "text": "#else" } ] } }, { "keyword": "JSC::decompress", "path": "JS8_Main/Varicode.cpp", "line": 2015, "context": { "start_line": 2010, "end_line": 2020, "lines": [ { "line": 2010, "text": "" }, { "line": 2011, "text": " // trim off the pad bits" }, { "line": 2012, "text": " bits = bits.mid(0, n);" }, { "line": 2013, "text": "" }, { "line": 2014, "text": " // partial word (s,c)-dense coding with code tables" }, { "line": 2015, "text": " unpacked = JSC::decompress(bits);" }, { "line": 2016, "text": "#endif" }, { "line": 2017, "text": "" }, { "line": 2018, "text": " return unpacked;" }, { "line": 2019, "text": "}" }, { "line": 2020, "text": "" } ] } }, { "keyword": "JSC::compress", "path": "JS8_Main/Varicode.cpp", "line": 1849, "context": { "start_line": 1844, "end_line": 1854, "lines": [ { "line": 1844, "text": " if (!prefix.isEmpty()) {" }, { "line": 1845, "text": " frameBits << prefix;" }, { "line": 1846, "text": " }" }, { "line": 1847, "text": "" }, { "line": 1848, "text": " int i = 0;" }, { "line": 1849, "text": " foreach (auto pair, JSC::compress(input)) {" }, { "line": 1850, "text": " auto bits = pair.first;" }, { "line": 1851, "text": " auto chars = pair.second;" }, { "line": 1852, "text": "" }, { "line": 1853, "text": " if (frameBits.length() + bits.length() < frameSize) {" }, { "line": 1854, "text": " frameBits.append(bits);" } ] } }, { "keyword": "unpackDataMessage", "path": "JS8_Main/Varicode.cpp", "line": 1912, "context": { "start_line": 1907, "end_line": 1917, "lines": [ { "line": 1907, "text": "}" }, { "line": 1908, "text": "" }, { "line": 1909, "text": "// TODO: DEPRECATED in 2.2 (still available for decoding legacy frames, but will" }, { "line": 1910, "text": "// eventually no longer be decodable) unpack data message using 70 bits" }, { "line": 1911, "text": "// available flagged as data by the first 2 bits" }, { "line": 1912, "text": "QString Varicode::unpackDataMessage(const QString &text) {" }, { "line": 1913, "text": " QString unpacked;" }, { "line": 1914, "text": "" }, { "line": 1915, "text": " if (text.length() < 12 || text.contains(\" \")) {" }, { "line": 1916, "text": " return unpacked;" }, { "line": 1917, "text": " }" } ] } }, { "keyword": "unpackFastDataMessage", "path": "JS8_Main/Varicode.cpp", "line": 1983, "context": { "start_line": 1978, "end_line": 1988, "lines": [ { "line": 1978, "text": "#endif" }, { "line": 1979, "text": "}" }, { "line": 1980, "text": "" }, { "line": 1981, "text": "// unpack data message using the full 72 bits available (with the data flag in" }, { "line": 1982, "text": "// the i3bit header)" }, { "line": 1983, "text": "QString Varicode::unpackFastDataMessage(const QString &text) {" }, { "line": 1984, "text": " QString unpacked;" }, { "line": 1985, "text": "" }, { "line": 1986, "text": " if (text.length() < 12 || text.contains(\" \")) {" }, { "line": 1987, "text": " return unpacked;" }, { "line": 1988, "text": " }" } ] } }, { "keyword": "packCompressedMessage", "path": "JS8_Main/Varicode.cpp", "line": 1830, "context": { "start_line": 1825, "end_line": 1835, "lines": [ { "line": 1825, "text": " *n = i;" }, { "line": 1826, "text": "" }, { "line": 1827, "text": " return frame;" }, { "line": 1828, "text": "}" }, { "line": 1829, "text": "" }, { "line": 1830, "text": "QString packCompressedMessage(const QString &input, QVector prefix," }, { "line": 1831, "text": " int *n) {" }, { "line": 1832, "text": " static const int frameSize = 72;" }, { "line": 1833, "text": "" }, { "line": 1834, "text": " QString frame;" }, { "line": 1835, "text": "" } ] } }, { "keyword": "packCompressedMessage", "path": "JS8_Main/Varicode.cpp", "line": 1896, "context": { "start_line": 1891, "end_line": 1901, "lines": [ { "line": 1891, "text": " huffFrame = packHuffMessage(input, {true, false}, &huffChars);" }, { "line": 1892, "text": "" }, { "line": 1893, "text": " QString compressedFrame;" }, { "line": 1894, "text": " int compressedChars = 0;" }, { "line": 1895, "text": " compressedFrame =" }, { "line": 1896, "text": " packCompressedMessage(input, {true, true}, &compressedChars);" }, { "line": 1897, "text": "" }, { "line": 1898, "text": " if (huffChars > compressedChars) {" }, { "line": 1899, "text": " if (n)" }, { "line": 1900, "text": " *n = huffChars;" }, { "line": 1901, "text": " return huffFrame;" } ] } }, { "keyword": "packCompressedMessage", "path": "JS8_Main/Varicode.cpp", "line": 1959, "context": { "start_line": 1954, "end_line": 1964, "lines": [ { "line": 1954, "text": " int huffChars = 0;" }, { "line": 1955, "text": " huffFrame = packHuffMessage(input, {false}, &huffChars);" }, { "line": 1956, "text": "" }, { "line": 1957, "text": " QString compressedFrame;" }, { "line": 1958, "text": " int compressedChars = 0;" }, { "line": 1959, "text": " compressedFrame = packCompressedMessage(input, {true}, &compressedChars);" }, { "line": 1960, "text": "" }, { "line": 1961, "text": " if (huffChars > compressedChars) {" }, { "line": 1962, "text": " if (n)" }, { "line": 1963, "text": " *n = huffChars;" }, { "line": 1964, "text": " return huffFrame;" } ] } }, { "keyword": "packCompressedMessage", "path": "JS8_Main/Varicode.cpp", "line": 1973, "context": { "start_line": 1968, "end_line": 1978, "lines": [ { "line": 1968, "text": " return compressedFrame;" }, { "line": 1969, "text": " }" }, { "line": 1970, "text": "#else" }, { "line": 1971, "text": " QString compressedFrame;" }, { "line": 1972, "text": " int compressedChars = 0;" }, { "line": 1973, "text": " compressedFrame = packCompressedMessage(input, {}, &compressedChars);" }, { "line": 1974, "text": "" }, { "line": 1975, "text": " if (n)" }, { "line": 1976, "text": " *n = compressedChars;" }, { "line": 1977, "text": " return compressedFrame;" }, { "line": 1978, "text": "#endif" } ] } }, { "keyword": "packHuffMessage", "path": "JS8_Main/Varicode.cpp", "line": 1762, "context": { "start_line": 1757, "end_line": 1767, "lines": [ { "line": 1757, "text": " if (pType)" }, { "line": 1758, "text": " *pType = packed_flag;" }, { "line": 1759, "text": " return unpacked;" }, { "line": 1760, "text": "}" }, { "line": 1761, "text": "" }, { "line": 1762, "text": "QString packHuffMessage(const QString &input, const QVector prefix," }, { "line": 1763, "text": " int *n) {" }, { "line": 1764, "text": " static const int frameSize = 72;" }, { "line": 1765, "text": "" }, { "line": 1766, "text": " QString frame;" }, { "line": 1767, "text": "" } ] } }, { "keyword": "packHuffMessage", "path": "JS8_Main/Varicode.cpp", "line": 1891, "context": { "start_line": 1886, "end_line": 1896, "lines": [ { "line": 1886, "text": "// TODO: DEPRECATED in 2.2 (we will eventually stop transmitting these frames)" }, { "line": 1887, "text": "// pack data message using 70 bits available flagged as data by the first 2 bits" }, { "line": 1888, "text": "QString Varicode::packDataMessage(const QString &input, int *n) {" }, { "line": 1889, "text": " QString huffFrame;" }, { "line": 1890, "text": " int huffChars = 0;" }, { "line": 1891, "text": " huffFrame = packHuffMessage(input, {true, false}, &huffChars);" }, { "line": 1892, "text": "" }, { "line": 1893, "text": " QString compressedFrame;" }, { "line": 1894, "text": " int compressedChars = 0;" }, { "line": 1895, "text": " compressedFrame =" }, { "line": 1896, "text": " packCompressedMessage(input, {true, true}, &compressedChars);" } ] } }, { "keyword": "packHuffMessage", "path": "JS8_Main/Varicode.cpp", "line": 1955, "context": { "start_line": 1950, "end_line": 1960, "lines": [ { "line": 1950, "text": "// i3bit header)" }, { "line": 1951, "text": "QString Varicode::packFastDataMessage(const QString &input, int *n) {" }, { "line": 1952, "text": "#if JS8_FAST_DATA_CAN_USE_HUFF" }, { "line": 1953, "text": " QString huffFrame;" }, { "line": 1954, "text": " int huffChars = 0;" }, { "line": 1955, "text": " huffFrame = packHuffMessage(input, {false}, &huffChars);" }, { "line": 1956, "text": "" }, { "line": 1957, "text": " QString compressedFrame;" }, { "line": 1958, "text": " int compressedChars = 0;" }, { "line": 1959, "text": " compressedFrame = packCompressedMessage(input, {true}, &compressedChars);" }, { "line": 1960, "text": "" } ] } }, { "keyword": "huffDecode", "path": "JS8_Main/Varicode.cpp", "line": 597, "context": { "start_line": 592, "end_line": 602, "lines": [ { "line": 592, "text": " }" }, { "line": 593, "text": "" }, { "line": 594, "text": " return out;" }, { "line": 595, "text": "}" }, { "line": 596, "text": "" }, { "line": 597, "text": "QString Varicode::huffDecode(QMap const &huff," }, { "line": 598, "text": " QVector const &bitvec) {" }, { "line": 599, "text": " QString text;" }, { "line": 600, "text": "" }, { "line": 601, "text": " QString bits = Varicode::bitsToStr(bitvec);" }, { "line": 602, "text": "" } ] } }, { "keyword": "huffDecode", "path": "JS8_Main/Varicode.cpp", "line": 1941, "context": { "start_line": 1936, "end_line": 1946, "lines": [ { "line": 1936, "text": " if (compressed) {" }, { "line": 1937, "text": " // partial word (s,c)-dense coding with code tables" }, { "line": 1938, "text": " unpacked = JSC::decompress(bits);" }, { "line": 1939, "text": " } else {" }, { "line": 1940, "text": " // huff decode the bits (without escapes)" }, { "line": 1941, "text": " unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);" }, { "line": 1942, "text": " }" }, { "line": 1943, "text": "" }, { "line": 1944, "text": " return unpacked;" }, { "line": 1945, "text": "}" }, { "line": 1946, "text": "" } ] } }, { "keyword": "huffDecode", "path": "JS8_Main/Varicode.cpp", "line": 2006, "context": { "start_line": 2001, "end_line": 2011, "lines": [ { "line": 2001, "text": " if (compressed) {" }, { "line": 2002, "text": " // partial word (s,c)-dense coding with code tables" }, { "line": 2003, "text": " unpacked = JSC::decompress(bits);" }, { "line": 2004, "text": " } else {" }, { "line": 2005, "text": " // huff decode the bits (without escapes)" }, { "line": 2006, "text": " unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);" }, { "line": 2007, "text": " }" }, { "line": 2008, "text": "#else" }, { "line": 2009, "text": " int n = bits.lastIndexOf(0);" }, { "line": 2010, "text": "" }, { "line": 2011, "text": " // trim off the pad bits" } ] } }, { "keyword": "defaultHuffTable", "path": "JS8_Main/Varicode.cpp", "line": 438, "context": { "start_line": 433, "end_line": 443, "lines": [ { "line": 433, "text": "}" }, { "line": 434, "text": "" }, { "line": 435, "text": "/*" }, { "line": 436, "text": " * VARICODE" }, { "line": 437, "text": " */" }, { "line": 438, "text": "QMap Varicode::defaultHuffTable() { return hufftable; }" }, { "line": 439, "text": "" }, { "line": 440, "text": "QString Varicode::cqString(int number) {" }, { "line": 441, "text": " if (!cqs.contains(number)) {" }, { "line": 442, "text": " return QString{};" }, { "line": 443, "text": " }" } ] } }, { "keyword": "defaultHuffTable", "path": "JS8_Main/Varicode.cpp", "line": 1784, "context": { "start_line": 1779, "end_line": 1789, "lines": [ { "line": 1779, "text": " int i = 0;" }, { "line": 1780, "text": "" }, { "line": 1781, "text": " // only pack huff messages that only contain valid chars" }, { "line": 1782, "text": " QString::const_iterator it;" }, { "line": 1783, "text": " QSet validChars =" }, { "line": 1784, "text": " Varicode::huffValidChars(Varicode::defaultHuffTable());" }, { "line": 1785, "text": " for (it = input.constBegin(); it != input.constEnd(); it++) {" }, { "line": 1786, "text": " auto ch = (*it).toUpper();" }, { "line": 1787, "text": " if (!validChars.contains(ch)) {" }, { "line": 1788, "text": " if (n)" }, { "line": 1789, "text": " *n = 0;" } ] } }, { "keyword": "defaultHuffTable", "path": "JS8_Main/Varicode.cpp", "line": 1796, "context": { "start_line": 1791, "end_line": 1801, "lines": [ { "line": 1791, "text": " }" }, { "line": 1792, "text": " }" }, { "line": 1793, "text": "" }, { "line": 1794, "text": " // pack using the default huff table" }, { "line": 1795, "text": " foreach (auto pair," }, { "line": 1796, "text": " Varicode::huffEncode(Varicode::defaultHuffTable(), input)) {" }, { "line": 1797, "text": " auto charN = pair.first;" }, { "line": 1798, "text": " auto charBits = pair.second;" }, { "line": 1799, "text": " if (frameBits.length() + charBits.length() < frameSize) {" }, { "line": 1800, "text": " frameBits += charBits;" }, { "line": 1801, "text": " i += charN;" } ] } }, { "keyword": "defaultHuffTable", "path": "JS8_Main/Varicode.cpp", "line": 1941, "context": { "start_line": 1936, "end_line": 1946, "lines": [ { "line": 1936, "text": " if (compressed) {" }, { "line": 1937, "text": " // partial word (s,c)-dense coding with code tables" }, { "line": 1938, "text": " unpacked = JSC::decompress(bits);" }, { "line": 1939, "text": " } else {" }, { "line": 1940, "text": " // huff decode the bits (without escapes)" }, { "line": 1941, "text": " unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);" }, { "line": 1942, "text": " }" }, { "line": 1943, "text": "" }, { "line": 1944, "text": " return unpacked;" }, { "line": 1945, "text": "}" }, { "line": 1946, "text": "" } ] } }, { "keyword": "FrameData", "path": "JS8_Main/Varicode.cpp", "line": 1532, "context": { "start_line": 1527, "end_line": 1537, "lines": [ { "line": 1527, "text": "QString Varicode::packCompoundFrame(const QString &callsign, quint8 type," }, { "line": 1528, "text": " quint16 num, quint8 bits3) {" }, { "line": 1529, "text": " QString frame;" }, { "line": 1530, "text": "" }, { "line": 1531, "text": " // needs to be a compound type..." }, { "line": 1532, "text": " if (type == Varicode::FrameData || type == Varicode::FrameDirected) {" }, { "line": 1533, "text": " return frame;" }, { "line": 1534, "text": " }" }, { "line": 1535, "text": "" }, { "line": 1536, "text": " quint8 packed_flag = type;" }, { "line": 1537, "text": " quint64 packed_callsign = Varicode::packAlphaNumeric50(callsign);" } ] } }, { "keyword": "FrameData", "path": "JS8_Main/Varicode.cpp", "line": 1576, "context": { "start_line": 1571, "end_line": 1581, "lines": [ { "line": 1571, "text": " quint8 packed_3 = packed_8 & ((1 << 3) - 1);" }, { "line": 1572, "text": "" }, { "line": 1573, "text": " quint8 packed_flag = Varicode::bitsToInt(bits.mid(0, 3));" }, { "line": 1574, "text": "" }, { "line": 1575, "text": " // needs to be a ping type..." }, { "line": 1576, "text": " if (packed_flag == Varicode::FrameData ||" }, { "line": 1577, "text": " packed_flag == Varicode::FrameDirected) {" }, { "line": 1578, "text": " return unpacked;" }, { "line": 1579, "text": " }" }, { "line": 1580, "text": "" }, { "line": 1581, "text": " quint64 packed_callsign = Varicode::bitsToInt(bits.mid(3, 50));" } ] } }, { "keyword": "JS8CallData", "path": "JS8_Main/Varicode.cpp", "line": 1842, "context": { "start_line": 1837, "end_line": 1847, "lines": [ { "line": 1837, "text": " // The first bit is a flag that indicates this is a data frame, technically" }, { "line": 1838, "text": " // encoded as [100] but, since none of the other frame types start with a 1," }, { "line": 1839, "text": " // we can drop the two zeros and use them for encoding the first two bits of" }, { "line": 1840, "text": " // the actuall data sent. boom! The second bit is a flag that indicates this" }, { "line": 1841, "text": " // is a compressed frame (dense coding) For fast modes, we don't use the" }, { "line": 1842, "text": " // prefix since it is indicated by the JS8CallData flag." }, { "line": 1843, "text": " QVector frameBits;" }, { "line": 1844, "text": " if (!prefix.isEmpty()) {" }, { "line": 1845, "text": " frameBits << prefix;" }, { "line": 1846, "text": " }" }, { "line": 1847, "text": "" } ] } }, { "keyword": "JS8CallData", "path": "JS8_Main/Varicode.cpp", "line": 2307, "context": { "start_line": 2302, "end_line": 2312, "lines": [ { "line": 2302, "text": " }" }, { "line": 2303, "text": " }" }, { "line": 2304, "text": "" }, { "line": 2305, "text": " if (useDat) {" }, { "line": 2306, "text": " // use the standard data frame" }, { "line": 2307, "text": " lineFrames.append({frame, fastDataFrame ? Varicode::JS8CallData" }, { "line": 2308, "text": " : Varicode::JS8Call});" }, { "line": 2309, "text": " line = line.mid(m);" }, { "line": 2310, "text": " }" }, { "line": 2311, "text": " }" }, { "line": 2312, "text": "" } ] } }, { "keyword": "lastIndexOf(0)", "path": "JS8_Main/Varicode.cpp", "line": 1931, "context": { "start_line": 1926, "end_line": 1936, "lines": [ { "line": 1926, "text": " }" }, { "line": 1927, "text": "" }, { "line": 1928, "text": " bits = bits.mid(1);" }, { "line": 1929, "text": "" }, { "line": 1930, "text": " bool compressed = bits.at(0);" }, { "line": 1931, "text": " int n = bits.lastIndexOf(0);" }, { "line": 1932, "text": "" }, { "line": 1933, "text": " // trim off the pad bits" }, { "line": 1934, "text": " bits = bits.mid(1, n - 1);" }, { "line": 1935, "text": "" }, { "line": 1936, "text": " if (compressed) {" } ] } }, { "keyword": "lastIndexOf(0)", "path": "JS8_Main/Varicode.cpp", "line": 1996, "context": { "start_line": 1991, "end_line": 2001, "lines": [ { "line": 1991, "text": " quint64 value = Varicode::unpack72bits(text, &rem);" }, { "line": 1992, "text": " auto bits = Varicode::intToBits(value, 64) + Varicode::intToBits(rem, 8);" }, { "line": 1993, "text": "" }, { "line": 1994, "text": "#if JS8_FAST_DATA_CAN_USE_HUFF" }, { "line": 1995, "text": " bool compressed = bits.at(0);" }, { "line": 1996, "text": " int n = bits.lastIndexOf(0);" }, { "line": 1997, "text": "" }, { "line": 1998, "text": " // trim off the pad bits" }, { "line": 1999, "text": " bits = bits.mid(1, n - 1);" }, { "line": 2000, "text": "" }, { "line": 2001, "text": " if (compressed) {" } ] } }, { "keyword": "lastIndexOf(0)", "path": "JS8_Main/Varicode.cpp", "line": 2009, "context": { "start_line": 2004, "end_line": 2014, "lines": [ { "line": 2004, "text": " } else {" }, { "line": 2005, "text": " // huff decode the bits (without escapes)" }, { "line": 2006, "text": " unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);" }, { "line": 2007, "text": " }" }, { "line": 2008, "text": "#else" }, { "line": 2009, "text": " int n = bits.lastIndexOf(0);" }, { "line": 2010, "text": "" }, { "line": 2011, "text": " // trim off the pad bits" }, { "line": 2012, "text": " bits = bits.mid(0, n);" }, { "line": 2013, "text": "" }, { "line": 2014, "text": " // partial word (s,c)-dense coding with code tables" } ] } }, { "keyword": "bits.mid", "path": "JS8_Main/Varicode.cpp", "line": 614, "context": { "start_line": 609, "end_line": 619, "lines": [ { "line": 609, "text": " text.append(\" \");" }, { "line": 610, "text": " found = false;" }, { "line": 611, "text": " break;" }, { "line": 612, "text": " }" }, { "line": 613, "text": " text.append(key);" }, { "line": 614, "text": " bits = bits.mid(huff[key].length());" }, { "line": 615, "text": " found = true;" }, { "line": 616, "text": " }" }, { "line": 617, "text": " }" }, { "line": 618, "text": " if (!found) {" }, { "line": 619, "text": " break;" } ] } }, { "keyword": "bits.mid", "path": "JS8_Main/Varicode.cpp", "line": 1573, "context": { "start_line": 1568, "end_line": 1578, "lines": [ { "line": 1568, "text": " Varicode::intToBits(Varicode::unpack72bits(text, &packed_8), 64);" }, { "line": 1569, "text": "" }, { "line": 1570, "text": " quint8 packed_5 = packed_8 >> 3;" }, { "line": 1571, "text": " quint8 packed_3 = packed_8 & ((1 << 3) - 1);" }, { "line": 1572, "text": "" }, { "line": 1573, "text": " quint8 packed_flag = Varicode::bitsToInt(bits.mid(0, 3));" }, { "line": 1574, "text": "" }, { "line": 1575, "text": " // needs to be a ping type..." }, { "line": 1576, "text": " if (packed_flag == Varicode::FrameData ||" }, { "line": 1577, "text": " packed_flag == Varicode::FrameDirected) {" }, { "line": 1578, "text": " return unpacked;" } ] } }, { "keyword": "bits.mid", "path": "JS8_Main/Varicode.cpp", "line": 1581, "context": { "start_line": 1576, "end_line": 1586, "lines": [ { "line": 1576, "text": " if (packed_flag == Varicode::FrameData ||" }, { "line": 1577, "text": " packed_flag == Varicode::FrameDirected) {" }, { "line": 1578, "text": " return unpacked;" }, { "line": 1579, "text": " }" }, { "line": 1580, "text": "" }, { "line": 1581, "text": " quint64 packed_callsign = Varicode::bitsToInt(bits.mid(3, 50));" }, { "line": 1582, "text": " quint16 packed_11 = Varicode::bitsToInt(bits.mid(53, 11));" }, { "line": 1583, "text": "" }, { "line": 1584, "text": " QString callsign = Varicode::unpackAlphaNumeric50(packed_callsign);" }, { "line": 1585, "text": "" }, { "line": 1586, "text": " quint16 num = (packed_11 << 5) | packed_5;" } ] } }, { "keyword": "bits.mid", "path": "JS8_Main/Varicode.cpp", "line": 1582, "context": { "start_line": 1577, "end_line": 1587, "lines": [ { "line": 1577, "text": " packed_flag == Varicode::FrameDirected) {" }, { "line": 1578, "text": " return unpacked;" }, { "line": 1579, "text": " }" }, { "line": 1580, "text": "" }, { "line": 1581, "text": " quint64 packed_callsign = Varicode::bitsToInt(bits.mid(3, 50));" }, { "line": 1582, "text": " quint16 packed_11 = Varicode::bitsToInt(bits.mid(53, 11));" }, { "line": 1583, "text": "" }, { "line": 1584, "text": " QString callsign = Varicode::unpackAlphaNumeric50(packed_callsign);" }, { "line": 1585, "text": "" }, { "line": 1586, "text": " quint16 num = (packed_11 << 5) | packed_5;" }, { "line": 1587, "text": "" } ] } }, { "keyword": "pack72bits", "path": "JS8_Main/Varicode.cpp", "line": 767, "context": { "start_line": 762, "end_line": 772, "lines": [ { "line": 762, "text": " quint32 b = packed & 0xFFFFFFFF;" }, { "line": 763, "text": " return pack32bits(a) + pack32bits(b);" }, { "line": 764, "text": "}" }, { "line": 765, "text": "" }, { "line": 766, "text": "// returns the first 64 bits and sets the last 8 bits in pRem" }, { "line": 767, "text": "quint64 Varicode::unpack72bits(QString const &text, quint8 *pRem) {" }, { "line": 768, "text": " quint64 value = 0;" }, { "line": 769, "text": " quint8 rem = 0;" }, { "line": 770, "text": " quint8 mask2 = ((1 << 2) - 1);" }, { "line": 771, "text": "" }, { "line": 772, "text": " for (int i = 0; i < 10; i++) {" } ] } }, { "keyword": "pack72bits", "path": "JS8_Main/Varicode.cpp", "line": 787, "context": { "start_line": 782, "end_line": 792, "lines": [ { "line": 782, "text": " if (pRem)" }, { "line": 783, "text": " *pRem = rem;" }, { "line": 784, "text": " return value;" }, { "line": 785, "text": "}" }, { "line": 786, "text": "" }, { "line": 787, "text": "QString Varicode::pack72bits(quint64 value, quint8 rem) {" }, { "line": 788, "text": " QChar packed[12]; // 12 x 6bit characters" }, { "line": 789, "text": "" }, { "line": 790, "text": " quint8 mask4 = ((1 << 4) - 1);" }, { "line": 791, "text": " quint8 mask6 = ((1 << 6) - 1);" }, { "line": 792, "text": "" } ] } }, { "keyword": "pack72bits", "path": "JS8_Main/Varicode.cpp", "line": 1554, "context": { "start_line": 1549, "end_line": 1559, "lines": [ { "line": 1549, "text": " // [3][50][11],[5][3] = 72" }, { "line": 1550, "text": " auto bits = (Varicode::intToBits(packed_flag, 3) +" }, { "line": 1551, "text": " Varicode::intToBits(packed_callsign, 50) +" }, { "line": 1552, "text": " Varicode::intToBits(packed_11, 11));" }, { "line": 1553, "text": "" }, { "line": 1554, "text": " return Varicode::pack72bits(Varicode::bitsToInt(bits), packed_8);" }, { "line": 1555, "text": "}" }, { "line": 1556, "text": "" }, { "line": 1557, "text": "QStringList Varicode::unpackCompoundFrame(const QString &text, quint8 *pType," }, { "line": 1558, "text": " quint16 *pNum, quint8 *pBits3) {" }, { "line": 1559, "text": " QStringList unpacked;" } ] } }, { "keyword": "pack72bits", "path": "JS8_Main/Varicode.cpp", "line": 1568, "context": { "start_line": 1563, "end_line": 1573, "lines": [ { "line": 1563, "text": " }" }, { "line": 1564, "text": "" }, { "line": 1565, "text": " // [3][50][11],[5][3] = 72" }, { "line": 1566, "text": " quint8 packed_8 = 0;" }, { "line": 1567, "text": " auto bits =" }, { "line": 1568, "text": " Varicode::intToBits(Varicode::unpack72bits(text, &packed_8), 64);" }, { "line": 1569, "text": "" }, { "line": 1570, "text": " quint8 packed_5 = packed_8 >> 3;" }, { "line": 1571, "text": " quint8 packed_3 = packed_8 & ((1 << 3) - 1);" }, { "line": 1572, "text": "" }, { "line": 1573, "text": " quint8 packed_flag = Varicode::bitsToInt(bits.mid(0, 3));" } ] } }, { "keyword": "unpack72bits", "path": "JS8_Main/Varicode.cpp", "line": 767, "context": { "start_line": 762, "end_line": 772, "lines": [ { "line": 762, "text": " quint32 b = packed & 0xFFFFFFFF;" }, { "line": 763, "text": " return pack32bits(a) + pack32bits(b);" }, { "line": 764, "text": "}" }, { "line": 765, "text": "" }, { "line": 766, "text": "// returns the first 64 bits and sets the last 8 bits in pRem" }, { "line": 767, "text": "quint64 Varicode::unpack72bits(QString const &text, quint8 *pRem) {" }, { "line": 768, "text": " quint64 value = 0;" }, { "line": 769, "text": " quint8 rem = 0;" }, { "line": 770, "text": " quint8 mask2 = ((1 << 2) - 1);" }, { "line": 771, "text": "" }, { "line": 772, "text": " for (int i = 0; i < 10; i++) {" } ] } }, { "keyword": "unpack72bits", "path": "JS8_Main/Varicode.cpp", "line": 1568, "context": { "start_line": 1563, "end_line": 1573, "lines": [ { "line": 1563, "text": " }" }, { "line": 1564, "text": "" }, { "line": 1565, "text": " // [3][50][11],[5][3] = 72" }, { "line": 1566, "text": " quint8 packed_8 = 0;" }, { "line": 1567, "text": " auto bits =" }, { "line": 1568, "text": " Varicode::intToBits(Varicode::unpack72bits(text, &packed_8), 64);" }, { "line": 1569, "text": "" }, { "line": 1570, "text": " quint8 packed_5 = packed_8 >> 3;" }, { "line": 1571, "text": " quint8 packed_3 = packed_8 & ((1 << 3) - 1);" }, { "line": 1572, "text": "" }, { "line": 1573, "text": " quint8 packed_flag = Varicode::bitsToInt(bits.mid(0, 3));" } ] } }, { "keyword": "unpack72bits", "path": "JS8_Main/Varicode.cpp", "line": 1726, "context": { "start_line": 1721, "end_line": 1731, "lines": [ { "line": 1721, "text": " return unpacked;" }, { "line": 1722, "text": " }" }, { "line": 1723, "text": "" }, { "line": 1724, "text": " // [3][28][22][11],[2][6] = 72" }, { "line": 1725, "text": " quint8 extra = 0;" }, { "line": 1726, "text": " auto bits = Varicode::intToBits(Varicode::unpack72bits(text, &extra), 64);" }, { "line": 1727, "text": "" }, { "line": 1728, "text": " quint8 packed_flag = Varicode::bitsToInt(bits.mid(0, 3));" }, { "line": 1729, "text": " if (packed_flag != Varicode::FrameDirected) {" }, { "line": 1730, "text": " return unpacked;" }, { "line": 1731, "text": " }" } ] } }, { "keyword": "unpack72bits", "path": "JS8_Main/Varicode.cpp", "line": 1920, "context": { "start_line": 1915, "end_line": 1925, "lines": [ { "line": 1915, "text": " if (text.length() < 12 || text.contains(\" \")) {" }, { "line": 1916, "text": " return unpacked;" }, { "line": 1917, "text": " }" }, { "line": 1918, "text": "" }, { "line": 1919, "text": " quint8 rem = 0;" }, { "line": 1920, "text": " quint64 value = Varicode::unpack72bits(text, &rem);" }, { "line": 1921, "text": " auto bits = Varicode::intToBits(value, 64) + Varicode::intToBits(rem, 8);" }, { "line": 1922, "text": "" }, { "line": 1923, "text": " bool isData = bits.at(0);" }, { "line": 1924, "text": " if (!isData) {" }, { "line": 1925, "text": " return unpacked;" } ] } }, { "keyword": "buildMessageFrames", "path": "JS8_Main/Varicode.cpp", "line": 159, "context": { "start_line": 154, "end_line": 164, "lines": [ { "line": 154, "text": " R\"(^\\s*(?[@](?:ALLCALL|HB)\\s+)?(?CQ CQ CQ|CQ DX|CQ QRP|CQ CONTEST|CQ FIELD|CQ FD|CQ CQ|CQ|HB|HEARTBEAT(?!\\s+SNR))(?:\\s(?[A-R]{2}[0-9]{2}))?\\b)\");" }, { "line": 155, "text": "" }, { "line": 156, "text": "QRegularExpression" }, { "line": 157, "text": " compound_re(\"^\\\\s*[`]\" + callsign_pattern + \"(?\" +" }, { "line": 158, "text": " optional_grid_pattern + // there's a reason this is first (see:" }, { "line": 159, "text": " // buildMessageFrames)" }, { "line": 160, "text": " optional_cmd_pattern + optional_num_pattern + \")\");" }, { "line": 161, "text": "" }, { "line": 162, "text": "QMap hufftable = {" }, { "line": 163, "text": " // char code weight" }, { "line": 164, "text": " {\" \", \"01\"}, // 1.0" } ] } }, { "keyword": "buildMessageFrames", "path": "JS8_Main/Varicode.cpp", "line": 2023, "context": { "start_line": 2018, "end_line": 2028, "lines": [ { "line": 2018, "text": " return unpacked;" }, { "line": 2019, "text": "}" }, { "line": 2020, "text": "" }, { "line": 2021, "text": "// TODO: remove the dependence on providing all this data?" }, { "line": 2022, "text": "QList>" }, { "line": 2023, "text": "Varicode::buildMessageFrames(QString const &mycall, QString const &mygrid," }, { "line": 2024, "text": " QString const &selectedCall, QString const &text," }, { "line": 2025, "text": " bool forceIdentify, bool forceData, int submode," }, { "line": 2026, "text": " MessageInfo *pInfo) {" }, { "line": 2027, "text": "" }, { "line": 2028, "text": "#define ALLOW_SEND_COMPOUND 1" } ] } }, { "keyword": "buildMessageFrames", "path": "JS8_Main/Varicode.cpp", "line": 2335, "context": { "start_line": 2330, "end_line": 2340, "lines": [ { "line": 2330, "text": " m_forceIdentify{forceIdentify}, m_forceData{forceData}," }, { "line": 2331, "text": " m_submode{submode} {}" }, { "line": 2332, "text": "" }, { "line": 2333, "text": "void BuildMessageFramesThread::run() {" }, { "line": 2334, "text": " auto results =" }, { "line": 2335, "text": " Varicode::buildMessageFrames(m_mycall, m_mygrid, m_selectedCall, m_text," }, { "line": 2336, "text": " m_forceIdentify, m_forceData, m_submode);" }, { "line": 2337, "text": "" }, { "line": 2338, "text": " // TODO: jsherer - we wouldn't normally use DecodedText.h here... but it's" }, { "line": 2339, "text": " // useful for computing the actual frames transmitted." }, { "line": 2340, "text": " QStringList textList;" } ] } }, { "keyword": "unpackDataMessage", "path": "JS8_Main/Varicode.h", "line": 189, "context": { "start_line": 184, "end_line": 194, "lines": [ { "line": 184, "text": " QString *pNum, int *n);" }, { "line": 185, "text": " static QStringList unpackDirectedMessage(QString const &text," }, { "line": 186, "text": " quint8 *pType);" }, { "line": 187, "text": "" }, { "line": 188, "text": " static QString packDataMessage(QString const &text, int *n);" }, { "line": 189, "text": " static QString unpackDataMessage(QString const &text);" }, { "line": 190, "text": "" }, { "line": 191, "text": " static QString packFastDataMessage(QString const &text, int *n);" }, { "line": 192, "text": " static QString unpackFastDataMessage(QString const &text);" }, { "line": 193, "text": "" }, { "line": 194, "text": " static QList>" } ] } }, { "keyword": "unpackFastDataMessage", "path": "JS8_Main/Varicode.h", "line": 192, "context": { "start_line": 187, "end_line": 197, "lines": [ { "line": 187, "text": "" }, { "line": 188, "text": " static QString packDataMessage(QString const &text, int *n);" }, { "line": 189, "text": " static QString unpackDataMessage(QString const &text);" }, { "line": 190, "text": "" }, { "line": 191, "text": " static QString packFastDataMessage(QString const &text, int *n);" }, { "line": 192, "text": " static QString unpackFastDataMessage(QString const &text);" }, { "line": 193, "text": "" }, { "line": 194, "text": " static QList>" }, { "line": 195, "text": " buildMessageFrames(QString const &mycall, QString const &mygrid," }, { "line": 196, "text": " QString const &selectedCall, QString const &text," }, { "line": 197, "text": " bool forceIdentify, bool forceData, int submode," } ] } }, { "keyword": "huffDecode", "path": "JS8_Main/Varicode.h", "line": 107, "context": { "start_line": 102, "end_line": 112, "lines": [ { "line": 102, "text": " static QStringList parseCallsigns(QString const &input);" }, { "line": 103, "text": " static QStringList parseGrids(QString const &input);" }, { "line": 104, "text": "" }, { "line": 105, "text": " static QList>>" }, { "line": 106, "text": " huffEncode(const QMap &huff, QString const &text);" }, { "line": 107, "text": " static QString huffDecode(const QMap &huff," }, { "line": 108, "text": " QVector const &bitvec);" }, { "line": 109, "text": " static QSet huffValidChars(const QMap &huff);" }, { "line": 110, "text": "" }, { "line": 111, "text": " static QVector bytesToBits(char *bitvec, int n);" }, { "line": 112, "text": " static QVector strToBits(QString const &bitvec);" } ] } }, { "keyword": "defaultHuffTable", "path": "JS8_Main/Varicode.h", "line": 88, "context": { "start_line": 83, "end_line": 93, "lines": [ { "line": 83, "text": " static QString unescape(const QString &text);" }, { "line": 84, "text": "" }, { "line": 85, "text": " static QString rstrip(const QString &str);" }, { "line": 86, "text": " static QString lstrip(const QString &str);" }, { "line": 87, "text": "" }, { "line": 88, "text": " static QMap defaultHuffTable();" }, { "line": 89, "text": " static QString cqString(int number);" }, { "line": 90, "text": " static QString hbString(int number);" }, { "line": 91, "text": " static bool startsWithCQ(QString text);" }, { "line": 92, "text": " static bool startsWithHB(QString text);" }, { "line": 93, "text": " static QString formatSNR(int snr);" } ] } }, { "keyword": "FrameDataCompressed", "path": "JS8_Main/Varicode.h", "line": 56, "context": { "start_line": 51, "end_line": 61, "lines": [ { "line": 51, "text": " FrameCompound = 1, // [001]" }, { "line": 52, "text": " FrameCompoundDirected = 2, // [010]" }, { "line": 53, "text": " FrameDirected = 3, // [011]" }, { "line": 54, "text": " FrameData = 4, // [10X] // but this only encodes the first 2 msb bits" }, { "line": 55, "text": " // and drops the lsb" }, { "line": 56, "text": " FrameDataCompressed = 6, // [11X] // but this only encodes the first 2" }, { "line": 57, "text": " // msb bits and drops the lsb" }, { "line": 58, "text": " };" }, { "line": 59, "text": "" }, { "line": 60, "text": " static const quint8 FrameTypeMax = 6;" }, { "line": 61, "text": "" } ] } }, { "keyword": "FrameDataCompressed", "path": "JS8_Main/Varicode.h", "line": 67, "context": { "start_line": 62, "end_line": 72, "lines": [ { "line": 62, "text": " static QString frameTypeString(quint8 type) {" }, { "line": 63, "text": " const char *FrameTypeStrings[] = {" }, { "line": 64, "text": " \"FrameHeartbeat\", \"FrameCompound\", \"FrameCompoundDirected\"," }, { "line": 65, "text": " \"FrameDirected\", \"FrameData\"," }, { "line": 66, "text": " \"FrameUnknown\", // 5" }, { "line": 67, "text": " \"FrameDataCompressed\"," }, { "line": 68, "text": " };" }, { "line": 69, "text": "" }, { "line": 70, "text": " if (type > FrameTypeMax) {" }, { "line": 71, "text": " return \"FrameUnknown\";" }, { "line": 72, "text": " }" } ] } }, { "keyword": "FrameData", "path": "JS8_Main/Varicode.h", "line": 54, "context": { "start_line": 49, "end_line": 59, "lines": [ { "line": 49, "text": " FrameUnknown = 255, // [11111111] <- only used as a sentinel" }, { "line": 50, "text": " FrameHeartbeat = 0, // [000]" }, { "line": 51, "text": " FrameCompound = 1, // [001]" }, { "line": 52, "text": " FrameCompoundDirected = 2, // [010]" }, { "line": 53, "text": " FrameDirected = 3, // [011]" }, { "line": 54, "text": " FrameData = 4, // [10X] // but this only encodes the first 2 msb bits" }, { "line": 55, "text": " // and drops the lsb" }, { "line": 56, "text": " FrameDataCompressed = 6, // [11X] // but this only encodes the first 2" }, { "line": 57, "text": " // msb bits and drops the lsb" }, { "line": 58, "text": " };" }, { "line": 59, "text": "" } ] } }, { "keyword": "FrameData", "path": "JS8_Main/Varicode.h", "line": 56, "context": { "start_line": 51, "end_line": 61, "lines": [ { "line": 51, "text": " FrameCompound = 1, // [001]" }, { "line": 52, "text": " FrameCompoundDirected = 2, // [010]" }, { "line": 53, "text": " FrameDirected = 3, // [011]" }, { "line": 54, "text": " FrameData = 4, // [10X] // but this only encodes the first 2 msb bits" }, { "line": 55, "text": " // and drops the lsb" }, { "line": 56, "text": " FrameDataCompressed = 6, // [11X] // but this only encodes the first 2" }, { "line": 57, "text": " // msb bits and drops the lsb" }, { "line": 58, "text": " };" }, { "line": 59, "text": "" }, { "line": 60, "text": " static const quint8 FrameTypeMax = 6;" }, { "line": 61, "text": "" } ] } }, { "keyword": "FrameData", "path": "JS8_Main/Varicode.h", "line": 65, "context": { "start_line": 60, "end_line": 70, "lines": [ { "line": 60, "text": " static const quint8 FrameTypeMax = 6;" }, { "line": 61, "text": "" }, { "line": 62, "text": " static QString frameTypeString(quint8 type) {" }, { "line": 63, "text": " const char *FrameTypeStrings[] = {" }, { "line": 64, "text": " \"FrameHeartbeat\", \"FrameCompound\", \"FrameCompoundDirected\"," }, { "line": 65, "text": " \"FrameDirected\", \"FrameData\"," }, { "line": 66, "text": " \"FrameUnknown\", // 5" }, { "line": 67, "text": " \"FrameDataCompressed\"," }, { "line": 68, "text": " };" }, { "line": 69, "text": "" }, { "line": 70, "text": " if (type > FrameTypeMax) {" } ] } }, { "keyword": "FrameData", "path": "JS8_Main/Varicode.h", "line": 67, "context": { "start_line": 62, "end_line": 72, "lines": [ { "line": 62, "text": " static QString frameTypeString(quint8 type) {" }, { "line": 63, "text": " const char *FrameTypeStrings[] = {" }, { "line": 64, "text": " \"FrameHeartbeat\", \"FrameCompound\", \"FrameCompoundDirected\"," }, { "line": 65, "text": " \"FrameDirected\", \"FrameData\"," }, { "line": 66, "text": " \"FrameUnknown\", // 5" }, { "line": 67, "text": " \"FrameDataCompressed\"," }, { "line": 68, "text": " };" }, { "line": 69, "text": "" }, { "line": 70, "text": " if (type > FrameTypeMax) {" }, { "line": 71, "text": " return \"FrameUnknown\";" }, { "line": 72, "text": " }" } ] } }, { "keyword": "JS8CallData", "path": "JS8_Main/Varicode.h", "line": 37, "context": { "start_line": 32, "end_line": 42, "lines": [ { "line": 32, "text": " // frame type transmitted via itype and decoded by the ft8 decoded" }, { "line": 33, "text": " enum TransmissionType {" }, { "line": 34, "text": " JS8Call = 0, // [000] <- any other frame of the message" }, { "line": 35, "text": " JS8CallFirst = 1, // [001] <- the first frame of a message" }, { "line": 36, "text": " JS8CallLast = 2, // [010] <- the last frame of a message" }, { "line": 37, "text": " JS8CallData = 4, // [100] <- flagged frame (no frame type header)" }, { "line": 38, "text": " };" }, { "line": 39, "text": "" }, { "line": 40, "text": " /*" }, { "line": 41, "text": "" }, { "line": 42, "text": " 000 = heartbeat" } ] } }, { "keyword": "pack72bits", "path": "JS8_Main/Varicode.h", "line": 135, "context": { "start_line": 130, "end_line": 140, "lines": [ { "line": 130, "text": " static QString pack32bits(quint32 packed);" }, { "line": 131, "text": "" }, { "line": 132, "text": " static quint64 unpack64bits(QString const &value);" }, { "line": 133, "text": " static QString pack64bits(quint64 packed);" }, { "line": 134, "text": "" }, { "line": 135, "text": " static quint64 unpack72bits(QString const &value, quint8 *pRem);" }, { "line": 136, "text": " static QString pack72bits(quint64 value, quint8 rem);" }, { "line": 137, "text": "" }, { "line": 138, "text": " static quint32 packAlphaNumeric22(QString const &value, bool isFlag);" }, { "line": 139, "text": " static QString unpackAlphaNumeric22(quint32 packed, bool *isFlag);" }, { "line": 140, "text": "" } ] } }, { "keyword": "pack72bits", "path": "JS8_Main/Varicode.h", "line": 136, "context": { "start_line": 131, "end_line": 141, "lines": [ { "line": 131, "text": "" }, { "line": 132, "text": " static quint64 unpack64bits(QString const &value);" }, { "line": 133, "text": " static QString pack64bits(quint64 packed);" }, { "line": 134, "text": "" }, { "line": 135, "text": " static quint64 unpack72bits(QString const &value, quint8 *pRem);" }, { "line": 136, "text": " static QString pack72bits(quint64 value, quint8 rem);" }, { "line": 137, "text": "" }, { "line": 138, "text": " static quint32 packAlphaNumeric22(QString const &value, bool isFlag);" }, { "line": 139, "text": " static QString unpackAlphaNumeric22(quint32 packed, bool *isFlag);" }, { "line": 140, "text": "" }, { "line": 141, "text": " static quint64 packAlphaNumeric50(QString const &value);" } ] } }, { "keyword": "unpack72bits", "path": "JS8_Main/Varicode.h", "line": 135, "context": { "start_line": 130, "end_line": 140, "lines": [ { "line": 130, "text": " static QString pack32bits(quint32 packed);" }, { "line": 131, "text": "" }, { "line": 132, "text": " static quint64 unpack64bits(QString const &value);" }, { "line": 133, "text": " static QString pack64bits(quint64 packed);" }, { "line": 134, "text": "" }, { "line": 135, "text": " static quint64 unpack72bits(QString const &value, quint8 *pRem);" }, { "line": 136, "text": " static QString pack72bits(quint64 value, quint8 rem);" }, { "line": 137, "text": "" }, { "line": 138, "text": " static quint32 packAlphaNumeric22(QString const &value, bool isFlag);" }, { "line": 139, "text": " static QString unpackAlphaNumeric22(quint32 packed, bool *isFlag);" }, { "line": 140, "text": "" } ] } }, { "keyword": "buildMessageFrames", "path": "JS8_Main/Varicode.h", "line": 16, "context": { "start_line": 11, "end_line": 21, "lines": [ { "line": 11, "text": "#include " }, { "line": 12, "text": "#include " }, { "line": 13, "text": "" }, { "line": 14, "text": "class Varicode {" }, { "line": 15, "text": " public:" }, { "line": 16, "text": " // extra information out of buildMessageFrames" }, { "line": 17, "text": " struct MessageInfo {" }, { "line": 18, "text": " QString dirTo;" }, { "line": 19, "text": " QString dirCmd;" }, { "line": 20, "text": " QString dirNum;" }, { "line": 21, "text": " };" } ] } }, { "keyword": "buildMessageFrames", "path": "JS8_Main/Varicode.h", "line": 195, "context": { "start_line": 190, "end_line": 200, "lines": [ { "line": 190, "text": "" }, { "line": 191, "text": " static QString packFastDataMessage(QString const &text, int *n);" }, { "line": 192, "text": " static QString unpackFastDataMessage(QString const &text);" }, { "line": 193, "text": "" }, { "line": 194, "text": " static QList>" }, { "line": 195, "text": " buildMessageFrames(QString const &mycall, QString const &mygrid," }, { "line": 196, "text": " QString const &selectedCall, QString const &text," }, { "line": 197, "text": " bool forceIdentify, bool forceData, int submode," }, { "line": 198, "text": " MessageInfo *pInfo = nullptr);" }, { "line": 199, "text": "};" }, { "line": 200, "text": "" } ] } }, { "keyword": "JSC::decompress", "path": "JS8_JSC/JSC.cpp", "line": 127, "context": { "start_line": 122, "end_line": 132, "lines": [ { "line": 122, "text": " * @brief Decompresses the given bit vector into a string." }, { "line": 123, "text": " *" }, { "line": 124, "text": " * @param bitvec" }, { "line": 125, "text": " * @return QString" }, { "line": 126, "text": " */" }, { "line": 127, "text": "QString JSC::decompress(Codeword const &bitvec) {" }, { "line": 128, "text": " const quint32 b = 4;" }, { "line": 129, "text": " const quint32 s = 7;" }, { "line": 130, "text": " const quint32 c = pow(2, b) - s;" }, { "line": 131, "text": "" }, { "line": 132, "text": " QStringList out;" } ] } }, { "keyword": "JSC::compress", "path": "JS8_JSC/JSC.cpp", "line": 71, "context": { "start_line": 66, "end_line": 76, "lines": [ { "line": 66, "text": " * @brief Compresses the given text into a list of codeword pairs." }, { "line": 67, "text": " *" }, { "line": 68, "text": " * @param text" }, { "line": 69, "text": " * @return QList" }, { "line": 70, "text": " */" }, { "line": 71, "text": "QList JSC::compress(QString text) {" }, { "line": 72, "text": " QList out;" }, { "line": 73, "text": "" }, { "line": 74, "text": " const quint32 b = 4;" }, { "line": 75, "text": " const quint32 s = 7;" }, { "line": 76, "text": " const quint32 c = pow(2, 4) - s;" } ] } } ], "function_body_previews": [ { "path": "JS8_Main/Varicode.cpp", "line": 1912, "pattern": "QString\\s+Varicode::unpackDataMessage\\s*\\(", "chars": 849, "context": { "start_line": 1909, "end_line": 1915, "lines": [ { "line": 1909, "text": "// TODO: DEPRECATED in 2.2 (still available for decoding legacy frames, but will" }, { "line": 1910, "text": "// eventually no longer be decodable) unpack data message using 70 bits" }, { "line": 1911, "text": "// available flagged as data by the first 2 bits" }, { "line": 1912, "text": "QString Varicode::unpackDataMessage(const QString &text) {" }, { "line": 1913, "text": " QString unpacked;" }, { "line": 1914, "text": "" }, { "line": 1915, "text": " if (text.length() < 12 || text.contains(\" \")) {" } ] }, "body_preview": "QString Varicode::unpackDataMessage(const QString &text) {\n QString unpacked;\n\n if (text.length() < 12 || text.contains(\" \")) {\n return unpacked;\n }\n\n quint8 rem = 0;\n quint64 value = Varicode::unpack72bits(text, &rem);\n auto bits = Varicode::intToBits(value, 64) + Varicode::intToBits(rem, 8);\n\n bool isData = bits.at(0);\n if (!isData) {\n return unpacked;\n }\n\n bits = bits.mid(1);\n\n bool compressed = bits.at(0);\n int n = bits.lastIndexOf(0);\n\n // trim off the pad bits\n bits = bits.mid(1, n - 1);\n\n if (compressed) {\n // partial word (s,c)-dense coding with code tables\n unpacked = JSC::decompress(bits);\n } else {\n // huff decode the bits (without escapes)\n unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);\n }\n\n return unpacked;\n}" }, { "path": "JS8_Main/Varicode.cpp", "line": 1983, "pattern": "QString\\s+Varicode::unpackFastDataMessage\\s*\\(", "chars": 976, "context": { "start_line": 1980, "end_line": 1986, "lines": [ { "line": 1980, "text": "" }, { "line": 1981, "text": "// unpack data message using the full 72 bits available (with the data flag in" }, { "line": 1982, "text": "// the i3bit header)" }, { "line": 1983, "text": "QString Varicode::unpackFastDataMessage(const QString &text) {" }, { "line": 1984, "text": " QString unpacked;" }, { "line": 1985, "text": "" }, { "line": 1986, "text": " if (text.length() < 12 || text.contains(\" \")) {" } ] }, "body_preview": "QString Varicode::unpackFastDataMessage(const QString &text) {\n QString unpacked;\n\n if (text.length() < 12 || text.contains(\" \")) {\n return unpacked;\n }\n\n quint8 rem = 0;\n quint64 value = Varicode::unpack72bits(text, &rem);\n auto bits = Varicode::intToBits(value, 64) + Varicode::intToBits(rem, 8);\n\n#if JS8_FAST_DATA_CAN_USE_HUFF\n bool compressed = bits.at(0);\n int n = bits.lastIndexOf(0);\n\n // trim off the pad bits\n bits = bits.mid(1, n - 1);\n\n if (compressed) {\n // partial word (s,c)-dense coding with code tables\n unpacked = JSC::decompress(bits);\n } else {\n // huff decode the bits (without escapes)\n unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);\n }\n#else\n int n = bits.lastIndexOf(0);\n\n // trim off the pad bits\n bits = bits.mid(0, n);\n\n // partial word (s,c)-dense coding with code tables\n unpacked = JSC::decompress(bits);\n#endif\n\n return unpacked;\n}" }, { "path": "JS8_Main/Varicode.cpp", "line": 1830, "pattern": "QString\\s+packCompressedMessage\\s*\\(", "chars": 1818, "context": { "start_line": 1827, "end_line": 1833, "lines": [ { "line": 1827, "text": " return frame;" }, { "line": 1828, "text": "}" }, { "line": 1829, "text": "" }, { "line": 1830, "text": "QString packCompressedMessage(const QString &input, QVector prefix," }, { "line": 1831, "text": " int *n) {" }, { "line": 1832, "text": " static const int frameSize = 72;" }, { "line": 1833, "text": "" } ] }, "body_preview": "QString packCompressedMessage(const QString &input, QVector prefix,\n int *n) {\n static const int frameSize = 72;\n\n QString frame;\n\n // [1][1][70] = 72\n // The first bit is a flag that indicates this is a data frame, technically\n // encoded as [100] but, since none of the other frame types start with a 1,\n // we can drop the two zeros and use them for encoding the first two bits of\n // the actuall data sent. boom! The second bit is a flag that indicates this\n // is a compressed frame (dense coding) For fast modes, we don't use the\n // prefix since it is indicated by the JS8CallData flag.\n QVector frameBits;\n if (!prefix.isEmpty()) {\n frameBits << prefix;\n }\n\n int i = 0;\n foreach (auto pair, JSC::compress(input)) {\n auto bits = pair.first;\n auto chars = pair.second;\n\n if (frameBits.length() + bits.length() < frameSize) {\n frameBits.append(bits);\n i += chars;\n continue;\n }\n\n break;\n }\n\n qCDebug(varicode_js8) << \"Compressed bits\" << frameBits.length() << \"chars\"\n << i;\n\n int pad = frameSize - frameBits.length();\n if (pad) {\n // the way we will pad is this...\n // set the bit after the frame to 0 and every bit after that a 1\n // to unpad, seek from the end of the bits until you hit a zero... the\n // rest is the actual frame.\n for (int i = 0; i < pad; i++) {\n frameBits.append(i == 0 ? (bool)0 : (bool)1);\n }\n }\n\n quint64 value = Varicode::bitsToInt(frameBits.constBegin(), 64);\n quint8 rem = (quint8)Varicode::bitsToInt(frameBits.constBegin() + 64, 8);\n frame = Varicode::pack72bits(value, rem);\n\n if (n)\n *n = i;\n\n return frame;\n}" }, { "path": "JS8_Main/Varicode.cpp", "line": 597, "pattern": "QString\\s+Varicode::huffDecode\\s*\\(", "chars": 750, "context": { "start_line": 594, "end_line": 600, "lines": [ { "line": 594, "text": " return out;" }, { "line": 595, "text": "}" }, { "line": 596, "text": "" }, { "line": 597, "text": "QString Varicode::huffDecode(QMap const &huff," }, { "line": 598, "text": " QVector const &bitvec) {" }, { "line": 599, "text": " QString text;" }, { "line": 600, "text": "" } ] }, "body_preview": "QString Varicode::huffDecode(QMap const &huff,\n QVector const &bitvec) {\n QString text;\n\n QString bits = Varicode::bitsToStr(bitvec);\n\n // TODO: jsherer - this is naive...\n while (bits.length() > 0) {\n bool found = false;\n foreach (auto key, huff.keys()) {\n if (bits.startsWith(huff[key])) {\n if (key == EOT) {\n text.append(\" \");\n found = false;\n break;\n }\n text.append(key);\n bits = bits.mid(huff[key].length());\n found = true;\n }\n }\n if (!found) {\n break;\n }\n }\n\n return text;\n}" }, { "path": "JS8_Main/Varicode.cpp", "line": 438, "pattern": "QMap<[^>]+>\\s+Varicode::defaultHuffTable\\s*\\(", "chars": 73, "context": { "start_line": 435, "end_line": 441, "lines": [ { "line": 435, "text": "/*" }, { "line": 436, "text": " * VARICODE" }, { "line": 437, "text": " */" }, { "line": 438, "text": "QMap Varicode::defaultHuffTable() { return hufftable; }" }, { "line": 439, "text": "" }, { "line": 440, "text": "QString Varicode::cqString(int number) {" }, { "line": 441, "text": " if (!cqs.contains(number)) {" } ] }, "body_preview": "QMap Varicode::defaultHuffTable() { return hufftable; }" }, { "path": "JS8_Main/Varicode.cpp", "line": 1938, "pattern": "\\bJSC::decompress\\s*\\(", "chars": 168, "context": { "start_line": 1935, "end_line": 1941, "lines": [ { "line": 1935, "text": "" }, { "line": 1936, "text": " if (compressed) {" }, { "line": 1937, "text": " // partial word (s,c)-dense coding with code tables" }, { "line": 1938, "text": " unpacked = JSC::decompress(bits);" }, { "line": 1939, "text": " } else {" }, { "line": 1940, "text": " // huff decode the bits (without escapes)" }, { "line": 1941, "text": " unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);" } ] }, "body_preview": "JSC::decompress(bits);\n } else {\n // huff decode the bits (without escapes)\n unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);\n }" }, { "path": "JS8_Main/Varicode.cpp", "line": 2003, "pattern": "\\bJSC::decompress\\s*\\(", "chars": 168, "context": { "start_line": 2000, "end_line": 2006, "lines": [ { "line": 2000, "text": "" }, { "line": 2001, "text": " if (compressed) {" }, { "line": 2002, "text": " // partial word (s,c)-dense coding with code tables" }, { "line": 2003, "text": " unpacked = JSC::decompress(bits);" }, { "line": 2004, "text": " } else {" }, { "line": 2005, "text": " // huff decode the bits (without escapes)" }, { "line": 2006, "text": " unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);" } ] }, "body_preview": "JSC::decompress(bits);\n } else {\n // huff decode the bits (without escapes)\n unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);\n }" }, { "path": "JS8_Main/Varicode.cpp", "line": 2015, "pattern": "\\bJSC::decompress\\s*\\(", "chars": 422, "context": { "start_line": 2012, "end_line": 2018, "lines": [ { "line": 2012, "text": " bits = bits.mid(0, n);" }, { "line": 2013, "text": "" }, { "line": 2014, "text": " // partial word (s,c)-dense coding with code tables" }, { "line": 2015, "text": " unpacked = JSC::decompress(bits);" }, { "line": 2016, "text": "#endif" }, { "line": 2017, "text": "" }, { "line": 2018, "text": " return unpacked;" } ] }, "body_preview": "JSC::decompress(bits);\n#endif\n\n return unpacked;\n}\n\n// TODO: remove the dependence on providing all this data?\nQList>\nVaricode::buildMessageFrames(QString const &mycall, QString const &mygrid,\n QString const &selectedCall, QString const &text,\n bool forceIdentify, bool forceData, int submode,\n MessageInfo *pInfo) " }, { "path": "JS8_Main/Varicode.cpp", "line": 1938, "pattern": "\\bdecompress\\s*\\(", "chars": 163, "context": { "start_line": 1935, "end_line": 1941, "lines": [ { "line": 1935, "text": "" }, { "line": 1936, "text": " if (compressed) {" }, { "line": 1937, "text": " // partial word (s,c)-dense coding with code tables" }, { "line": 1938, "text": " unpacked = JSC::decompress(bits);" }, { "line": 1939, "text": " } else {" }, { "line": 1940, "text": " // huff decode the bits (without escapes)" }, { "line": 1941, "text": " unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);" } ] }, "body_preview": "decompress(bits);\n } else {\n // huff decode the bits (without escapes)\n unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);\n }" }, { "path": "JS8_Main/Varicode.cpp", "line": 2003, "pattern": "\\bdecompress\\s*\\(", "chars": 163, "context": { "start_line": 2000, "end_line": 2006, "lines": [ { "line": 2000, "text": "" }, { "line": 2001, "text": " if (compressed) {" }, { "line": 2002, "text": " // partial word (s,c)-dense coding with code tables" }, { "line": 2003, "text": " unpacked = JSC::decompress(bits);" }, { "line": 2004, "text": " } else {" }, { "line": 2005, "text": " // huff decode the bits (without escapes)" }, { "line": 2006, "text": " unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);" } ] }, "body_preview": "decompress(bits);\n } else {\n // huff decode the bits (without escapes)\n unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);\n }" }, { "path": "JS8_Main/Varicode.cpp", "line": 2015, "pattern": "\\bdecompress\\s*\\(", "chars": 417, "context": { "start_line": 2012, "end_line": 2018, "lines": [ { "line": 2012, "text": " bits = bits.mid(0, n);" }, { "line": 2013, "text": "" }, { "line": 2014, "text": " // partial word (s,c)-dense coding with code tables" }, { "line": 2015, "text": " unpacked = JSC::decompress(bits);" }, { "line": 2016, "text": "#endif" }, { "line": 2017, "text": "" }, { "line": 2018, "text": " return unpacked;" } ] }, "body_preview": "decompress(bits);\n#endif\n\n return unpacked;\n}\n\n// TODO: remove the dependence on providing all this data?\nQList>\nVaricode::buildMessageFrames(QString const &mycall, QString const &mygrid,\n QString const &selectedCall, QString const &text,\n bool forceIdentify, bool forceData, int submode,\n MessageInfo *pInfo) " }, { "path": "JS8_Main/Varicode.cpp", "line": 1849, "pattern": "\\bcompress\\s*\\(", "chars": 261, "context": { "start_line": 1846, "end_line": 1852, "lines": [ { "line": 1846, "text": " }" }, { "line": 1847, "text": "" }, { "line": 1848, "text": " int i = 0;" }, { "line": 1849, "text": " foreach (auto pair, JSC::compress(input)) {" }, { "line": 1850, "text": " auto bits = pair.first;" }, { "line": 1851, "text": " auto chars = pair.second;" }, { "line": 1852, "text": "" } ] }, "body_preview": "compress(input)) {\n auto bits = pair.first;\n auto chars = pair.second;\n\n if (frameBits.length() + bits.length() < frameSize) {\n frameBits.append(bits);\n i += chars;\n continue;\n }\n\n break;\n }" }, { "path": "JS8_JSC/JSC.cpp", "line": 127, "pattern": "\\bJSC::decompress\\s*\\(", "chars": 1810, "context": { "start_line": 124, "end_line": 130, "lines": [ { "line": 124, "text": " * @param bitvec" }, { "line": 125, "text": " * @return QString" }, { "line": 126, "text": " */" }, { "line": 127, "text": "QString JSC::decompress(Codeword const &bitvec) {" }, { "line": 128, "text": " const quint32 b = 4;" }, { "line": 129, "text": " const quint32 s = 7;" }, { "line": 130, "text": " const quint32 c = pow(2, b) - s;" } ] }, "body_preview": "JSC::decompress(Codeword const &bitvec) {\n const quint32 b = 4;\n const quint32 s = 7;\n const quint32 c = pow(2, b) - s;\n\n QStringList out;\n\n quint32 base[8];\n base[0] = 0;\n base[1] = s;\n base[2] = base[1] + s * c;\n base[3] = base[2] + s * c * c;\n base[4] = base[3] + s * c * c * c;\n base[5] = base[4] + s * c * c * c * c;\n base[6] = base[5] + s * c * c * c * c * c;\n base[7] = base[6] + s * c * c * c * c * c * c;\n\n QList bytes;\n QList separators;\n\n int i = 0;\n int count = bitvec.count();\n while (i < count) {\n auto b = bitvec.mid(i, 4);\n if (b.length() != 4) {\n break;\n }\n quint64 byte = Varicode::bitsToInt(b);\n bytes.append(byte);\n i += 4;\n\n if (byte < s) {\n if (count - i > 0 && bitvec.at(i)) {\n separators.append(bytes.length() - 1);\n }\n i += 1;\n }\n }\n\n quint32 start = 0;\n while (start < (quint32)bytes.length()) {\n quint32 k = 0;\n quint32 j = 0;\n\n while (start + k < (quint32)bytes.length() && bytes[start + k] >= s) {\n j = j * c + (bytes[start + k] - s);\n k++;\n }\n if (j >= JSC::size) {\n break;\n }\n\n if (start + k >= (quint32)bytes.length()) {\n break;\n }\n j = j * s + bytes[start + k] + base[k];\n\n if (j >= JSC::size) {\n break;\n }\n\n // map is in latin1 format, not utf-8\n auto word = QLatin1String(JSC::map[j].str);\n\n out.append(word);\n if (!separators.isEmpty() && separators.first() == start + k) {\n out.append(\" \");\n separators.removeFirst();\n }\n\n start = start + (k + 1);\n }\n\n return out.join(\"\");\n}" }, { "path": "JS8_JSC/JSC.cpp", "line": 127, "pattern": "\\bdecompress\\s*\\(", "chars": 1805, "context": { "start_line": 124, "end_line": 130, "lines": [ { "line": 124, "text": " * @param bitvec" }, { "line": 125, "text": " * @return QString" }, { "line": 126, "text": " */" }, { "line": 127, "text": "QString JSC::decompress(Codeword const &bitvec) {" }, { "line": 128, "text": " const quint32 b = 4;" }, { "line": 129, "text": " const quint32 s = 7;" }, { "line": 130, "text": " const quint32 c = pow(2, b) - s;" } ] }, "body_preview": "decompress(Codeword const &bitvec) {\n const quint32 b = 4;\n const quint32 s = 7;\n const quint32 c = pow(2, b) - s;\n\n QStringList out;\n\n quint32 base[8];\n base[0] = 0;\n base[1] = s;\n base[2] = base[1] + s * c;\n base[3] = base[2] + s * c * c;\n base[4] = base[3] + s * c * c * c;\n base[5] = base[4] + s * c * c * c * c;\n base[6] = base[5] + s * c * c * c * c * c;\n base[7] = base[6] + s * c * c * c * c * c * c;\n\n QList bytes;\n QList separators;\n\n int i = 0;\n int count = bitvec.count();\n while (i < count) {\n auto b = bitvec.mid(i, 4);\n if (b.length() != 4) {\n break;\n }\n quint64 byte = Varicode::bitsToInt(b);\n bytes.append(byte);\n i += 4;\n\n if (byte < s) {\n if (count - i > 0 && bitvec.at(i)) {\n separators.append(bytes.length() - 1);\n }\n i += 1;\n }\n }\n\n quint32 start = 0;\n while (start < (quint32)bytes.length()) {\n quint32 k = 0;\n quint32 j = 0;\n\n while (start + k < (quint32)bytes.length() && bytes[start + k] >= s) {\n j = j * c + (bytes[start + k] - s);\n k++;\n }\n if (j >= JSC::size) {\n break;\n }\n\n if (start + k >= (quint32)bytes.length()) {\n break;\n }\n j = j * s + bytes[start + k] + base[k];\n\n if (j >= JSC::size) {\n break;\n }\n\n // map is in latin1 format, not utf-8\n auto word = QLatin1String(JSC::map[j].str);\n\n out.append(word);\n if (!separators.isEmpty() && separators.first() == start + k) {\n out.append(\" \");\n separators.removeFirst();\n }\n\n start = start + (k + 1);\n }\n\n return out.join(\"\");\n}" }, { "path": "JS8_JSC/JSC.cpp", "line": 71, "pattern": "\\bcompress\\s*\\(", "chars": 1327, "context": { "start_line": 68, "end_line": 74, "lines": [ { "line": 68, "text": " * @param text" }, { "line": 69, "text": " * @return QList" }, { "line": 70, "text": " */" }, { "line": 71, "text": "QList JSC::compress(QString text) {" }, { "line": 72, "text": " QList out;" }, { "line": 73, "text": "" }, { "line": 74, "text": " const quint32 b = 4;" } ] }, "body_preview": "compress(QString text) {\n QList out;\n\n const quint32 b = 4;\n const quint32 s = 7;\n const quint32 c = pow(2, 4) - s;\n\n QString space(\" \");\n\n QStringList words = text.split(\" \", Qt::KeepEmptyParts);\n\n for (int i = 0, len = words.length(); i < len; i++) {\n QString w = words[i];\n\n bool isLastWord = (i == len - 1);\n bool ok = false;\n bool isSpaceCharacter = false;\n\n // if this is an empty part, it should be a space, unless its the last\n // word.\n if (w.isEmpty() && !isLastWord) {\n w = space;\n isSpaceCharacter = true;\n }\n\n while (!w.isEmpty()) {\n // this does both prefix and full match lookup\n auto index = lookup(w, &ok);\n if (!ok) {\n break;\n }\n\n auto t = JSC::map[index];\n\n w = QString(w).mid(t.size);\n\n bool isLast = w.isEmpty();\n bool shouldAppendSpace = isLast && !isSpaceCharacter && !isLastWord;\n\n out.append(\n {codeword(index, shouldAppendSpace, b, s, c),\n (quint32)t.size + (shouldAppendSpace\n ? 1\n : 0) /* for the space that follows */});\n }\n }\n\n return out;\n}" } ], "webftr_adapter_hint": { "safe_to_poll_read_only": true, "productive_integration": false, "do_not_merge_as_chat_text_yet": true, "step68_contract_remains_current_ui_source": true }, "verdict": "jsc_source_ready_no_data_frames_in_current_fixture", "warnings": [ "Step69 is research/audit only and remains RX-only.", "No JS8 free-text rows are released by this step.", "JSC::decompress must be ported with source fixtures before FrameData/FrameDataCompressed can be shown as chat text." ], "next_action": "Port JSC::decompress using the extracted source path, then wait for or inject a FrameData/FrameDataCompressed fixture to validate free text.", "stable_latest_written": "/decoders/js8_decoder/logs/js8_jsc_decompress_source_audit_latest.json" } [webftr-js8-lab] JSON output: /decoders/js8_decoder/logs/20260527T183331Z_data_frame_text_unpack_probe_output.json [webftr-js8-lab] JSON timeout guard: 180s { "ok": true, "tool": "webftr-js8-data-frame-text-unpack-probe", "tool_version": "step70-data-frame-text-unpack-probe", "schema": "webftr-js8-data-frame-text-unpack-probe-v1", "rx_only_guard": { "tx": false, "ptt": false, "tune": false, "send": false, "js8call_runtime_control": false, "webftr_productive_integration": false }, "no_gui_runtime_started": true, "root": "/decoders/js8_decoder", "log_dir": "/decoders/js8_decoder/logs", "input_reports": [ { "path": "/decoders/js8_decoder/logs/20260527T183331Z_jsc_decompress_source_audit_output.json", "exists": true, "selected_input": true } ], "source_resolution": { "source_dir": "/decoders/js8_decoder/runtime/src/JS8Call-improved", "source_found": true, "checked": [ { "path": "/decoders/js8_decoder/runtime/src/JS8Call-improved", "exists": true, "is_dir": true } ], "focused_files_present": [ "JS8_Main/Varicode.cpp", "JS8_Main/Varicode.h", "JS8_JSC/JSC.cpp", "JS8_JSC/JSC.h", "JS8_JSC/JSC_map.cpp", "JS8_JSC/JSC_list.cpp", "JS8_Mode/JS8.cpp", "JS8_Mode/JS8.h" ], "focused_files_missing": [ "JS8_JSC/jsc.cpp", "JS8_JSC/jsc.h" ] }, "jsc_decode_path_evidence": { "has_jsc_decompress_reference": true, "has_unpack_fast_data_message": true, "has_unpack_legacy_data_message": true, "has_huff_fallback_evidence": true, "expected_source_flow": [ "unpack72bits(message174_text) -> 72 bits", "FrameData/FrameDataCompressed bits are trimmed at the final zero padding marker", "compressed path calls JSC::decompress(bits)", "legacy non-compressed path uses Varicode::huffDecode(defaultHuffTable, bits)", "Step69 does not yet display free text; it only extracts and documents the source path for a safe Step70 port." ] }, "source_trim_contract": { "message174_to_72_bits": "unpack72bits(message174_text) -> 64-bit value + 8-bit remainder", "legacy_data_flags": "bit0=data, bit1=compressed", "legacy_noncompressed_path": "payload bits between data/compressed flags and final zero delimiter -> Varicode::huffDecode(defaultHuffTable)", "compressed_path": "same trim family, then JSC::decompress(payload bits); still blocked in Step70", "chat_release": "disabled; this step is a guarded port/harness probe only" }, "current_fixture_has_data_frames": false, "data_frame_candidate_count": 0, "data_frame_text_rows": [], "synthetic_selftest_fixtures": [ { "fixture_kind": "legacy_noncompressed_huff_data_frame", "input_text": "TEST", "message174_text_12chars": "jbDV++++++++", "payload_bit_count": 16, "bits72_prefix": "1011011001010011010111111111111111111111", "unpack_result": { "message_text_12chars": "jbDV++++++++", "ok": true, "data_text_release_allowed": false, "release_guard": "step70_diagnostics_only_no_chat_release", "top2": 2, "top3": 5, "is_data_flag": true, "compressed_flag": false, "last_zero_index": 18, "payload_bit_count": 16, "payload_preview_bits": "1101100101001101", "source_trim_rule": "bits[2:last_zero] using final zero as padding delimiter for legacy data frames", "frame_text_path": "legacy_huff_noncompressed", "huff_decode": { "text": "TEST", "consumed_bits": 16, "remaining_bits": 0, "complete": true }, "decoded_text": "TEST", "jsc_decompress_needed": false, "diagnostic_text_plausible": true, "warning": "Decoded only as a diagnostic legacy Huff data frame. It is not released to WebFTR chat rows in Step70." }, "passes": true }, { "fixture_kind": "legacy_noncompressed_huff_data_frame", "input_text": "CQ", "message174_text_12chars": "iI3+++++++++", "payload_bit_count": 13, "bits72_prefix": "1011000100100000111111111111111111111111", "unpack_result": { "message_text_12chars": "iI3+++++++++", "ok": true, "data_text_release_allowed": false, "release_guard": "step70_diagnostics_only_no_chat_release", "top2": 2, "top3": 5, "is_data_flag": true, "compressed_flag": false, "last_zero_index": 15, "payload_bit_count": 13, "payload_preview_bits": "1100010010000", "source_trim_rule": "bits[2:last_zero] using final zero as padding delimiter for legacy data frames", "frame_text_path": "legacy_huff_noncompressed", "huff_decode": { "text": "CQ", "consumed_bits": 13, "remaining_bits": 0, "complete": true }, "decoded_text": "CQ", "jsc_decompress_needed": false, "diagnostic_text_plausible": true, "warning": "Decoded only as a diagnostic legacy Huff data frame. It is not released to WebFTR chat rows in Step70." }, "passes": true } ], "selftest_fixture_pass_count": 2, "webftr_rx_rows": [], "webftr_display_count": 0, "webftr_adapter_hint": { "safe_to_poll_read_only": true, "productive_integration": false, "do_not_merge_as_chat_text_yet": true, "step68_contract_remains_current_ui_source": true }, "verdict": "data_frame_trim_and_huff_harness_ready_no_current_data_frames", "warnings": [ "Step70 remains RX-only and does not start JS8Call GUI/Qt.", "Step70 does not release decoded data text to WebFTR chat/RX rows.", "Compressed FrameData still needs a source-faithful JSC::decompress table port before free text can be considered displayable." ], "next_action": "Wait for or inject a real FrameData/FrameDataCompressed fixture, then run Step70 again; next implementation step is JSC table extraction/port for compressed frames.", "stable_latest_written": "/decoders/js8_decoder/logs/js8_data_frame_text_unpack_probe_latest.json" } [webftr-js8-lab] OK [webftr-js8-lab] log file: /decoders/js8_decoder/logs/20260527T183331Z_data-frame-text-unpack-probe.log [webftr-js8-lab] manifest: /decoders/js8_decoder/logs/20260527T183331Z_data-frame-text-unpack-probe_manifest.json