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 "Utils.h"
18 
19 #ifdef USE_CRYPTO_MBEDTLS
20 #include "mbedtls/md.h"
21 #include "mbedtls/compat-1.3.h"
22 #include "mbedtls/sha1.h"
23 #include "mbedtls/base64.h"
24 #include "mbedtls/md5.h"
25 
26 #else
27 
28 #include <openssl/evp.h>
29 #include <openssl/hmac.h>
30 #include <openssl/md5.h>
31 
32 #ifdef OPENSSL_IS_BORINGSSL
33 #include <openssl/base64.h>
34 #endif
35 
36 #endif
37 
38 #include <algorithm>
39 #include <cstring>
40 #include <iostream>
41 #include <sstream>
42 #include <map>
43 #include <regex>
44 #include <iomanip>
45 #include <alibabacloud/oss/Const.h>
46 #include <alibabacloud/oss/http/HttpType.h>
47 #include <alibabacloud/oss/http/Url.h>
48 #include "../external/json/json.h"
49 
50 using namespace AlibabaCloud::OSS;
51 
52 #if defined(__GNUG__) && __GNUC__ < 5
53 
54 #else
55 static const std::regex ipPattern("((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])");
56 static const std::regex bucketNamePattern("^[a-z0-9][a-z0-9\\-]{1,61}[a-z0-9]$");
57 static const std::regex loggingPrefixPattern("^[a-zA-Z][a-zA-Z0-9\\-]{0,31}$");
58 #endif
59 
GenerateUuid()60 std::string AlibabaCloud::OSS::GenerateUuid()
61 {
62     return "";
63 }
64 
UrlEncode(const std::string & src)65 std::string AlibabaCloud::OSS::UrlEncode(const std::string & src)
66 {
67     std::stringstream dest;
68     static const char *hex = "0123456789ABCDEF";
69     unsigned char c;
70 
71     for (size_t i = 0; i < src.size(); i++) {
72         c = src[i];
73         if (isalnum(c) || (c == '-') || (c == '_') || (c == '.') || (c == '~')) {
74             dest << c;
75         } else if (c == ' ') {
76             dest << "%20";
77         } else {
78             dest << '%' << hex[c >> 4] << hex[c & 15];
79         }
80     }
81 
82     return dest.str();
83 }
84 
UrlDecode(const std::string & src)85 std::string AlibabaCloud::OSS::UrlDecode(const std::string & src)
86 {
87     std::stringstream unescaped;
88     unescaped.fill('0');
89     unescaped << std::hex;
90 
91     size_t safeLength = src.size();
92     const char *safe = src.c_str();
93     for (auto i = safe, n = safe + safeLength; i != n; ++i)
94     {
95         char c = *i;
96         if(c == '%')
97         {
98             char hex[3];
99             hex[0] = *(i + 1);
100             hex[1] = *(i + 2);
101             hex[2] = 0;
102             i += 2;
103             auto hexAsInteger = strtol(hex, nullptr, 16);
104             unescaped << (char)hexAsInteger;
105         }
106         else
107         {
108             unescaped << *i;
109         }
110     }
111 
112     return unescaped.str();
113 }
114 
Base64Encode(const std::string & src)115 std::string AlibabaCloud::OSS::Base64Encode(const std::string &src)
116 {
117     return AlibabaCloud::OSS::Base64Encode(src.c_str(), static_cast<int>(src.size()));
118 }
119 
Base64Encode(const ByteBuffer & buffer)120 std::string AlibabaCloud::OSS::Base64Encode(const ByteBuffer& buffer)
121 {
122     return AlibabaCloud::OSS::Base64Encode(reinterpret_cast<const char*>(buffer.data()), static_cast<int>(buffer.size()));
123 }
124 
Base64Encode(const char * src,int len)125 std::string AlibabaCloud::OSS::Base64Encode(const char *src, int len)
126 {
127     if (!src || len == 0) {
128         return "";
129     }
130 
131     static const char *ENC = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
132     auto in = reinterpret_cast<const unsigned char *>(src);
133     auto inLen = len;
134     std::stringstream ss;
135     while (inLen) {
136         // first 6 bits of char 1
137         ss << ENC[*in >> 2];
138         if (!--inLen) {
139             // last 2 bits of char 1, 4 bits of 0
140             ss << ENC[(*in & 0x3) << 4];
141             ss << '=';
142             ss << '=';
143             break;
144         }
145         // last 2 bits of char 1, first 4 bits of char 2
146         ss << ENC[((*in & 0x3) << 4) | (*(in + 1) >> 4)];
147         in++;
148         if (!--inLen) {
149             // last 4 bits of char 2, 2 bits of 0
150             ss << ENC[(*in & 0xF) << 2];
151             ss << '=';
152             break;
153         }
154         // last 4 bits of char 2, first 2 bits of char 3
155         ss << ENC[((*in & 0xF) << 2) | (*(in + 1) >> 6)];
156         in++;
157         // last 6 bits of char 3
158         ss << ENC[*in & 0x3F];
159         in++, inLen--;
160     }
161     return ss.str();
162 }
163 
Base64EncodeUrlSafe(const std::string & src)164 std::string AlibabaCloud::OSS::Base64EncodeUrlSafe(const std::string &src)
165 {
166     return AlibabaCloud::OSS::Base64EncodeUrlSafe(src.c_str(), static_cast<int>(src.size()));
167 }
168 
Base64EncodeUrlSafe(const char * src,int len)169 std::string AlibabaCloud::OSS::Base64EncodeUrlSafe(const char *src, int len)
170 {
171     std::string out = AlibabaCloud::OSS::Base64Encode(src, len);
172 
173     while (out.size() > 0 && *out.rbegin() == '=')
174         out.pop_back();
175 
176     std::transform(out.begin(), out.end(), out.begin(), [](unsigned char c) {
177         if (c == '+') return '-';
178         if (c == '/') return '_';
179         return (char)c;
180     });
181     return out;
182 }
183 
XmlEscape(const std::string & value)184 std::string AlibabaCloud::OSS::XmlEscape(const std::string& value)
185 {
186     struct Entity {
187         const char* pattern;
188         char value;
189     };
190 
191     static const Entity entities[] = {
192         { "&quot;", '\"' },
193         { "&amp;",  '&'  },
194         { "&apos;", '\'' },
195         { "&lt;",	'<'  },
196         { "&gt;",	'>'  },
197         { "&#13;",	'\r' }
198     };
199 
200     if (value.empty()) {
201         return value;
202     }
203 
204     std::stringstream ss;
205     for (size_t i = 0; i < value.size(); i++) {
206         bool flag = false;
207         for (size_t j = 0; j < (sizeof(entities)/sizeof(entities[0])); j++) {
208             if (value[i] == entities[j].value) {
209                 flag = true;
210                 ss << entities[j].pattern;
211                 break;
212             }
213         }
214 
215         if (!flag) {
216             ss << value[i];
217         }
218     }
219 
220     return ss.str();
221 }
Base64Decode(const char * data,int len)222 ByteBuffer AlibabaCloud::OSS::Base64Decode(const char *data, int len)
223 {
224     int in_len = len;
225     int i = 0;
226     int in_ = 0;
227     unsigned char part4[4];
228 
229     const int max_len = (len * 3 / 4);
230     ByteBuffer ret(max_len);
231     int idx = 0;
232 
233     while (in_len-- && (data[in_] != '=')) {
234         unsigned char ch = data[in_++];
235         if ('A' <= ch && ch <= 'Z')  ch = ch - 'A';           // A - Z
236         else if ('a' <= ch && ch <= 'z') ch = ch - 'a' + 26;  // a - z
237         else if ('0' <= ch && ch <= '9') ch = ch - '0' + 52;  // 0 - 9
238         else if ('+' == ch) ch = 62;                          // +
239         else if ('/' == ch) ch = 63;                          // /
240         else if ('=' == ch) ch = 64;                          // =
241         else ch = 0xff;                                       // something wrong
242         part4[i++] = ch;
243         if (i == 4) {
244             ret[idx++] = (part4[0] << 2) + ((part4[1] & 0x30) >> 4);
245             ret[idx++] = ((part4[1] & 0xf) << 4) + ((part4[2] & 0x3c) >> 2);
246             ret[idx++] = ((part4[2] & 0x3) << 6) + part4[3];
247             i = 0;
248         }
249     }
250 
251     if (i) {
252         for (int j = i; j < 4; j++)
253             part4[j] = 0xFF;
254         ret[idx++] = (part4[0] << 2) + ((part4[1] & 0x30) >> 4);
255         if (part4[2] != 0xFF) {
256             ret[idx++] = ((part4[1] & 0xf) << 4) + ((part4[2] & 0x3c) >> 2);
257             if (part4[3] != 0xFF) {
258                 ret[idx++] = ((part4[2] & 0x3) << 6) + part4[3];
259             }
260         }
261     }
262 
263     ret.resize(idx);
264     return ret;
265 }
266 
Base64Decode(const std::string & src)267 ByteBuffer AlibabaCloud::OSS::Base64Decode(const std::string &src)
268 {
269     return Base64Decode(src.c_str(), src.size());
270 }
271 
272 
ComputeContentMD5(const std::string & data)273 std::string AlibabaCloud::OSS::ComputeContentMD5(const std::string& data)
274 {
275     return ComputeContentMD5(data.c_str(), data.size());
276 }
277 
ComputeContentMD5(const char * data,size_t size)278 std::string AlibabaCloud::OSS::ComputeContentMD5(const char * data, size_t size)
279 {
280 #if defined(USE_CRYPTO_MBEDTLS)
281     unsigned char md_data[16];
282     unsigned int mdLen = 16;
283     mbedtls_md5_context ctx;
284 	unsigned int olen = 0;
285 #if 0
286     mbedtls_md5_init(&ctx);
287     mbedtls_md5_starts(&ctx);
288     mbedtls_md5_update(&ctx, (const unsigned char *)data, size);
289     mbedtls_md5_finish(&ctx, md_data);
290     mbedtls_md5_free(&ctx);
291 #endif
292 
293 	mbedtls_md5_ret((const unsigned char*)data, size, md_data);
294 
295     char encodedData[100];
296 
297     mbedtls_base64_encode((unsigned char*)encodedData, sizeof(encodedData), &olen, md_data, mdLen);
298 
299     return encodedData;
300     //TODO: ethan: not used for the moment
301 #elif 0//defined(USE_CRYPTO_MBEDTLS)
302 	unsigned char md_data[16];
303     unsigned int mdLen = 16;
304     unsigned int olen = 0;
305 
306 	mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_MD5), data, size, md_data);
307 
308 	char encodedData[100];
309 
310     mbedtls_base64_encode((unsigned char*)encodedData, sizeof(encodedData), &olen, md_data, mdLen);
311 
312     return encodedData;
313 #else
314 
315     unsigned char md[MD5_DIGEST_LENGTH];
316     MD5(reinterpret_cast<const unsigned char*>(data), size, (unsigned char*)&md);
317 
318     char encodedData[100];
319 
320     EVP_EncodeBlock(reinterpret_cast<unsigned char*>(encodedData), md, MD5_DIGEST_LENGTH);
321 
322     return encodedData;
323 #endif
324 }
325 
ComputeContentMD5(std::istream & stream)326 std::string AlibabaCloud::OSS::ComputeContentMD5(std::istream& stream)
327 {
328 #ifdef USE_CRYPTO_MBEDTLS
329 	unsigned char md_value[16];
330     unsigned int md_len = 16;
331     unsigned int olen = 0;
332     mbedtls_md5_context ctx;
333 
334     mbedtls_md5_init(&ctx);
335     mbedtls_md5_starts_ret(&ctx);
336 
337     auto currentPos = stream.tellg();
338     if (currentPos == static_cast<std::streampos>(-1)) {
339         currentPos = 0;
340         stream.clear();
341     }
342     stream.seekg(0, stream.beg);
343 
344 	// TODO: ethan, need to shrink the buffer, or stack overflow may happen?
345 
346     char streamBuffer[2048];
347     while (stream.good())
348     {
349         stream.read(streamBuffer, 2048);
350         auto bytesRead = stream.gcount();
351 
352         if (bytesRead > 0)
353         {
354             mbedtls_md5_update_ret(&ctx, (const unsigned char*)streamBuffer, static_cast<size_t>(bytesRead));
355         }
356     }
357 
358     mbedtls_md5_finish_ret(&ctx, md_value);
359     mbedtls_md5_free(&ctx);
360 
361     stream.clear();
362     stream.seekg(currentPos, stream.beg);
363 
364     //Based64
365     char encodedData[100];
366 
367     mbedtls_base64_encode((unsigned char*)encodedData, sizeof(encodedData), &olen, md_value, md_len);
368 
369     return encodedData;
370 #else
371     auto ctx = EVP_MD_CTX_create();
372 
373     unsigned char md_value[EVP_MAX_MD_SIZE];
374     unsigned int md_len = 0;
375 
376     EVP_MD_CTX_init(ctx);
377 #ifndef OPENSSL_IS_BORINGSSL
378     EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
379 #endif
380     EVP_DigestInit_ex(ctx, EVP_md5(), nullptr);
381 
382     auto currentPos = stream.tellg();
383     if (currentPos == static_cast<std::streampos>(-1)) {
384         currentPos = 0;
385         stream.clear();
386     }
387     stream.seekg(0, stream.beg);
388 
389     char streamBuffer[2048];
390     while (stream.good())
391     {
392         stream.read(streamBuffer, 2048);
393         auto bytesRead = stream.gcount();
394 
395         if (bytesRead > 0)
396         {
397             EVP_DigestUpdate(ctx, streamBuffer, static_cast<size_t>(bytesRead));
398         }
399     }
400 
401     EVP_DigestFinal_ex(ctx, md_value, &md_len);
402     EVP_MD_CTX_destroy(ctx);
403     stream.clear();
404     stream.seekg(currentPos, stream.beg);
405 
406     //Based64
407     char encodedData[100];
408     EVP_EncodeBlock(reinterpret_cast<unsigned char*>(encodedData), md_value, md_len);
409 	return encodedData;
410 #endif
411 }
HexToString(const unsigned char * data,size_t size)412 static std::string HexToString(const unsigned char *data, size_t size)
413 {
414     static char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
415     std::stringstream ss;
416     for (size_t i = 0; i < size; i++)
417         ss << hex[(data[i] >> 4)] << hex[(data[i] & 0x0F)];
418     return ss.str();
419 }
420 
ComputeContentETag(const std::string & data)421 std::string AlibabaCloud::OSS::ComputeContentETag(const std::string& data)
422 {
423     return ComputeContentETag(data.c_str(), data.size());
424 }
425 
ComputeContentETag(const char * data,size_t size)426 std::string AlibabaCloud::OSS::ComputeContentETag(const char * data, size_t size)
427 {
428     if (!data) {
429         return "";
430     }
431 #if defined(USE_CRYPTO_MBEDTLS)
432     unsigned char md_data[16];
433 
434 #if 0
435     mbedtls_md5_context ctx;
436 
437     mbedtls_md5_init(&ctx);
438     mbedtls_md5_starts_ret(&ctx);
439     mbedtls_md5_update_ret(&ctx, (const unsigned char*)data, size);
440     mbedtls_md5_finish_ret(&ctx, md_data);
441     mbedtls_md5_free(&ctx);
442 #endif
443 
444     mbedtls_md5_ret((const unsigned char*)data, size, md_data);
445 
446     return HexToString(md_data, 16);
447 
448 #elif 0//defined(USE_CRYPTO_MBEDTLS)
449 	unsigned char md_data[16];
450 
451 	mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_MD5), data, size, md_data);
452 
453 	return HexToString(md_data, 16);
454 #else
455     unsigned char md[MD5_DIGEST_LENGTH];
456     MD5(reinterpret_cast<const unsigned char*>(data), size, (unsigned char*)&md);
457 	return HexToString(md, MD5_DIGEST_LENGTH);
458 #endif
459 }
460 
ComputeContentETag(std::istream & stream)461 std::string AlibabaCloud::OSS::ComputeContentETag(std::istream& stream)
462 {
463 #ifdef USE_CRYPTO_MBEDTLS
464 	unsigned char md_value[16];
465     unsigned int md_len = 16;
466 
467 	mbedtls_md5_context ctx;
468 
469     mbedtls_md5_init( &ctx);
470     mbedtls_md5_starts_ret(&ctx);
471 
472     auto currentPos = stream.tellg();
473     if (currentPos == static_cast<std::streampos>(-1)) {
474         currentPos = 0;
475         stream.clear();
476     }
477     stream.seekg(0, stream.beg);
478 	// TODO: ethan, need to shrink the buffer, or stack overflow may happen?
479     char streamBuffer[2048];
480     while (stream.good())
481     {
482         stream.read(streamBuffer, 2048);
483         auto bytesRead = stream.gcount();
484 
485         if (bytesRead > 0)
486         {
487             mbedtls_md5_update_ret(&ctx, (const unsigned char*)streamBuffer, static_cast<size_t>(bytesRead));
488         }
489     }
490 
491     mbedtls_md5_finish_ret(&ctx, md_value);
492 	mbedtls_md5_free(&ctx);
493 
494     stream.clear();
495     stream.seekg(currentPos, stream.beg);
496     return HexToString(md_value, md_len);
497 #else
498     auto ctx = EVP_MD_CTX_create();
499 
500     unsigned char md_value[EVP_MAX_MD_SIZE];
501     unsigned int md_len = 0;
502 
503     EVP_MD_CTX_init(ctx);
504 #ifndef OPENSSL_IS_BORINGSSL
505     EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
506 #endif
507 
508     EVP_DigestInit_ex(ctx, EVP_md5(), nullptr);
509 
510     auto currentPos = stream.tellg();
511     if (currentPos == static_cast<std::streampos>(-1)) {
512         currentPos = 0;
513         stream.clear();
514     }
515     stream.seekg(0, stream.beg);
516 
517     char streamBuffer[2048];
518     while (stream.good())
519     {
520         stream.read(streamBuffer, 2048);
521         auto bytesRead = stream.gcount();
522 
523         if (bytesRead > 0)
524         {
525             EVP_DigestUpdate(ctx, streamBuffer, static_cast<size_t>(bytesRead));
526         }
527     }
528 
529     EVP_DigestFinal_ex(ctx, md_value, &md_len);
530     EVP_MD_CTX_destroy(ctx);
531     stream.clear();
532     stream.seekg(currentPos, stream.beg);
533     return HexToString(md_value, md_len);
534 #endif
535 }
536 
537 
StringReplace(std::string & src,const std::string & s1,const std::string & s2)538 void AlibabaCloud::OSS::StringReplace(std::string & src, const std::string & s1, const std::string & s2)
539 {
540     std::string::size_type pos =0;
541     while ((pos = src.find(s1, pos)) != std::string::npos)
542     {
543         src.replace(pos, s1.length(), s2);
544         pos += s2.length();
545     }
546 }
547 
LeftTrim(const char * source)548 std::string AlibabaCloud::OSS::LeftTrim(const char* source)
549 {
550     std::string copy(source);
551     copy.erase(copy.begin(), std::find_if(copy.begin(), copy.end(), [](unsigned char ch) { return !::isspace(ch); }));
552     return copy;
553 }
554 
RightTrim(const char * source)555 std::string AlibabaCloud::OSS::RightTrim(const char* source)
556 {
557     std::string copy(source);
558     copy.erase(std::find_if(copy.rbegin(), copy.rend(), [](unsigned char ch) { return !::isspace(ch); }).base(), copy.end());
559     return copy;
560 }
561 
Trim(const char * source)562 std::string AlibabaCloud::OSS::Trim(const char* source)
563 {
564     return LeftTrim(RightTrim(source).c_str());
565 }
566 
LeftTrimQuotes(const char * source)567 std::string AlibabaCloud::OSS::LeftTrimQuotes(const char* source)
568 {
569     std::string copy(source);
570     copy.erase(copy.begin(), std::find_if(copy.begin(), copy.end(), [](int ch) { return !(ch == '"'); }));
571     return copy;
572 }
573 
RightTrimQuotes(const char * source)574 std::string AlibabaCloud::OSS::RightTrimQuotes(const char* source)
575 {
576     std::string copy(source);
577     copy.erase(std::find_if(copy.rbegin(), copy.rend(), [](int ch) { return !(ch == '"'); }).base(), copy.end());
578     return copy;
579 }
580 
TrimQuotes(const char * source)581 std::string AlibabaCloud::OSS::TrimQuotes(const char* source)
582 {
583     return LeftTrimQuotes(RightTrimQuotes(source).c_str());
584 }
585 
ToLower(const char * source)586 std::string AlibabaCloud::OSS::ToLower(const char* source)
587 {
588     std::string copy;
589     if (source) {
590         size_t srcLength = strlen(source);
591         copy.resize(srcLength);
592         std::transform(source, source + srcLength, copy.begin(), [](unsigned char c) { return (char)::tolower(c); });
593     }
594     return copy;
595 }
596 
ToUpper(const char * source)597 std::string AlibabaCloud::OSS::ToUpper(const char* source)
598 {
599     std::string copy;
600     if (source) {
601         size_t srcLength = strlen(source);
602         copy.resize(srcLength);
603         std::transform(source, source + srcLength, copy.begin(), [](unsigned char c) { return (char)::toupper(c); });
604     }
605     return copy;
606 }
607 
IsIp(const std::string & host)608 bool AlibabaCloud::OSS::IsIp(const std::string &host)
609 {
610 #if defined(__GNUG__) && __GNUC__ < 5
611     int n[4];
612     char c[4];
613     const char *p = host.c_str();
614     if (sscanf(p, "%d%c%d%c%d%c%d%c", &n[0], &c[0], &n[1], &c[1], &n[2], &c[2], &n[3], &c[3]) == 7)
615     {
616         int i;
617         for (i = 0; i < 3; ++i)
618             if (c[i] != '.')
619                 return false;
620         for (i = 0; i < 4; ++i)
621             if (n[i] > 255 || n[i] < 0)
622                 return false;
623         return true;
624     }
625     return false;
626 #else
627     return std::regex_match(host, ipPattern);
628 #endif
629 }
630 
ToGmtTime(std::time_t & t)631 std::string AlibabaCloud::OSS::ToGmtTime(std::time_t &t)
632 {
633     std::stringstream date;
634     std::tm tm;
635 #ifdef _WIN32
636     ::gmtime_s(&tm, &t);
637 #else
638     ::gmtime_r(&t, &tm);
639 #endif
640 
641 #if defined(__GNUG__) && __GNUC__ < 5
642     static const char wday_name[][4] = {
643       "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
644     };
645     static const char mon_name[][4] = {
646       "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
647     };
648     char tmbuff[26];
649     snprintf(tmbuff, sizeof(tmbuff), "%.3s, %.2d %.3s %d %.2d:%.2d:%.2d",
650         wday_name[tm.tm_wday], tm.tm_mday, mon_name[tm.tm_mon],
651         1900 + tm.tm_year,
652         tm.tm_hour, tm.tm_min, tm.tm_sec);
653     date << tmbuff << " GMT";
654 #else
655     date.imbue(std::locale::classic());
656     date << std::put_time(&tm, "%a, %d %b %Y %H:%M:%S GMT");
657 #endif
658     return date.str();
659 }
660 
ToUtcTime(std::time_t & t)661 std::string AlibabaCloud::OSS::ToUtcTime(std::time_t &t)
662 {
663     std::stringstream date;
664     std::tm tm;
665 #ifdef _WIN32
666     ::gmtime_s(&tm, &t);
667 #else
668     ::gmtime_r(&t, &tm);
669 #endif
670 #if defined(__GNUG__) && __GNUC__ < 5
671     char tmbuff[26];
672     strftime(tmbuff, 26, "%Y-%m-%dT%H:%M:%S.000Z", &tm);
673     date << tmbuff;
674 #else
675     date.imbue(std::locale::classic());
676     date << std::put_time(&tm, "%Y-%m-%dT%X.000Z");
677 #endif
678     return date.str();
679 }
680 
UtcToUnixTime(const std::string & t)681 std::time_t AlibabaCloud::OSS::UtcToUnixTime(const std::string &t)
682 {
683     const char* date = t.c_str();
684     std::tm tm;
685     std::time_t tt = -1;
686     int ms;
687     auto result = sscanf(date, "%4d-%2d-%2dT%2d:%2d:%2d.%dZ",
688         &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &ms);
689 
690     if (result == 7) {
691         tm.tm_year = tm.tm_year - 1900;
692         tm.tm_mon = tm.tm_mon - 1;
693 #ifdef _WIN32
694         tt = _mkgmtime64(&tm);
695 #else
696 #if 0
697         tt = timegm(&tm);
698 #endif
699 #endif // _WIN32
700     }
701     return tt < 0 ? -1 : tt;
702 }
703 
IsValidBucketName(const std::string & bucketName)704 bool AlibabaCloud::OSS::IsValidBucketName(const std::string &bucketName)
705 {
706 #if defined(__GNUG__) && __GNUC__ < 5
707     if (bucketName.size() < 3 || bucketName.size() > 63)
708         return false;
709     for (auto it = bucketName.begin(); it != bucketName.end(); it++) {
710         if (!((*it >= 'a' && *it <= 'z') || (*it >= '0' && *it <= '9') || *it == '-'))
711             return false;
712     }
713     if (*bucketName.begin() == '-' || *bucketName.rbegin() == '-')
714         return false;
715     return true;
716 #else
717     if (bucketName.empty())
718         return false;
719     return std::regex_match(bucketName, bucketNamePattern);
720 #endif
721 }
722 
IsValidObjectKey(const std::string & key)723  bool AlibabaCloud::OSS::IsValidObjectKey(const std::string & key)
724 {
725     if (key.empty() || !key.compare(0, 1, "\\", 1))
726          return false;
727 
728     return key.size() <= ObjectNameLengthLimit;
729 }
730 
IsValidLoggingPrefix(const std::string & prefix)731  bool AlibabaCloud::OSS::IsValidLoggingPrefix(const std::string &prefix)
732  {
733      if (prefix.empty())
734          return true;
735 #if defined(__GNUG__) && __GNUC__ < 5
736      if (prefix.size() > 32)
737          return false;
738 
739      auto ch = static_cast<int>(*prefix.begin());
740      if (isalpha(ch) == 0)
741          return false;
742 
743      for (auto it = prefix.begin(); it != prefix.end(); it++) {
744          ch = static_cast<int>(*it);
745          if (!(::isalpha(ch) || ::isdigit(ch) || *it == '-'))
746              return false;
747      }
748      return true;
749 #else
750      return std::regex_match(prefix, loggingPrefixPattern);
751 #endif
752  }
753 
IsValidChannelName(const std::string & channelName)754  bool AlibabaCloud::OSS::IsValidChannelName(const std::string &channelName)
755  {
756      if(channelName.empty() ||
757         std::string::npos != channelName.find('/') ||
758         channelName.size() > MaxLiveChannelNameLength)
759         return false;
760 
761     return true;
762  }
763 
IsValidPlayListName(const std::string & playlistName)764  bool AlibabaCloud::OSS::IsValidPlayListName(const std::string &playlistName)
765  {
766      if(playlistName.empty())
767     {
768         return false;
769     }else{
770         if(!IsValidObjectKey(playlistName))
771         {
772             return false;
773         }
774         if(playlistName.size() < MinLiveChannelPlayListLength ||
775             playlistName.size() > MaxLiveChannelPlayListLength)
776         {
777             return false;
778         }
779         std::size_t lastPos = playlistName.find_last_of('.');
780         std::size_t slashPos = playlistName.find('/');
781         if(lastPos == std::string::npos ||
782             slashPos != std::string::npos ||
783             0 == lastPos || '.' == playlistName[lastPos-1])
784         {
785             return false;
786         }else{
787             std::string suffix = playlistName.substr(lastPos);
788             if(suffix.size() < 5)
789             {
790                 return false;
791             }
792             if(ToLower(suffix.c_str()) != ".m3u8")
793             {
794                 return false;
795             }
796             return true;
797         }
798     }
799  }
800 
IsValidTagKey(const std::string & key)801  bool AlibabaCloud::OSS::IsValidTagKey(const std::string &key)
802  {
803      if (key.empty() || key.size() > TagKeyLengthLimit)
804          return false;
805 
806      return true;
807  }
808 
IsValidTagValue(const std::string & value)809  bool AlibabaCloud::OSS::IsValidTagValue(const std::string &value)
810  {
811      return value.size() <= TagValueLengthLimit;
812  }
813 
LookupMimeType(const std::string & name)814 const std::string& AlibabaCloud::OSS::LookupMimeType(const std::string &name)
815 {
816     const static std::map<std::string, std::string> mimeType = {
817         {"html", "text/html"},
818         {"htm", "text/html"},
819         {"shtml", "text/html"},
820         {"css", "text/css"},
821         {"xml", "text/xml"},
822         {"gif", "image/gif"},
823         {"jpeg", "image/jpeg"},
824         {"jpg", "image/jpeg"},
825         {"js", "application/x-javascript"},
826         {"atom", "application/atom+xml"},
827         {"rss", "application/rss+xml"},
828         {"mml", "text/mathml"},
829         {"txt", "text/plain"},
830         {"jad", "text/vnd.sun.j2me.app-descriptor"},
831         {"wml", "text/vnd.wap.wml"},
832         {"htc", "text/x-component"},
833         {"png", "image/png"},
834         {"tif", "image/tiff"},
835         {"tiff", "image/tiff"},
836         {"wbmp", "image/vnd.wap.wbmp"},
837         {"ico", "image/x-icon"},
838         {"jng", "image/x-jng"},
839         {"bmp", "image/x-ms-bmp"},
840         {"svg", "image/svg+xml"},
841         {"svgz", "image/svg+xml"},
842         {"webp", "image/webp"},
843         {"jar", "application/java-archive"},
844         {"war", "application/java-archive"},
845         {"ear", "application/java-archive"},
846         {"hqx", "application/mac-binhex40"},
847         {"doc ", "application/msword"},
848         {"pdf", "application/pdf"},
849         {"ps", "application/postscript"},
850         {"eps", "application/postscript"},
851         {"ai", "application/postscript"},
852         {"rtf", "application/rtf"},
853         {"xls", "application/vnd.ms-excel"},
854         {"ppt", "application/vnd.ms-powerpoint"},
855         {"wmlc", "application/vnd.wap.wmlc"},
856         {"kml", "application/vnd.google-earth.kml+xml"},
857         {"kmz", "application/vnd.google-earth.kmz"},
858         {"7z", "application/x-7z-compressed"},
859         {"cco", "application/x-cocoa"},
860         {"jardiff", "application/x-java-archive-diff"},
861         {"jnlp", "application/x-java-jnlp-file"},
862         {"run", "application/x-makeself"},
863         {"pl", "application/x-perl"},
864         {"pm", "application/x-perl"},
865         {"prc", "application/x-pilot"},
866         {"pdb", "application/x-pilot"},
867         {"rar", "application/x-rar-compressed"},
868         {"rpm", "application/x-redhat-package-manager"},
869         {"sea", "application/x-sea"},
870         {"swf", "application/x-shockwave-flash"},
871         {"sit", "application/x-stuffit"},
872         {"tcl", "application/x-tcl"},
873         {"tk", "application/x-tcl"},
874         {"der", "application/x-x509-ca-cert"},
875         {"pem", "application/x-x509-ca-cert"},
876         {"crt", "application/x-x509-ca-cert"},
877         {"xpi", "application/x-xpinstall"},
878         {"xhtml", "application/xhtml+xml"},
879         {"zip", "application/zip"},
880         {"wgz", "application/x-nokia-widget"},
881         {"bin", "application/octet-stream"},
882         {"exe", "application/octet-stream"},
883         {"dll", "application/octet-stream"},
884         {"deb", "application/octet-stream"},
885         {"dmg", "application/octet-stream"},
886         {"eot", "application/octet-stream"},
887         {"iso", "application/octet-stream"},
888         {"img", "application/octet-stream"},
889         {"msi", "application/octet-stream"},
890         {"msp", "application/octet-stream"},
891         {"msm", "application/octet-stream"},
892         {"mid", "audio/midi"},
893         {"midi", "audio/midi"},
894         {"kar", "audio/midi"},
895         {"mp3", "audio/mpeg"},
896         {"ogg", "audio/ogg"},
897         {"m4a", "audio/x-m4a"},
898         {"ra", "audio/x-realaudio"},
899         {"3gpp", "video/3gpp"},
900         {"3gp", "video/3gpp"},
901         {"mp4", "video/mp4"},
902         {"mpeg", "video/mpeg"},
903         {"mpg", "video/mpeg"},
904         {"mov", "video/quicktime"},
905         {"webm", "video/webm"},
906         {"flv", "video/x-flv"},
907         {"m4v", "video/x-m4v"},
908         {"mng", "video/x-mng"},
909         {"asx", "video/x-ms-asf"},
910         {"asf", "video/x-ms-asf"},
911         {"wmv", "video/x-ms-wmv"},
912         {"avi", "video/x-msvideo"},
913         {"ts", "video/MP2T"},
914         {"m3u8", "application/x-mpegURL"},
915         {"apk", "application/vnd.android.package-archive"}
916         };
917 
918     const static std::string defaultType("application/octet-stream");
919     std::string::size_type last_pos  = name.find_last_of('.');
920     std::string::size_type first_pos = name.find_first_of('.');
921     std::string prefix, ext, ext2;
922 
923     if (last_pos == std::string::npos) {
924         return defaultType;
925     }
926 
927     // extract the last extension
928     if (last_pos != std::string::npos) {
929         ext = name.substr(1 + last_pos, std::string::npos);
930     }
931     if (last_pos != std::string::npos) {
932         if (first_pos != std::string::npos && first_pos < last_pos) {
933             prefix = name.substr(0, last_pos);
934             // Now get the second to last file extension
935             std::string::size_type next_pos = prefix.find_last_of('.');
936             if (next_pos != std::string::npos) {
937                 ext2 = prefix.substr(1 + next_pos, std::string::npos);
938             }
939         }
940     }
941 
942     ext = ToLower(ext.c_str());
943     auto iter = mimeType.find(ext);
944     if (iter != mimeType.end()) {
945         return (*iter).second;
946     }
947 
948     if (first_pos == last_pos) {
949         return defaultType;
950     }
951 
952     ext2 = ToLower(ext2.c_str());
953     iter = mimeType.find(ext2);
954     if (iter != mimeType.end()) {
955         return (*iter).second;
956     }
957 
958     return defaultType;
959 }
960 
CombineHostString(const std::string & endpoint,const std::string & bucket,bool isCname)961 std::string AlibabaCloud::OSS::CombineHostString(
962     const std::string &endpoint,
963     const std::string &bucket,
964     bool isCname)
965 {
966     Url url(endpoint);
967     if (url.scheme().empty()) {
968         url.setScheme(Http::SchemeToString(Http::HTTP));
969     }
970 
971     if (!bucket.empty() && !isCname && !IsIp(url.host())) {
972         std::string host(bucket);
973         host.append(".").append(url.host());
974         url.setHost(host);
975     }
976 
977     std::ostringstream out;
978     out << url.scheme() << "://" << url.authority();
979     return out.str();
980 }
981 
CombinePathString(const std::string & endpoint,const std::string & bucket,const std::string & key)982 std::string AlibabaCloud::OSS::CombinePathString(
983     const std::string &endpoint,
984     const std::string &bucket,
985     const std::string &key)
986 {
987     Url url(endpoint);
988     std::string path;
989     path = "/";
990     if (IsIp(url.host())) {
991         path.append(bucket).append("/");
992     }
993     path.append(UrlEncode(key));
994     return path;
995 }
996 
CombineRTMPString(const std::string & endpoint,const std::string & bucket,bool isCname)997 std::string AlibabaCloud::OSS::CombineRTMPString(
998     const std::string &endpoint,
999     const std::string &bucket,
1000     bool isCname)
1001 {
1002     Url url(endpoint);
1003     if (!bucket.empty() && !isCname && !IsIp(url.host())) {
1004         std::string host(bucket);
1005         host.append(".").append(url.host());
1006         url.setHost(host);
1007     }
1008 
1009     std::ostringstream out;
1010     out << "rtmp://" << url.authority();
1011     return out.str();
1012 }
1013 
CombineQueryString(const ParameterCollection & parameters)1014 std::string AlibabaCloud::OSS::CombineQueryString(const ParameterCollection &parameters)
1015 {
1016     std::stringstream ss;
1017     if (!parameters.empty()) {
1018         for (const auto &p : parameters)
1019         {
1020             if (p.second.empty())
1021                 ss << "&" << UrlEncode(p.first);
1022             else
1023                 ss << "&" << UrlEncode(p.first) << "=" << UrlEncode(p.second);
1024         }
1025     }
1026     return ss.str().substr(1);
1027 }
1028 
GetIOStreamLength(std::iostream & stream)1029 std::streampos AlibabaCloud::OSS::GetIOStreamLength(std::iostream &stream)
1030 {
1031     auto currentPos = stream.tellg();
1032     if (currentPos == static_cast<std::streampos>(-1)) {
1033         currentPos = 0;
1034         stream.clear();
1035     }
1036     stream.seekg(0, stream.end);
1037     auto streamSize = stream.tellg();
1038     stream.seekg(currentPos, stream.beg);
1039     return streamSize;
1040 }
1041 
ToStorageClassName(StorageClass storageClass)1042 const char *AlibabaCloud::OSS::ToStorageClassName(StorageClass storageClass)
1043 {
1044     static const char *StorageClassName[] = { "Standard", "IA", "Archive", "ColdArchive" };
1045     return StorageClassName[storageClass - StorageClass::Standard];
1046 }
1047 
ToStorageClassType(const char * name)1048 StorageClass AlibabaCloud::OSS::ToStorageClassType(const char *name)
1049 {
1050     std::string storageName = ToLower(name);
1051     if(!storageName.compare("ia")) return StorageClass::IA;
1052     else if (!storageName.compare("archive")) return StorageClass::Archive;
1053     else if (!storageName.compare("coldarchive")) return StorageClass::ColdArchive;
1054     else return StorageClass::Standard;
1055 }
1056 
ToAclName(CannedAccessControlList acl)1057 const char *AlibabaCloud::OSS::ToAclName(CannedAccessControlList acl)
1058 {
1059     static const char *AclName[] = { "private", "public-read", "public-read-write", "default"};
1060     return AclName[acl - CannedAccessControlList::Private];
1061 }
1062 
ToAclType(const char * name)1063 CannedAccessControlList AlibabaCloud::OSS::ToAclType(const char *name)
1064 {
1065     std::string aclName = ToLower(name);
1066     if (!aclName.compare("private")) return CannedAccessControlList::Private;
1067     else if (!aclName.compare("public-read")) return CannedAccessControlList::PublicRead;
1068     else if (!aclName.compare("public-read-write")) return CannedAccessControlList::PublicReadWrite;
1069     else return CannedAccessControlList::Default;
1070 }
1071 
ToCopyActionName(CopyActionList action)1072 const char *AlibabaCloud::OSS::ToCopyActionName(CopyActionList action)
1073 {
1074     static const char *ActionName[] = { "COPY", "REPLACE"};
1075     return ActionName[action - CopyActionList::Copy];
1076 }
1077 
ToRuleStatusName(RuleStatus status)1078 const char *AlibabaCloud::OSS::ToRuleStatusName(RuleStatus status)
1079 {
1080     static const char *StatusName[] = { "Enabled", "Disabled" };
1081     return StatusName[status - RuleStatus::Enabled];
1082 }
1083 
ToRuleStatusType(const char * name)1084 RuleStatus AlibabaCloud::OSS::ToRuleStatusType(const char *name)
1085 {
1086     std::string statusName = ToLower(name);
1087     if (!statusName.compare("enabled")) return RuleStatus::Enabled;
1088     else return RuleStatus::Disabled;
1089 }
1090 
ToLiveChannelStatusName(LiveChannelStatus status)1091 const char *AlibabaCloud::OSS::ToLiveChannelStatusName(LiveChannelStatus status)
1092 {
1093     if(status > LiveChannelStatus::LiveStatus)
1094         return "";
1095 
1096     static const char *StatusName[] = { "enabled", "disabled", "idle", "live" };
1097     return StatusName[status - LiveChannelStatus::EnabledStatus];
1098 }
1099 
ToLiveChannelStatusType(const char * name)1100 LiveChannelStatus AlibabaCloud::OSS::ToLiveChannelStatusType(const char *name)
1101 {
1102     std::string statusName = ToLower(name);
1103     if (!statusName.compare("enabled")) return LiveChannelStatus::EnabledStatus;
1104     else if (!statusName.compare("disabled")) return LiveChannelStatus::DisabledStatus;
1105     else if (!statusName.compare("idle")) return LiveChannelStatus::IdleStatus;
1106     else if (!statusName.compare("live")) return LiveChannelStatus::LiveStatus;
1107     else return LiveChannelStatus::UnknownStatus;
1108 }
1109 
ToRequestPayerName(RequestPayer payer)1110 const char* AlibabaCloud::OSS::ToRequestPayerName(RequestPayer payer)
1111 {
1112     static const char* PayerName[] = { "NotSet", "BucketOwner", "Requester"};
1113     return PayerName[static_cast<int>(payer) - static_cast<int>(RequestPayer::NotSet)];
1114 }
1115 
ToRequestPayer(const char * name)1116 RequestPayer AlibabaCloud::OSS::ToRequestPayer(const char* name)
1117 {
1118     std::string statusName = ToLower(name);
1119     if (!statusName.compare("bucketowner")) return RequestPayer::BucketOwner;
1120     else if (!statusName.compare("requester")) return RequestPayer::Requester;
1121     else return RequestPayer::NotSet;
1122 }
1123 
ToSSEAlgorithmName(SSEAlgorithm sse)1124 const char* AlibabaCloud::OSS::ToSSEAlgorithmName(SSEAlgorithm sse)
1125 {
1126     static const char* StatusName[] = { "NotSet", "KMS", "AES256" };
1127     return StatusName[static_cast<int>(sse) - static_cast<int>(SSEAlgorithm::NotSet)];
1128 }
1129 
ToSSEAlgorithm(const char * name)1130 SSEAlgorithm AlibabaCloud::OSS::ToSSEAlgorithm(const char* name)
1131 {
1132     std::string statusName = ToLower(name);
1133     if (!statusName.compare("kms")) return SSEAlgorithm::KMS;
1134     else if (!statusName.compare("aes256")) return SSEAlgorithm::AES256;
1135     else return SSEAlgorithm::NotSet;
1136 }
1137 
ToDataRedundancyType(const char * name)1138 DataRedundancyType AlibabaCloud::OSS::ToDataRedundancyType(const char* name)
1139 {
1140     std::string storageName = ToLower(name);
1141     if (!storageName.compare("lrs")) return DataRedundancyType::LRS;
1142     else if (!storageName.compare("zrs")) return DataRedundancyType::ZRS;
1143     else return DataRedundancyType::NotSet;
1144 }
1145 
ToDataRedundancyTypeName(DataRedundancyType type)1146 const char* AlibabaCloud::OSS::ToDataRedundancyTypeName(DataRedundancyType type)
1147 {
1148     static const char* typeName[] = { "NotSet", "LRS", "ZRS" };
1149     return typeName[static_cast<int>(type) - static_cast<int>(DataRedundancyType::NotSet)];
1150 }
1151 
ToVersioningStatusName(VersioningStatus status)1152 const char * AlibabaCloud::OSS::ToVersioningStatusName(VersioningStatus status)
1153 {
1154     static const char *StatusName[] = { "NotSet", "Enabled", "Suspended" };
1155     return StatusName[static_cast<int>(status) - static_cast<int>(VersioningStatus::NotSet)];
1156 }
1157 
ToVersioningStatusType(const char * name)1158 VersioningStatus AlibabaCloud::OSS::ToVersioningStatusType(const char *name)
1159 {
1160     std::string statusName = ToLower(name);
1161     if (!statusName.compare("enabled")) return VersioningStatus::Enabled;
1162     else if (!statusName.compare("suspended")) return VersioningStatus::Suspended;
1163     else return VersioningStatus::NotSet;
1164 }
1165 
ToInventoryFormatName(InventoryFormat status)1166 const char* AlibabaCloud::OSS::ToInventoryFormatName(InventoryFormat status)
1167 {
1168     static const char* StatusName[] = { "NotSet", "CSV"};
1169     return StatusName[static_cast<int>(status) - static_cast<int>(InventoryFormat::NotSet)];
1170 }
1171 
ToInventoryFormatType(const char * name)1172 InventoryFormat AlibabaCloud::OSS::ToInventoryFormatType(const char* name)
1173 {
1174     std::string statusName = ToLower(name);
1175     if (!statusName.compare("csv")) return InventoryFormat::CSV;
1176     else return InventoryFormat::NotSet;
1177 }
1178 
ToInventoryFrequencyName(InventoryFrequency status)1179 const char* AlibabaCloud::OSS::ToInventoryFrequencyName(InventoryFrequency status)
1180 {
1181     static const char* StatusName[] = { "NotSet", "Daily", "Weekly" };
1182     return StatusName[static_cast<int>(status) - static_cast<int>(InventoryFrequency::NotSet)];
1183 }
1184 
ToInventoryFrequencyType(const char * name)1185 InventoryFrequency AlibabaCloud::OSS::ToInventoryFrequencyType(const char* name)
1186 {
1187     std::string statusName = ToLower(name);
1188     if (!statusName.compare("daily")) return InventoryFrequency::Daily;
1189     else if (!statusName.compare("weekly")) return InventoryFrequency::Weekly;
1190     else return InventoryFrequency::NotSet;
1191 }
1192 
ToInventoryOptionalFieldName(InventoryOptionalField status)1193 const char* AlibabaCloud::OSS::ToInventoryOptionalFieldName(InventoryOptionalField status)
1194 {
1195     static const char* StatusName[] = { "NotSet", "Size", "LastModifiedDate", "ETag", "StorageClass", "IsMultipartUploaded", "EncryptionStatus" };
1196     return StatusName[static_cast<int>(status) - static_cast<int>(InventoryOptionalField::NotSet)];
1197 }
1198 
ToInventoryOptionalFieldType(const char * name)1199 InventoryOptionalField AlibabaCloud::OSS::ToInventoryOptionalFieldType(const char* name)
1200 {
1201     std::string statusName = ToLower(name);
1202     if (!statusName.compare("size")) return InventoryOptionalField::Size;
1203     else if (!statusName.compare("lastmodifieddate")) return InventoryOptionalField::LastModifiedDate;
1204     else if (!statusName.compare("etag")) return InventoryOptionalField::ETag;
1205     else if (!statusName.compare("storageclass")) return InventoryOptionalField::StorageClass;
1206     else if (!statusName.compare("ismultipartuploaded")) return InventoryOptionalField::IsMultipartUploaded;
1207     else if (!statusName.compare("encryptionstatus")) return InventoryOptionalField::EncryptionStatus;
1208     else return InventoryOptionalField::NotSet;
1209 }
1210 
ToInventoryIncludedObjectVersionsName(InventoryIncludedObjectVersions status)1211 const char* AlibabaCloud::OSS::ToInventoryIncludedObjectVersionsName(InventoryIncludedObjectVersions status)
1212 {
1213     static const char* StatusName[] = { "NotSet", "All", "Current" };
1214     return StatusName[static_cast<int>(status) - static_cast<int>(InventoryIncludedObjectVersions::NotSet)];
1215 }
1216 
ToInventoryIncludedObjectVersionsType(const char * name)1217 InventoryIncludedObjectVersions AlibabaCloud::OSS::ToInventoryIncludedObjectVersionsType(const char* name)
1218 {
1219     std::string statusName = ToLower(name);
1220     if (!statusName.compare("all")) return InventoryIncludedObjectVersions::All;
1221     else if (!statusName.compare("current")) return InventoryIncludedObjectVersions::Current;
1222     else return InventoryIncludedObjectVersions::NotSet;
1223 }
1224 
ToInventoryBucketFullName(const std::string & name)1225 std::string AlibabaCloud::OSS::ToInventoryBucketFullName(const std::string& name)
1226 {
1227     std::string fullName = "acs:oss:::";
1228     return fullName.append(name);
1229 }
1230 
ToInventoryBucketShortName(const char * name)1231 std::string AlibabaCloud::OSS::ToInventoryBucketShortName(const char* name)
1232 {
1233     std::string name_ = ToLower(name);
1234     std::string shortName;
1235 
1236     if (!name_.compare(0, 10, "acs:oss:::")) {
1237         shortName.append(name + 10);
1238     }
1239     return shortName;
1240 }
1241 
ToTierTypeName(TierType status)1242 const char * AlibabaCloud::OSS::ToTierTypeName(TierType status)
1243 {
1244     static const char *StatusName[] = { "Expedited", "Standard", "Bulk" };
1245     return StatusName[static_cast<int>(status) - static_cast<int>(TierType::Expedited)];
1246 }
1247 
ToTierType(const char * name)1248 TierType AlibabaCloud::OSS::ToTierType(const char *name)
1249 {
1250     std::string statusName = ToLower(name);
1251     if (!statusName.compare("expedited")) return TierType::Expedited;
1252     else if (!statusName.compare("bulk")) return TierType::Bulk;
1253     else return TierType::Standard;
1254 }
1255 
1256 #if !defined(OSS_DISABLE_RESUAMABLE) || !defined(OSS_DISABLE_ENCRYPTION)
JsonStringToMap(const std::string & jsonStr)1257 std::map<std::string, std::string> AlibabaCloud::OSS::JsonStringToMap(const std::string& jsonStr)
1258 {
1259     std::map<std::string, std::string> valueMap;
1260     Json::Value root;
1261     Json::CharReaderBuilder rbuilder;
1262     std::stringstream input(jsonStr);
1263     std::string errMsg;
1264 
1265     if (Json::parseFromStream(rbuilder, input, &root, &errMsg)) {
1266 
1267         for (auto it = root.begin(); it != root.end(); ++it)
1268         {
1269             valueMap[it.key().asString()] = (*it).asString();
1270         }
1271     }
1272 
1273     return valueMap;
1274 }
1275 
MapToJsonString(const std::map<std::string,std::string> & map)1276 std::string AlibabaCloud::OSS::MapToJsonString(const std::map<std::string, std::string>& map)
1277 {
1278     if (map.empty()) {
1279         return "";
1280     }
1281     Json::Value root;
1282     for (const auto& it : map) {
1283         root[it.first] = it.second;
1284     }
1285 
1286     Json::StreamWriterBuilder builder;
1287     builder["indentation"] = "";
1288     return Json::writeString(builder, root);
1289 }
1290 #endif
1291