Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / lib / mdns / minimal / ResponseBuilder.h
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17
18 #pragma once
19
20 #include <system/SystemPacketBuffer.h>
21
22 #include <mdns/minimal/core/DnsHeader.h>
23 #include <mdns/minimal/records/ResourceRecord.h>
24
25 namespace mdns {
26 namespace Minimal {
27
28 /// Writes a MDNS reply into a given packet buffer.
29 class ResponseBuilder
30 {
31 public:
32     ResponseBuilder() : mHeader(nullptr) {}
33     ResponseBuilder(chip::System::PacketBufferHandle && packet) : mHeader(nullptr) { Reset(std::move(packet)); }
34
35     ResponseBuilder & Reset(chip::System::PacketBufferHandle && packet)
36     {
37         mPacket = std::move(packet);
38         mHeader = HeaderRef(mPacket->Start());
39
40         if (mPacket->AvailableDataLength() >= HeaderRef::kSizeBytes)
41         {
42             mPacket->SetDataLength(HeaderRef::kSizeBytes);
43             mHeader.Clear();
44             mBuildOk = true;
45         }
46         else
47         {
48             mBuildOk = false;
49         }
50
51         mHeader.SetFlags(mHeader.GetFlags().SetResponse());
52         return *this;
53     }
54
55     CHECK_RETURN_VALUE
56     chip::System::PacketBufferHandle ReleasePacket()
57     {
58         mHeader  = HeaderRef(nullptr);
59         mBuildOk = false;
60         return std::move(mPacket);
61     }
62
63     bool HasResponseRecords() const
64     {
65         return (mHeader.GetAnswerCount() != 0) || (mHeader.GetAuthorityCount() != 0) || (mHeader.GetAdditionalCount() != 0);
66     }
67
68     HeaderRef & Header() { return mHeader; }
69
70     /// Attempts to add a record to the currentsystem packet buffer.
71     /// On success, the packet buffer data length is updated.
72     /// On failure, the packet buffer data length is NOT updated and header is unchanged.
73     ResponseBuilder & AddRecord(ResourceType type, const ResourceRecord & record)
74     {
75         if (!mBuildOk)
76         {
77             return *this;
78         }
79
80         chip::Encoding::BigEndian::BufferWriter out(mPacket->Start() + mPacket->DataLength(), mPacket->AvailableDataLength());
81
82         if (!record.Append(mHeader, type, out))
83         {
84             mBuildOk = false;
85         }
86         else
87         {
88             mPacket->SetDataLength(static_cast<uint16_t>(mPacket->DataLength() + out.Needed()));
89         }
90         return *this;
91     }
92
93     ResponseBuilder & AddQuery(const QueryData & query)
94     {
95         if (!mBuildOk)
96         {
97             return *this;
98         }
99
100         chip::Encoding::BigEndian::BufferWriter out(mPacket->Start() + mPacket->DataLength(), mPacket->AvailableDataLength());
101
102         if (!query.Append(mHeader, out))
103         {
104             mBuildOk = false;
105         }
106         else
107         {
108             mPacket->SetDataLength(static_cast<uint16_t>(mPacket->DataLength() + out.Needed()));
109         }
110         return *this;
111     }
112
113     bool Ok() const { return mBuildOk; }
114     bool HasPacketBuffer() const { return !mPacket.IsNull(); }
115
116 private:
117     chip::System::PacketBufferHandle mPacket;
118     HeaderRef mHeader;
119     bool mBuildOk = false;
120 };
121
122 } // namespace Minimal
123 } // namespace mdns