1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef ARKCOMPILER_TOOLCHAIN_WEBSOCKET_FRAME_BUILDER_H
17 #define ARKCOMPILER_TOOLCHAIN_WEBSOCKET_FRAME_BUILDER_H
18
19 #include "websocket/web_socket_frame.h"
20
21 #include <string>
22
23 namespace OHOS::ArkCompiler::Toolchain {
24 template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
PushNumberPerByte(std::string & message,T number)25 inline void PushNumberPerByte(std::string& message, T number)
26 {
27 constexpr size_t bytesCount = sizeof(T);
28 constexpr size_t bitsCount = 8;
29 size_t shiftCount = (bytesCount - 1) * bitsCount;
30 for (size_t i = 0; i < bytesCount; ++i, shiftCount -= bitsCount) {
31 message.push_back((number >> shiftCount) & 0xff);
32 }
33 }
34
35 class ServerFrameBuilder {
36 public:
37 // force users to specify opcode and final bit
38 ServerFrameBuilder() = delete;
ServerFrameBuilder(bool final,FrameType opcode)39 ServerFrameBuilder(bool final, FrameType opcode) : fin_(final), opcode_(opcode)
40 {
41 }
42 ~ServerFrameBuilder() noexcept = default;
43
44 ServerFrameBuilder& SetFinal(bool fin);
45 ServerFrameBuilder& SetOpcode(FrameType opcode);
46 ServerFrameBuilder& SetPayload(const std::string& payload);
47 ServerFrameBuilder& SetPayload(std::string&& payload);
48 ServerFrameBuilder& AppendPayload(const std::string& payload);
49
50 std::string Build() const;
51
52 protected:
53 void PushHeader(std::string& message, uint8_t payloadLenField) const;
54 void PushPayloadLength(std::string& message, uint8_t payloadLenField) const;
55 virtual void PushFullHeader(std::string& message, size_t additionalReservedMem) const;
56 virtual void PushPayload(std::string& message) const;
57
58 protected:
59 bool fin_;
60 FrameType opcode_;
61 std::string payload_;
62 };
63
64 class ClientFrameBuilder final : public ServerFrameBuilder {
65 public:
66 ClientFrameBuilder(bool final, FrameType opcode, const uint8_t maskingKey[WebSocketFrame::MASK_LEN]);
67
68 ClientFrameBuilder& SetMask(const uint8_t maskingKey[WebSocketFrame::MASK_LEN]);
69
70 private:
71 void PushMask(std::string& message) const;
72 void PushFullHeader(std::string& message, size_t additionalReservedMem) const override;
73 void PushPayload(std::string& message) const override;
74
75 private:
76 uint8_t maskingKey_[WebSocketFrame::MASK_LEN] = {0};
77 };
78 } // namespace OHOS::ArkCompiler::Toolchain
79
80 #endif // ARKCOMPILER_TOOLCHAIN_WEBSOCKET_FRAME_BUILDER_H
81