1 #include <map>
2 #include <sstream>
3 #include <iostream>
4 #include "../utils.h"
5 #include "alibabacloud/core/AlibabaCloud.h"
6 #include "alibabacloud/core/CommonClient.h"
7 
8 using namespace std;
9 using namespace AlibabaCloud;
10 
11 typedef unsigned char u8_t;
12 
13 
14 const string catId = "88888888"; // ref: https://help.aliyun.com/document_detail/66623.html
15 const string itemId = "1234";
16 string custContent = "{\"key\":\"value\"}";
17 
18 map<string, string> picList;
19 map<int, string> mapStudent;
20 
21 const string jpg1 = "1.jpg";
22 const string jpg2 = "2.jpg";
23 
24 
25 
26 static const u8_t base64_table[65] =
27     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
28 
29 /**
30 * base64_encode - Base64 encode
31 * @src: Data to be encoded
32 * @len: Length of the data to be encoded
33 * @out_len: Pointer to output length variable, or %NULL if not used
34 * Returns: Allocated buffer of out_len bytes of encoded data,
35 * or empty string on failure
36 */
base64_encode(const unsigned char * src,size_t len)37 string base64_encode(const unsigned char *src, size_t len) {
38   unsigned char *out, *pos;
39   const unsigned char *end, *in;
40   size_t olen;
41 
42   olen = 4*((len + 2) / 3); /* 3-byte blocks to 4-byte */
43 
44   if (olen < len)
45     return std::string(); /* integer overflow */
46 
47   std::string outStr;
48   outStr.resize(olen);
49   out = (unsigned char*)&outStr[0];
50 
51   end = src + len;
52   in = src;
53   pos = out;
54   while (end - in >= 3) {
55     *pos++ = base64_table[in[0] >> 2];
56     *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
57     *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
58     *pos++ = base64_table[in[2] & 0x3f];
59     in += 3;
60   }
61 
62   if (end - in) {
63     *pos++ = base64_table[in[0] >> 2];
64     if (end - in == 1) {
65       *pos++ = base64_table[(in[0] & 0x03) << 4];
66       *pos++ = '=';
67     }
68     else {
69       *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
70       *pos++ = base64_table[(in[1] & 0x0f) << 2];
71     }
72     *pos++ = '=';
73   }
74   return outStr;
75 }
76 
imageBase64(string file)77 string imageBase64(string file) {
78 
79   FILE* img = nullptr;
80 #ifdef _WIN32
81   fopen_s(&img, file.c_str(), "rb");
82 #else
83   img = fopen(file.c_str(), "rb");
84 #endif
85   if (!img) {
86     perror("open file error");
87     return "";
88   }
89 
90   fseek(img, 0L, SEEK_END);
91   int size = ftell(img);
92   fseek(img, 0L, SEEK_SET);
93   u8_t* buf = (u8_t*)malloc(size);
94   int bytes = fread(buf, 1, size, img);
95   fclose(img);
96   string encoded = base64_encode(buf, bytes);
97   free(buf);
98   return encoded;
99 }
100 
buildContent(map<string,string> params)101 string buildContent(map<string, string> params) {
102   string meta = "";
103   string body = "";
104   int start = 0;
105 
106   for(auto item = params.begin(); item != params.end(); item++) {
107     auto k = item->first;
108     auto v = item->second;
109 
110     if (meta.size() > 0) {
111       meta += "#";
112     }
113 
114     std::stringstream ss1, ss2;
115     ss1 << start;
116     ss2 << start + v.size();
117 
118     meta += k + "," + ss1.str() + "," + ss2.str();
119     body += v;
120     start += v.size();
121 
122   }
123   return meta + "^" + body;
124 }
125 
buildAddContent(map<string,string> picList)126 string buildAddContent(map<string, string> picList) {
127   if (itemId.empty() || catId.empty() ) {
128     return "";
129   }
130   if (custContent.empty()) {
131     custContent = "";
132   }
133 
134   map<string, string> params;
135   params["item_id"] = itemId;
136   params["cat_id"] = catId;
137   params["cust_content"] = custContent;
138 
139   string picListStr = "";
140   for (auto item = picList.begin(); item != picList.end(); item++) {
141     auto v = item->second;
142     auto k = item->first;
143 
144     if (k.empty()) {
145       continue;
146     }
147     picListStr += k + ",";
148     params[k] = v;
149   }
150 
151   params["pic_list"] = picListStr.substr(0, picListStr.size() - 1);
152   return buildContent(params);
153 }
154 
main(int argc,char ** argv)155 int main(int argc, char** argv) {
156   utUtils utils;
157   string key = utils.get_env("ENV_AccessKeyId");
158   string secret = utils.get_env("ENV_AccessKeySecret");
159 
160   InitializeSdk();
161   ClientConfiguration configuration("cn-shanghai");
162   CommonClient client(key, secret, configuration);
163 
164   CommonRequest request(CommonRequest::RoaPattern);
165   request.setScheme("http");
166   request.setDomain("imagesearch.cn-shanghai.aliyuncs.com");
167   request.setResourcePath("/item/add");
168 
169   request.setHeaderParameter("instanceName", "sdkimagetest1");
170   request.setHttpMethod(HttpRequest::Post);
171 
172   char dir[1024];
173   utils.get_dir_exec(dir, nullptr);
174 #ifdef _WIN32
175   // windows binary has an extra Release/Debug/... dir
176   string image1_path = string(dir) + "\\..\\1.jpg";
177   string image2_path = string(dir) + "\\..\\2.jpg";
178 #else
179   string image1_path = string(dir) + "1.jpg";
180   string image2_path = string(dir) + "2.jpg";
181 #endif
182   picList[base64_encode((u8_t*)jpg1.c_str(), jpg1.size())] = imageBase64(image1_path);
183   picList[base64_encode((u8_t*)jpg2.c_str(), jpg2.size())] = imageBase64(image2_path);
184 
185   string cc = buildAddContent(picList);
186   const char* data = cc.c_str();
187   request.setContent(cc.c_str(), cc.size());
188   request.setHeaderParameter("Content-Type", "application/octet-stream;charset=utf-8");
189   request.setHeaderParameter("Accept", "application/json");
190   request.setVersion("2018-01-20");
191 
192   auto out = client.commonResponse(request);
193   if (!out.isSuccess()) {
194     cout << "error code:      " << out.error().errorCode() << endl;
195     cout << "error message:   " << out.error().errorMessage() << endl;
196     cout << "error host:      " << out.error().host() << endl;
197     cout << "error requestId: " << out.error().requestId() << endl;
198     cout << "error detail:    " << out.error().detail() << endl;
199     ShutdownSdk();
200     return -1;
201   }
202   cout << endl << "add item returns: " << out.result().payload() << endl << endl;
203   ShutdownSdk();
204   return 0;
205 }
206