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