1 /*
2  * Copyright 2009-2017 Alibaba Cloud All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <alibabacloud/oss/model/CreateSelectObjectMetaResult.h>
18 #include <iostream>
19 #include <sstream>
20 #include "../utils/Crc32.h"
21 
22 #define FRAME_HEADER_LEN   (12+8)
23 #define PARSE_FOUR_BYTES(a, b, c, d) (((uint64_t)(a) << 24)|((uint64_t)(b) << 16)|((uint64_t)(c) << 8)|(d))
24 #define PARSE_EIGHT_BYTES(a, b, c, d, e, f, g, h) (((uint64_t)(a)<<56)|((uint64_t)(b)<<48)| ((uint64_t)(c)<<40)| ((uint64_t)(d)<<32)| ((uint64_t)(e)<<24)| ((uint64_t)(f)<<16)| ((uint64_t)(g)<<8)| (h))
25 
26 using namespace AlibabaCloud::OSS;
27 
CreateSelectObjectMetaResult()28 CreateSelectObjectMetaResult::CreateSelectObjectMetaResult()
29     :OssResult(),
30     offset_(0),
31     totalScanned_(0),
32     status_(0),
33     splitsCount_(0),
34     rowsCount_(0),
35     colsCount_(0)
36 {
37 }
38 
CreateSelectObjectMetaResult(const std::string & bucket,const std::string & key,const std::string & requestId,const std::shared_ptr<std::iostream> & data)39 CreateSelectObjectMetaResult::CreateSelectObjectMetaResult( const std::string& bucket, const std::string& key,
40     const std::string& requestId, const std::shared_ptr<std::iostream>& data) :
41     CreateSelectObjectMetaResult()
42 {
43     bucket_ = bucket;
44     key_ = key;
45     requestId_ = requestId;
46     *this = data;
47 }
48 
operator =(const std::shared_ptr<std::iostream> & data)49 CreateSelectObjectMetaResult& CreateSelectObjectMetaResult::operator=(const std::shared_ptr<std::iostream>& data)
50 {
51     data->seekg(0, data->beg);
52     uint8_t buffer[36];
53     char messageBuffer[256];
54     parseDone_ = true;
55     while (data->good()) {
56         // header 12 bytes
57         data->read(reinterpret_cast<char*>(buffer), 12);
58         if (!data->good()) {
59             break;
60         }
61         // type 3 bytes
62         int type = 0;
63         type = (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
64         // payload length 4 bytes
65         int length = PARSE_FOUR_BYTES(buffer[4], buffer[5], buffer[6], buffer[7]);
66         // header checksum
67 
68         // payload
69         switch (type)
70         {
71         case 0x800006:
72         case 0x800007:
73         {
74             uint32_t payloadCrc32 = 0;
75             int messageLength = length - 32;
76             data->read(reinterpret_cast<char*>(buffer), 32);
77             payloadCrc32 = CRC32::CalcCRC(payloadCrc32, buffer, 32);
78             // offset 8 bytes
79             offset_ = PARSE_EIGHT_BYTES(buffer[0],buffer[1],buffer[2],buffer[3],
80                     buffer[4],buffer[5],buffer[6],buffer[7]);
81             // total scaned 8bytes
82             totalScanned_ = PARSE_EIGHT_BYTES(buffer[8],buffer[9],buffer[10],buffer[11],
83                     buffer[12],buffer[13],buffer[14],buffer[15]);
84             // status 4 bytes
85             status_ = PARSE_FOUR_BYTES(buffer[16], buffer[17], buffer[18], buffer[19]);
86             // splitsCount 4 bytes
87             splitsCount_ = PARSE_FOUR_BYTES(buffer[20], buffer[21], buffer[22], buffer[23]);
88             // rowsCount 8 bytes
89             rowsCount_ = PARSE_EIGHT_BYTES(buffer[24],buffer[25],buffer[26],buffer[27],
90                     buffer[28],buffer[29],buffer[30],buffer[31]);
91 
92             if (type == 0x800006) {
93                 messageLength -= 4;
94                 // colsCount
95                 data->read(reinterpret_cast<char*>(buffer), 4);
96                 payloadCrc32 = CRC32::CalcCRC(payloadCrc32, buffer, 4);
97                 colsCount_ = PARSE_FOUR_BYTES(buffer[0],buffer[1],buffer[2],buffer[3]);
98             }
99             data->read(messageBuffer, messageLength);
100             payloadCrc32 = CRC32::CalcCRC(payloadCrc32, messageBuffer, messageLength);
101             errorMessage_ = std::string(messageBuffer);
102 
103             if (!data->good()) {
104                 parseDone_ = false;
105                 break;
106             }
107 
108             // payload crc32 checksum
109             uint32_t payloadChecksum = 0;
110             data->read(reinterpret_cast<char*>(buffer), 4);
111             payloadChecksum = PARSE_FOUR_BYTES(buffer[0],buffer[1],buffer[2],buffer[3]);
112             if (payloadChecksum != 0 && payloadChecksum != payloadCrc32) {
113                 parseDone_ = false;
114                 return *this;
115             }
116 
117         }
118         break;
119         default:
120             data->seekg(length + 4, data->cur);
121             break;
122         }
123     }
124     return *this;
125 }
126