1 /*
2  * Copyright (c) 2023 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 
17 #ifndef PRINT_HTTP_REQUEST_PROCESS_H_
18 #define PRINT_HTTP_REQUEST_PROCESS_H_
19 #ifdef IPPOVERUSB_ENABLE
20 
21 #include <string>
22 #include <queue>
23 #include <mutex>
24 #include "singleton.h"
25 #include "httplib.h"
26 #include "print_usb_manager.h"
27 
28 namespace OHOS::Print {
29 template<class T>
30 class DoubleBufQue {
31 public:
push(T & val)32     void push(T& val)
33     {
34         std::lock_guard<std::mutex> mtx_locker(mutexSwap);
35         writeQueue.emplace(val);
36     }
37 
pop(T & val)38     bool pop(T& val)
39     {
40         if (readQueue.empty()) {
41             std::lock_guard<std::mutex> mtx_locker(mutexSwap);
42             if (writeQueue.empty()) {
43                 return false;
44             }
45             readQueue.swap(writeQueue);
46         }
47         val = readQueue.front();
48         readQueue.pop();
49         return true;
50     }
51 
52 private:
53     std::queue<T> writeQueue;
54     std::queue<T> readQueue;
55     std::mutex mutexSwap;
56 };
57 
58 class PrintHttpRequestProcess {
59 public:
60     PrintHttpRequestProcess();
61     virtual ~PrintHttpRequestProcess();
62 
63     uint32_t ProcessRequest(const httplib::Request &requestData, httplib::Response &responseData,
64         const httplib::ContentReader &content_reader);
65 
66     void SetDeviceName(std::string name);
67     std::string GetDeviceName();
68 
69     void Stop();
70 
71 private:
72     std::string PrintOperation(Operation operation);
73     size_t NeedOffset(const std::vector<uint8_t> &readTempBuffer);
74     void RecordBufByOperation(Operation operation, size_t requestId, const std::vector<uint8_t> &tmVector);
75     void GetContentLength(const std::vector<uint8_t> &readTempBuffer, size_t index, bool &findContentLength,
76         size_t &contentLength);
77     void DumpRespIdCode(const std::vector<uint8_t> &readTempBuffer, Operation operation, size_t begin, size_t maxSize);
78     bool ProcessDataFromDevice(Operation operation);
79     void StartWriteDataToPrinterLooper();
80     void StartReadSendDocDataFromPrinterLooper();
81     void ProcessHttpResponse(httplib::Response &responseData, size_t requestId);
82     void ProcessHttpResponseGetAttr(httplib::Response &responseData, size_t requestId);
83     void ProcessHttpResponseSendDoc(httplib::Response &responseData, size_t requestId);
84     bool DealRequestHeader(const httplib::Request &requestData, std::string &sHeadersAndBody);
85     void CalcReqIdOperaId(const char *data, size_t dataLength, size_t &requestId);
86     void ProcessOtherRequest(const char *data, size_t data_length, std::string &sHeadersAndBody, size_t requestId);
87     void DumpReqIdOperaId(const char *data, size_t data_length);
88     std::string CreateChunk(const char *data, size_t data_length);
89     void CreatWriteDataTask();
90     void CreatReadSendDocTask();
91     bool CheckLineEnd(std::vector<uint8_t> &readTempBuffer, size_t index);
92     size_t CalculateRequestId(std::vector<uint8_t> &readTempBuffer, size_t index, Operation operation);
93     size_t CalculateFileDataBeginIndex(size_t index, Operation operation);
94     int32_t WriteDataSync(const std::string &dataStr);
95     int32_t BulkTransferWriteData(const std::string &dataStr);
96     void ProcessHttpResp(size_t requestId, httplib::Response &responseData, const std::string &sHeadersAndBody);
97     void GetAttrAgain(Operation operation, std::vector<uint8_t> &tmVector);
98 
99 private:
100     bool needWriteData = false;
101     bool needReadSendDoc = false;
102     bool needWriteSendDoc = false;
103     bool deviceOpen = true;
104 
105     std::map<size_t, size_t> reqIdOperaIdMap;  // requestId + operationId
106     std::map<size_t, std::vector<uint8_t>> readBufMap; // requestId + buffer
107     std::map<size_t, std::vector<uint8_t>> readSendDocBufMap; // requestId + buffer
108     std::map<size_t, std::vector<uint8_t>> readGetAttrBufMap; // requestId + buffer
109 
110     std::string devName;
111 
112     std::mutex mutexCommon;
113     std::mutex mutexGetAttr;
114     std::mutex mutexSendDoc;
115 
116     DoubleBufQue<std::string> sendDocDataQue;
117     DoubleBufQue<std::string> ippDataQue;
118     size_t sendDocTotalLen = 0;
119 };
120 
121 }
122 
123 #endif // PRINT_HTTP_REQUEST_PROCESS_H_
124 #endif // IPPOVERUSB_ENABLE