aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/streams/zc_memory_input/zc_memory_input.h
blob: c939d8e42632977cfd86e194d5e0c6761e319671 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#pragma once

#include <util/stream/mem.h>
#include <util/system/defaults.h>
#include <util/generic/yexception.h>

/// Zero-copy memory input with fixed read
class TZCMemoryInput: public TMemoryInput {
public:
    TZCMemoryInput() {
    }

    TZCMemoryInput(const char* dataPtr, size_t size)
        : TMemoryInput(dataPtr, size)
    {
    }

    TZCMemoryInput(TMemoryInput& rhs)
        : TMemoryInput(rhs.Buf(), rhs.Avail())
    {
    }

    /// if there's 'size' data read it, otherwise just return false
    Y_FORCE_INLINE bool ReadFixed(const char*& buf, size_t size) {
        if (Avail() >= size) {
            buf = Buf();
            Reset(Buf() + size, Avail() - size);
            return true;
        }
        return false;
    }

    template <class T>
    Y_FORCE_INLINE T LoadPOD() {
        const char* buf = nullptr;
        if (!ReadFixed(buf, sizeof(T)))
            ythrow yexception() << "TZCMemoryInput::LoadPOD failed: not enough data ("
                                << Avail() << " of " << sizeof(T) << " bytes)";
        T res;
        memcpy(&res, buf, sizeof(T));
        return res;
    }

    template <class T>
    Y_FORCE_INLINE void ReadPOD(T& x) {
        x = LoadPOD<T>();
    }
};