<commit_before>#pragma once

#include "ur_modern_driver/log.h"
#include "ur_modern_driver/types.h"
#include <assert.h>
#include <cstddef>
#include <cstring>
#include <endian.h>
#include <inttypes.h>
#include <string>

class BinParser {
private:
    uint8_t *_buf_pos, *_buf_end;
    BinParser& _parent;

public:
    BinParser(uint8_t* buffer, size_t buf_len)
        : _buf_pos(buffer)
        , _buf_end(buffer + buf_len)
        , _parent(*this)
    {
        assert(_buf_pos <= _buf_end);
    }

    BinParser(BinParser& parent, size_t sub_len)
        : _buf_pos(parent._buf_pos)
        , _buf_end(parent._buf_pos + sub_len)
        , _parent(parent)
    {
        assert(_buf_pos <= _buf_end);
    }

    ~BinParser()
    {
        _parent._buf_pos = _buf_pos;
    }

    //Decode from network encoding (big endian) to host encoding
    template <typename T>
    T decode(T val)
    {
        return val;
    }
    uint16_t decode(uint16_t val)
    {
        return be16toh(val);
    }
    uint32_t decode(uint32_t val)
    {
        return be32toh(val);
    }
    uint64_t decode(uint64_t val)
    {
        return be64toh(val);
    }
    int16_t decode(int16_t val)
    {
        return be16toh(val);
    }
    int32_t decode(int32_t val)
    {
        return be32toh(val);
    }
    int64_t decode(int64_t val)
    {
        return be64toh(val);
    }
    float decode(float val)
    {
        return be32toh(val);
    }
    double decode(double val)
    {
        return be64toh(val);
    }

    template <typename T>
    T peek()
    {
        assert(_buf_pos <= _buf_end);
        return decode(*(reinterpret_cast<T*>(_buf_pos)));
    }

    template <typename T>
    void parse(T& val)
    {
        val = peek<T>();
        _buf_pos += sizeof(T);
    }

    // UR uses 1 byte for boolean values but sizeof(bool) is implementation
    // defined so we must ensure they're parsed as uint8_t on all compilers
    void parse(bool& val)
    {
        uint8_t inner;
        parse<uint8_t>(inner);
        val = inner != 0;
    }

    // Explicit parsing order of fields to avoid issues with struct layout
    void parse(double3_t& val)
    {
        parse(val.x);
        parse(val.y);<commit_msg>Fixed strict alisasing warnings and double/float big endian issues<commit_after>#pragma once

#include "ur_modern_driver/log.h"
#include "ur_modern_driver/types.h"
#include <assert.h>
#include <cstddef>
#include <cstring>
#include <endian.h>
#include <inttypes.h>
#include <string>

class BinParser {
private:
    uint8_t *_buf_pos, *_buf_end;
    BinParser& _parent;

public:
    BinParser(uint8_t* buffer, size_t buf_len)
        : _buf_pos(buffer)
        , _buf_end(buffer + buf_len)
        , _parent(*this)
    {
        assert(_buf_pos <= _buf_end);
    }

    BinParser(BinParser& parent, size_t sub_len)
        : _buf_pos(parent._buf_pos)
        , _buf_end(parent._buf_pos + sub_len)
        , _parent(parent)
    {
        assert(_buf_pos <= _buf_end);
    }

    ~BinParser()
    {
        _parent._buf_pos = _buf_pos;
    }

    //Decode from network encoding (big endian) to host encoding
    template <typename T>
    T decode(T val)
    {
        return val;
    }
    uint16_t decode(uint16_t val)
    {
        return be16toh(val);
    }
    uint32_t decode(uint32_t val)
    {
        return be32toh(val);
    }
    uint64_t decode(uint64_t val)
    {
        return be64toh(val);
    }
    int16_t decode(int16_t val)
    {
        return be16toh(val);
    }
    int32_t decode(int32_t val)
    {
        return be32toh(val);
    }
    int64_t decode(int64_t val)
    {
        return be64toh(val);
    }

    template <typename T>
    T peek()
    {
        assert(_buf_pos <= _buf_end);
        T val;
        std::memcpy(&val, _buf_pos, sizeof(T));
        return decode(val);
    }

    template <typename T>
    void parse(T& val)
    {
        val = peek<T>();
        _buf_pos += sizeof(T);
    }

    void parse(double& val)
    {
        uint64_t inner;
        parse<uint64_t>(inner);
        std::memcpy(&val, &inner, sizeof(double));
    }
    void parse(float& val)
    {
        uint32_t inner;
        parse<uint32_t>(inner);
        std::memcpy(&val, &inner, sizeof(float));
    }

    // UR uses 1 byte for boolean values but sizeof(bool) is implementation
    // defined so we must ensure they're parsed as uint8_t on all compilers
    void parse(bool& val)
    {
        uint8_t inner;
        parse<uint8_t>(inner);
        val = inner != 0;
    }

    // Explicit parsing order of fields to avoid issues with struct layout
    void parse(double3_t& val)
    {
        parse(val.x);
        parse(val.y);
{'fraction_non_alphanumeric': 0.11051386798537949, 'fraction_numerical': 0.021500752526338422, 'mean_word_length': 2.186301369863014, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6524061', 'n_tokens_mistral': 1714, 'n_tokens_neox': 1634, 'n_words': 368}