17c804472Sopenharmony_ci/*
27c804472Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
37c804472Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
47c804472Sopenharmony_ci * you may not use this file except in compliance with the License.
57c804472Sopenharmony_ci * You may obtain a copy of the License at
67c804472Sopenharmony_ci *
77c804472Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
87c804472Sopenharmony_ci *
97c804472Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
107c804472Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
117c804472Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127c804472Sopenharmony_ci * See the License for the specific language governing permissions and
137c804472Sopenharmony_ci * limitations under the License.
147c804472Sopenharmony_ci */
157c804472Sopenharmony_ci
167c804472Sopenharmony_ci#include "LocalSocket.h"
177c804472Sopenharmony_ci
187c804472Sopenharmony_ci#include "PreviewerEngineLog.h"
197c804472Sopenharmony_ci
207c804472Sopenharmony_ciLocalSocket::LocalSocket() : pipeHandle(nullptr) {}
217c804472Sopenharmony_ci
227c804472Sopenharmony_ciLocalSocket::~LocalSocket() {}
237c804472Sopenharmony_ci
247c804472Sopenharmony_cibool LocalSocket::ConnectToServer(std::string name, LocalSocket::OpenMode openMode, TransMode transMode)
257c804472Sopenharmony_ci{
267c804472Sopenharmony_ci    std::wstring tempName = std::wstring(name.begin(), name.end());
277c804472Sopenharmony_ci
287c804472Sopenharmony_ci    DWORD openModeWin = GetWinOpenMode(openMode);
297c804472Sopenharmony_ci    pipeHandle = CreateFileW(tempName.c_str(), openModeWin, 0, nullptr, OPEN_EXISTING, 0, NULL);
307c804472Sopenharmony_ci    if (pipeHandle == INVALID_HANDLE_VALUE) {
317c804472Sopenharmony_ci        ELOG("LocalSocket::ConnectToServer CreateFileW failed: %d", GetLastError());
327c804472Sopenharmony_ci        return false;
337c804472Sopenharmony_ci    }
347c804472Sopenharmony_ci
357c804472Sopenharmony_ci    DWORD tranMode = GetWinTransMode(transMode);
367c804472Sopenharmony_ci    if (!SetNamedPipeHandleState(pipeHandle, &tranMode, nullptr, nullptr)) {
377c804472Sopenharmony_ci        ELOG("LocalSocket::ConnectToServer SetNamedPipeHandleState failed: %d", GetLastError());
387c804472Sopenharmony_ci        return false;
397c804472Sopenharmony_ci    }
407c804472Sopenharmony_ci
417c804472Sopenharmony_ci    return true;
427c804472Sopenharmony_ci}
437c804472Sopenharmony_ci
447c804472Sopenharmony_cistd::string LocalSocket::GetTracePipeName(std::string baseName) const
457c804472Sopenharmony_ci{
467c804472Sopenharmony_ci    return std::string("\\\\.\\pipe\\") + baseName;
477c804472Sopenharmony_ci}
487c804472Sopenharmony_ci
497c804472Sopenharmony_cistd::string LocalSocket::GetCommandPipeName(std::string baseName) const
507c804472Sopenharmony_ci{
517c804472Sopenharmony_ci    return std::string("\\\\.\\pipe\\") + baseName + "_commandPipe";
527c804472Sopenharmony_ci}
537c804472Sopenharmony_ci
547c804472Sopenharmony_cistd::string LocalSocket::GetImagePipeName(std::string baseName) const
557c804472Sopenharmony_ci{
567c804472Sopenharmony_ci    return std::string("\\\\.\\pipe\\") + baseName + "_imagePipe";
577c804472Sopenharmony_ci}
587c804472Sopenharmony_ci
597c804472Sopenharmony_civoid LocalSocket::DisconnectFromServer()
607c804472Sopenharmony_ci{
617c804472Sopenharmony_ci    CloseHandle(pipeHandle);
627c804472Sopenharmony_ci}
637c804472Sopenharmony_ci
647c804472Sopenharmony_ciint64_t LocalSocket::ReadData(char* data, size_t length) const
657c804472Sopenharmony_ci{
667c804472Sopenharmony_ci    if (length > UINT32_MAX) {
677c804472Sopenharmony_ci        ELOG("LocalSocket::ReadData length must < %d", UINT32_MAX);
687c804472Sopenharmony_ci        return -1;
697c804472Sopenharmony_ci    }
707c804472Sopenharmony_ci
717c804472Sopenharmony_ci    DWORD readSize = 0;
727c804472Sopenharmony_ci    if (!PeekNamedPipe(pipeHandle, nullptr, 0, nullptr, &readSize, nullptr)) {
737c804472Sopenharmony_ci        return 0;
747c804472Sopenharmony_ci    }
757c804472Sopenharmony_ci
767c804472Sopenharmony_ci    if (readSize == 0) {
777c804472Sopenharmony_ci        return 0;
787c804472Sopenharmony_ci    }
797c804472Sopenharmony_ci
807c804472Sopenharmony_ci    if (!ReadFile(pipeHandle, data, static_cast<DWORD>(length), &readSize, NULL)) {
817c804472Sopenharmony_ci        DWORD error = GetLastError();
827c804472Sopenharmony_ci        ELOG("LocalSocket::ReadData ReadFile failed: %d", error);
837c804472Sopenharmony_ci        return 0 - static_cast<int64_t>(error);
847c804472Sopenharmony_ci    }
857c804472Sopenharmony_ci    return readSize;
867c804472Sopenharmony_ci}
877c804472Sopenharmony_ci
887c804472Sopenharmony_cisize_t LocalSocket::WriteData(const void* data, size_t length) const
897c804472Sopenharmony_ci{
907c804472Sopenharmony_ci    if (length > UINT32_MAX) {
917c804472Sopenharmony_ci        ELOG("LocalSocket::WriteData length must < %d", UINT32_MAX);
927c804472Sopenharmony_ci        return 0;
937c804472Sopenharmony_ci    }
947c804472Sopenharmony_ci
957c804472Sopenharmony_ci    DWORD writeSize = 0;
967c804472Sopenharmony_ci    if (!WriteFile(pipeHandle, data, static_cast<DWORD>(length), &writeSize, nullptr)) {
977c804472Sopenharmony_ci        DWORD error = GetLastError();
987c804472Sopenharmony_ci        ELOG("LocalSocket::WriteData WriteFile failed: %d", error);
997c804472Sopenharmony_ci        return 0 - static_cast<size_t>(error);
1007c804472Sopenharmony_ci    }
1017c804472Sopenharmony_ci    return writeSize;
1027c804472Sopenharmony_ci}
1037c804472Sopenharmony_ci
1047c804472Sopenharmony_ciconst LocalSocket& LocalSocket::operator<<(const std::string data) const
1057c804472Sopenharmony_ci{
1067c804472Sopenharmony_ci    WriteData(data.c_str(), data.length() + 1);
1077c804472Sopenharmony_ci    return *this;
1087c804472Sopenharmony_ci}
1097c804472Sopenharmony_ci
1107c804472Sopenharmony_ciconst LocalSocket& LocalSocket::operator>>(std::string& data) const
1117c804472Sopenharmony_ci{
1127c804472Sopenharmony_ci    char c = '\255';
1137c804472Sopenharmony_ci    while (c != '\0' && ReadData(&c, 1) > 0) {
1147c804472Sopenharmony_ci        data.push_back(c);
1157c804472Sopenharmony_ci    }
1167c804472Sopenharmony_ci    return *this;
1177c804472Sopenharmony_ci}
1187c804472Sopenharmony_ci
1197c804472Sopenharmony_ciDWORD LocalSocket::GetWinOpenMode(LocalSocket::OpenMode mode) const
1207c804472Sopenharmony_ci{
1217c804472Sopenharmony_ci    DWORD openModeWin = GENERIC_READ;
1227c804472Sopenharmony_ci    switch (mode) {
1237c804472Sopenharmony_ci        case READ_ONLY:
1247c804472Sopenharmony_ci            openModeWin = GENERIC_READ;
1257c804472Sopenharmony_ci            break;
1267c804472Sopenharmony_ci        case WRITE_ONLY:
1277c804472Sopenharmony_ci            openModeWin = GENERIC_WRITE;
1287c804472Sopenharmony_ci            break;
1297c804472Sopenharmony_ci        case READ_WRITE:
1307c804472Sopenharmony_ci            openModeWin = GENERIC_READ | GENERIC_WRITE;
1317c804472Sopenharmony_ci    }
1327c804472Sopenharmony_ci    return openModeWin;
1337c804472Sopenharmony_ci}
1347c804472Sopenharmony_ci
1357c804472Sopenharmony_ciDWORD LocalSocket::GetWinTransMode(LocalSocket::TransMode mode) const
1367c804472Sopenharmony_ci{
1377c804472Sopenharmony_ci    DWORD transMode = PIPE_READMODE_BYTE;
1387c804472Sopenharmony_ci    switch (mode) {
1397c804472Sopenharmony_ci        case TRANS_BYTE:
1407c804472Sopenharmony_ci            transMode = PIPE_READMODE_BYTE;
1417c804472Sopenharmony_ci            break;
1427c804472Sopenharmony_ci        case TRANS_MESSAGE:
1437c804472Sopenharmony_ci            transMode = PIPE_READMODE_MESSAGE;
1447c804472Sopenharmony_ci            break;
1457c804472Sopenharmony_ci    }
1467c804472Sopenharmony_ci    return transMode;
1477c804472Sopenharmony_ci}
148