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 "web_socket_frame.h" 20 21#include <string> 22 23namespace OHOS::ArkCompiler::Toolchain { 24template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>> 25inline 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 35class ServerFrameBuilder { 36public: 37 // force users to specify opcode and final bit 38 ServerFrameBuilder() = delete; 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 52protected: 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 58protected: 59 bool fin_; 60 FrameType opcode_; 61 std::string payload_; 62}; 63 64class ClientFrameBuilder final : public ServerFrameBuilder { 65public: 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 70private: 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 75private: 76 uint8_t maskingKey_[WebSocketFrame::MASK_LEN] = {0}; 77}; 78} // namespace OHOS::ArkCompiler::Toolchain 79 80#endif // ARKCOMPILER_TOOLCHAIN_WEBSOCKET_FRAME_BUILDER_H 81