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/InputFormat.h>
18 #include <sstream>
19 #include "utils/Utils.h"
20 #include "ModelError.h"
21 
22 using namespace AlibabaCloud::OSS;
23 
CSVHeader_Str(CSVHeader num)24 static inline std::string CSVHeader_Str(CSVHeader num)
25 {
26     static const std::string strings[] = {
27         "None\0", "Ignore\0", "Use\0"
28     };
29     return strings[num];
30 }
31 
CompressionType_Str(CompressionType num)32 static inline std::string CompressionType_Str(CompressionType num)
33 {
34     static const std::string strings[] = {
35         "NONE\0",
36         "GZIP\0"
37     };
38     return strings[num];
39 }
40 
JsonType_Str(JsonType num)41 static inline std::string JsonType_Str(JsonType num)
42 {
43     static const std::string strings[] = {
44         "DOCUMENT\0",
45         "LINES\0"
46     };
47     return strings[num];
48 }
49 
Range_Str(const std::string rangePrefix,bool isSet,const int64_t range[2])50 static std::string Range_Str(const std::string rangePrefix,
51     bool isSet, const int64_t range[2])
52 {
53     int64_t start = 0, end = 0;
54     start = range[0];
55     end = range[1];
56 
57     if (!isSet ||
58         (start < 0 && end < 0) ||
59         (start > 0 && end > 0 && start > end)) {
60         return "";
61     }
62 
63     std::ostringstream ostr;
64     if (start < 0) {
65         ostr << rangePrefix << "-" << end;
66     }
67     else if (end < 0) {
68         ostr << rangePrefix << start << "-";
69     }
70     else {
71         ostr << rangePrefix << start << "-" << end;
72     }
73     std::string str = ostr.str();
74     return str;
75 }
76 
77 
InputFormat()78 InputFormat::InputFormat() :
79 	compressionType_(CompressionType::NONE),lineRangeIsSet_(false), splitRangeIsSet_(false)
80 {
81 }
82 
setCompressionType(CompressionType compressionType)83 void InputFormat::setCompressionType(CompressionType compressionType)
84 {
85 	compressionType_ = compressionType;
86 }
87 
CompressionTypeInfo() const88 const std::string InputFormat::CompressionTypeInfo() const
89 {
90 	std::string str = CompressionType_Str(compressionType_);
91 	return str;
92 }
93 
setLineRange(int64_t start,int64_t end)94 void InputFormat::setLineRange(int64_t start, int64_t end)
95 {
96     lineRange_[0] = start;
97     lineRange_[1] = end;
98     lineRangeIsSet_ = true;
99     splitRangeIsSet_ = false;
100 }
101 
setSplitRange(int64_t start,int64_t end)102 void InputFormat::setSplitRange(int64_t start, int64_t end)
103 {
104     splitRange_[0] = start;
105     splitRange_[1] = end;
106     splitRangeIsSet_ = true;
107     lineRangeIsSet_ = false;
108 }
109 
validate() const110 int InputFormat::validate() const
111 {
112     if (lineRangeIsSet_ && splitRangeIsSet_) {
113         return ARG_ERROR_SELECT_OBJECT_RANGE_INVALID;
114     }
115 
116     if (lineRangeIsSet_ &&
117         (lineRange_[0] < 0 || lineRange_[1] < -1 || (lineRange_[1] > -1 && lineRange_[1] < lineRange_[0]))) {
118         return ARG_ERROR_SELECT_OBJECT_LINE_RANGE_INVALID;
119     }
120     if (splitRangeIsSet_ &&
121         (splitRange_[0] < 0 || splitRange_[1] < -1 || (splitRange_[1] > -1 && splitRange_[1] < splitRange_[0]))) {
122         return ARG_ERROR_SELECT_OBJECT_SPLIT_RANGE_INVALID;
123     }
124 
125     return 0;
126 }
127 
RangeToString() const128 std::string InputFormat::RangeToString() const
129 {
130     if (lineRangeIsSet_ && splitRangeIsSet_) {
131         return "";
132     }
133     if (lineRangeIsSet_) {
134         return Range_Str("line-range=", lineRangeIsSet_, lineRange_);
135     }
136     if (splitRangeIsSet_) {
137         return Range_Str("split-range=", splitRangeIsSet_, splitRange_);
138     }
139     return "";
140 }
141 
142 /////////////////////////////////////////////////////////////////////////////////////////
143 
CSVInputFormat()144 CSVInputFormat::CSVInputFormat()
145     : CSVInputFormat(CSVHeader::None, "\n", ",", "\"", "#")
146 {}
147 
CSVInputFormat(CSVHeader headerInfo,const std::string & recordDelimiter,const std::string & fieldDelimiter,const std::string & quoteChar,const std::string & commentChar)148 CSVInputFormat::CSVInputFormat(CSVHeader headerInfo,
149     const std::string& recordDelimiter,
150     const std::string& fieldDelimiter,
151     const std::string& quoteChar,
152     const std::string& commentChar):
153     InputFormat(),
154     headerInfo_(headerInfo),
155     recordDelimiter_(recordDelimiter),
156     fieldDelimiter_(fieldDelimiter),
157     quoteChar_(quoteChar),
158     commentChar_(commentChar)
159 {}
160 
setHeaderInfo(CSVHeader headerInfo)161 void CSVInputFormat::setHeaderInfo(CSVHeader headerInfo)
162 {
163     headerInfo_ = headerInfo;
164 }
165 
setCommentChar(const std::string & commentChar)166 void CSVInputFormat::setCommentChar(const std::string& commentChar)
167 {
168     commentChar_ = commentChar;
169 }
170 
setQuoteChar(const std::string & quoteChar)171 void CSVInputFormat::setQuoteChar(const std::string& quoteChar)
172 {
173     quoteChar_ = quoteChar;
174 }
175 
setFieldDelimiter(const std::string & fieldDelimiter)176 void CSVInputFormat::setFieldDelimiter(const std::string& fieldDelimiter)
177 {
178     fieldDelimiter_ = fieldDelimiter;
179 }
180 
setRecordDelimiter(const std::string & recordDelimiter)181 void CSVInputFormat::setRecordDelimiter(const std::string& recordDelimiter)
182 {
183     recordDelimiter_ = recordDelimiter;
184 }
185 
HeaderInfo() const186 CSVHeader CSVInputFormat::HeaderInfo() const
187 {
188     return headerInfo_;
189 }
190 
RecordDelimiter() const191 const std::string& CSVInputFormat::RecordDelimiter() const
192 {
193     return recordDelimiter_;
194 }
195 
FieldDelimiter() const196 const std::string& CSVInputFormat::FieldDelimiter() const
197 {
198     return fieldDelimiter_;
199 }
200 
QuoteChar() const201 const std::string& CSVInputFormat::QuoteChar() const
202 {
203     return quoteChar_;
204 }
205 
CommentChar() const206 const std::string& CSVInputFormat::CommentChar() const
207 {
208     return commentChar_;
209 }
210 
Type() const211 std::string CSVInputFormat::Type() const
212 {
213     return "csv";
214 }
215 
toXML(int flag) const216 std::string CSVInputFormat::toXML(int flag) const
217 {
218     std::stringstream ss;
219     ss << "<InputSerialization>" << std::endl;
220     ss << "<CompressionType>" << InputFormat::CompressionTypeInfo() << "</CompressionType>" << std::endl;
221     ss << "<CSV>" << std::endl;
222     ss << "<RecordDelimiter>" << Base64Encode(recordDelimiter_) << "</RecordDelimiter>" << std::endl;
223     ss << "<FieldDelimiter>" << Base64Encode(fieldDelimiter_.empty() ? "" : std::string(1, fieldDelimiter_.front())) << "</FieldDelimiter>" << std::endl;
224     ss << "<QuoteCharacter>" << Base64Encode(quoteChar_.empty() ? "" : std::string(1, quoteChar_.front())) << "</QuoteCharacter>" << std::endl;
225     if (flag == 1) {
226         ss << "<FileHeaderInfo>" << CSVHeader_Str(headerInfo_) << "</FileHeaderInfo>" << std::endl;
227         ss << "<CommentCharacter>" << Base64Encode(commentChar_.empty() ? "" : std::string(1, commentChar_.front())) << "</CommentCharacter>" << std::endl;
228         ss << "<Range>" << InputFormat::RangeToString() << "</Range>" << std::endl;
229     }
230     ss << "</CSV>" << std::endl;
231     ss << "</InputSerialization>" << std::endl;
232     return ss.str();
233 }
234 
235 ////////////////////////////////////////////////////////////////////////////////////////
JSONInputFormat()236 JSONInputFormat::JSONInputFormat()
237     : InputFormat()
238 {}
239 
JSONInputFormat(JsonType jsonType)240 JSONInputFormat::JSONInputFormat(JsonType jsonType)
241     : InputFormat(), jsonType_(jsonType)
242 {}
243 
setJsonType(JsonType jsonType)244 void JSONInputFormat::setJsonType(JsonType jsonType)
245 {
246     jsonType_ = jsonType;
247 }
248 
setParseJsonNumberAsString(bool parseJsonNumberAsString)249 void JSONInputFormat::setParseJsonNumberAsString(bool parseJsonNumberAsString)
250 {
251     parseJsonNumberAsString_ = parseJsonNumberAsString;
252 }
253 
JsonInfo() const254 JsonType JSONInputFormat::JsonInfo() const
255 {
256     return jsonType_;
257 }
258 
ParseJsonNumberAsString() const259 bool JSONInputFormat::ParseJsonNumberAsString() const
260 {
261     return parseJsonNumberAsString_;
262 }
263 
Type() const264 std::string JSONInputFormat::Type() const
265 {
266     return "json";
267 }
268 
toXML(int flag) const269 std::string JSONInputFormat::toXML(int flag) const
270 {
271     std::stringstream ss;
272     ss << "<InputSerialization>" << std::endl;
273     ss << "<CompressionType>" << InputFormat::CompressionTypeInfo() << "</CompressionType>" << std::endl;
274     ss << "<JSON>" << std::endl;
275     if (flag == 1) {
276         ss << "<Type>" << JsonType_Str(jsonType_) << "</Type>" << std::endl;
277         ss << "<ParseJsonNumberAsString>" << (parseJsonNumberAsString_ ? "true" : "false") << "</ParseJsonNumberAsString>" << std::endl;
278         ss << "<Range>" << InputFormat::RangeToString() << "</Range>" << std::endl;
279     }
280     else {
281         ss << "<Type>" << "LINES" << "</Type>" << std::endl;
282     }
283 
284     ss << "</JSON>" << std::endl;
285     ss << "</InputSerialization>" << std::endl;
286     return ss.str();
287 }