aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/netliba/socket/udp_recv_packet.h
blob: a02e4c9b509174d68f1337fc7a8270fecc46fd90 (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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#pragma once

#include <util/generic/noncopyable.h>
#include <util/system/defaults.h>

#include <memory>
#include "allocator.h"

namespace NNetlibaSocket {
    constexpr int UDP_MAX_PACKET_SIZE = 8900;

    class TUdpHostRecvBufAlloc;
    struct TUdpRecvPacket: public TWithCustomAllocator {
        friend class TUdpHostRecvBufAlloc;
        int DataStart = 0, DataSize = 0;
        std::shared_ptr<char> Data;

    private:
        int ArraySize_ = 0;
    };

    ///////////////////////////////////////////////////////////////////////////////

    class TUdpHostRecvBufAlloc: public TNonCopyable {
    private:
        mutable TUdpRecvPacket* RecvPktBuf;

        static TUdpRecvPacket* Alloc() {
            return new TUdpRecvPacket();
        }

    public:
        static TUdpRecvPacket* Create(const int dataSize) {
            TUdpRecvPacket* result = Alloc();
            result->Data.reset(TCustomAllocator<char>().allocate(dataSize), [=](char* p) { TCustomAllocator<char>().deallocate(p, dataSize); }, TCustomAllocator<char>());
            result->ArraySize_ = dataSize;
            return result;
        }
        void SetNewPacket() const {
            RecvPktBuf = CreateNewPacket();
        }

    public:
        static TUdpRecvPacket* CreateNewSmallPacket(int dataSize) {
            return Create(dataSize);
        }
        static TUdpRecvPacket* CreateNewPacket() {
            return Create(UDP_MAX_PACKET_SIZE);
        }
        static TUdpRecvPacket* Clone(const TUdpRecvPacket* pkt) {
            TUdpRecvPacket* result = Alloc();
            result->DataStart = pkt->DataStart;
            result->DataSize = pkt->DataSize;
            result->Data = pkt->Data;
            result->ArraySize_ = pkt->ArraySize_;
            return result;
        }

        TUdpHostRecvBufAlloc() {
            SetNewPacket();
        }
        ~TUdpHostRecvBufAlloc() {
            delete RecvPktBuf;
        }

        TUdpRecvPacket* ExtractPacket() {
            TUdpRecvPacket* res = RecvPktBuf;
            SetNewPacket();
            return res;
        }

        int GetBufSize() const {
            return RecvPktBuf->ArraySize_;
        }
        char* GetDataPtr() const {
            return RecvPktBuf->Data.get();
        }
    };
}