1.前言
每当在认真阅读大牛们的技术blog时,心里面处理仰慕还是仰慕,但细下心来想想,其实自己从读研开始到工作,也做了不少的事情,只是自己感觉有点懒,不想动笔写blog,曾经,在读研的时候,和我一起的同学就建议过我可以写写blog神马的,但是我都是不以为然,现在想想其实大错特错了,写blog除了和别人一起分享技术之类的以外,其实也是在不断地自我总结的过程,总结多了,自然自己的无论技术上的还是写作能力上都能得到很大的提高,于是我决定从现在开始,我要好好地写blog,好好地总结自己的每一天,争取早日成为技术牛人。
2. 正题
好了,不那么多废话了,转入正题吧,这篇blog主要是写下我读研期间,在一家创业公司做云计算开发工程师时,写的一套基于OpenStack平台的C++API,该API主要是基于基础设施的API,类似于OpenStack的java,python以及PHP API,在我开发这套API时,在OpenStack平台上只有JAVA,python以及PHP的api,但是没有C++ API,而公司需要在OpenStack上进行一些有关C++的开发应用,于是,我就临时上阵,担当了开发这样一套API的作用,在开发这套API时,自己也是参考了目前的JAVA API,在进行是几点开发时,自己也遇到了很多的问题,一个最致命的问题时,java里面已经就具备了很多的第三方网络库可以使用,而在C++里面这部分明显不足,但是现在需要这样一套网络库来支持我开发OpenStack C++ API,当时也找了很久,最终决定使用libcurl这个库,这个库是一个轻量级的网络协议库,其支持很多的网络协议,这里面就有我需要的HTTP相关的一些接口,找好了一些辅助库之后,接下来就开始好好地规划API的设计了,这套API的设计主要是用C写的,但是底层的实现使用的C++,表层用C来实现主要是为了方便移植,目前这套API已经投入使用,接下来我就将这套API说明贴出来,每个API都进行了适当的说明,大家应该可以看懂
3.API说明
#include "xStatus.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef TRUE
#define TRUE 0
#endif
#ifndef FALSE
#define FALSE -1
#endif
/************************************************************************/
/* xUserInfo is used to keep user information */
/************************************************************************/
#ifndef XUSERINFO_H
typedef void* xUserInfo;
#endif
#ifndef XOBJECT_H
typedef void xObject;
#endif
typedef struct {
char** containner_names;
size_t containner_number;
} xContainerList;
typedef struct {
xObject** objects;
size_t object_number;
} xObjectList;
/*******************************************************************
General Library Functions
*******************************************************************
* Initialize Function, which initializes the userinfo struct
* out: userinfo (user information)
* return: if initialization success return xStatusOK
* this function will read property file "exacloud.properties", the properties file should be located in your project executable directory
************************************************************************** **/
xStatus xDefaultInitialize(xUserInfo* userinfo);
/** **************************************************************************
* Initialize Function, which initializes the userinfo struct
* param: username
* param: password
* param: connetction_timeout (http connection timeout)
* out: userinfo (userinfo information, the struct is very important to initialize)
* return: if initialize successfully return xStatusOK
************************************************************************** **/
xStatus xInitialize(const char* username,
const char* password,
const int connection_timeout,
xUserInfo* userinfo);
/** **************************************************************************
* DeInitialize Function which releases and destories the userinfo struct
* param: userinfo (user information)
* return: xStatusOK , if release the userinfo successfully
************************************************************************** **/
xStatus xDeinitialize(xUserInfo userinfo);
/** **************************************************************************
* Login Function which logins to ExaCloud Storage Service
* param: userinfo (user information)
* return: if login successful, then return xStatusOK
************************************************************************** **/
xStatus xLogin(xUserInfo userinfo);
/** **************************************************************************
* List containers, which gets a list of all containers in your account
* param: userinfo (user information)
* out: container_list(return container list)
* return: if container list is successfully fetched, return xStatusOK
* if using this function , it is important to remember to release the struct of container_list,
* otherwise it will cause memory leak! Please release the struct with "xClearContainerList" function ************************************************************************* **/
xStatus xListContainers(xUserInfo userinfo,
xContainerList** container_list);
/** **************************************************************************
* List containers with a limit number, which returns a containers list containing at most limited number of containers.
* param: userinfo (user information)
* param: limit(limit number of container to be returned)
* param: marker (returns containers lexicographically greater than marker. Used in conjunction with limit to paginate the list.)
* out: container_list(return container information list)
* return: if container list is successfully fetched in a limit number, return xStatusOK
* if using this function ,it is important to remember to release the struct of container_list,
* otherwise it will cause memory leak! Please release the struct with "xClearContainerList" function
************************************************************************** **/
xStatus xListContainersWithLimit(xUserInfo userinfo,
const int limit,
const char* marker,
xContainerList** container_list);
/** **************************************************************************
* Release containers list ,which releases a container_list struct
* param: container_list
* return: if container list is successfully released, return xStatusOK
************************************************************************** **/
xStatus xClearContainerList(xContainerList* container_list);
/** **************************************************************************
*List objects in specified container , which gets an object_list
* param: userinfo (user information)
* param: container_name
* out: object_list(containing object information)
* return: if an object list is successfully fetched in the specified container, return xStatusOK
* if using this function ,it is important to remember to release the struct of object_list,
* otherwise it will cause memory leak! Please release the struct with "xClearObjectList" function
************************************************************************** **/
xStatus xListObjects(xUserInfo userinfo,
const char* container_name,
xObjectList** object_list);
/** **************************************************************************
* List objects in specified container with a limit number
* param: userinfo (user information)
* param: container_name
* param: limit (the limit number of objects that you want to get)
* out: object_list(return object information list)
* return: if an object_list containing a limit number of objects in the specified container is successfully fetched, then return xStatusOK
* if using this function ,it is important to remember to release the struct of object_list,
* otherwise it will cause memory leak! Please release the struct with "xClearObjectList" function
************************************************************************** **/
xStatus xListObjectsWithLimit(xUserInfo userinfo,
const char* container_name,
const int limit,
xObjectList** object_list);
/** **************************************************************************
* List objects in specified container with a limit number and within the specified path
* param: userinfo (user information)
* param: container_name
* param: limit (the limit number of objects you want to get)
* param: path (only look for objects in this path.)
* out: object_list (return a object list)
* return: if an object list is successfully fetched, then return xStatusOK
* if using this function ,it is important to remember to release the struct of object_list,
*otherwise it will cause memory leak! Please release the struct with "xClearObjectList" function
************************************************************************** **/
xStatus xListObjectsWithLimitAndPath(xUserInfo userinfo,
const char* container_name,
const int limit,
const char* path,
xObjectList** object_list);
/** **************************************************************************
* Get the object number involving in an specified container with an specified path. Please note
* that this method has almost the same cost as listing all objects in the specified path.
* param: userinfo(user information)
* param: container_name
* param: path (only look for objects in this path)
* out: count (the number of object in the specified container and path)
* return: if the number is fetched successfully,then return xStatusOK
************************************************************************** **/
xStatus xGetObjectNums(xUserInfo userinfo,
const char* container_name,
const char* path,
size_t* count);
/** **************************************************************************
*Check container exists
* param: userinfo(user information)
* param: container_name
* return: if conainer exsits, return xStatusContainerExist
************************************************************************** **/
xStatus xContainerExists(xUserInfo userinfo,
const char* container_name);
/** **************************************************************************
* Get the container information size. This function should be called together with
* xGetContainerInfo as we need the size to prepare the container information buffer.
* param: userinfo (user information)
* param: container_name
* return: the size of container information buffer or 0 if failed
************************************************************************** **/
size_t xGetContainerInfoBufferSize(xUserInfo userinfo,
const char* container_name);
/** **************************************************************************
*Get the container information
* param: userinfo (user information)
* param: container_name
* out: containner_info_buffer (contains the container information)
* return: if container information is successfully fetched , then return xStatusOK
************************************************************************** **/
xStatus xGetContainerInfo(xUserInfo userinfo,
const char* container_name,
char* container_info_buffer);
/** **************************************************************************
*Create a container
* param: userinfo(user information)
* param: container_name
* return: if container is successfully created, then return xStatusOK
************************************************************************** **/
xStatus xCreateContainer(xUserInfo userinfo,
const char* container_name);
/** **************************************************************************
* Delete a container
* param: userinfo(user information)
* param: container_name
* return: if container is successfully deleted, then return xStatusOK
************************************************************************** **/
xStatus xDeleteContainer(xUserInfo userinfo,
const char* container_name);
/** **************************************************************************
* General store object in the specified container function
* param: userinfo(user information)
* param: container_name
* param: object_name (the destination object name)
* param: object_buffer (the source object content buffer which will be store in the container)
* param: object_size (the size of object_buffer)
* param: content_type (such value will be set in the http respect head,such as (Content-Type:"text/plain")
* param: metadata (the object metadata information,always set NULL)
* return: if store object in specified container success then return xStatusOK
************************************************************************** **/
xStatus xStoreObjectWithMeta(xUserInfo userinfo,
const char* container_name,
const char* object_name,
const char* object_buffer,
const size_t object_size,
const char* content_type,
const char* metadata);
/** **************************************************************************
* General store object in the specified container function
* param: userinfo(user information)
* param: container_name
* param: object_name (the destination object name)
* param: object_buffer (the source object content buffer which will be store in the container)
* param: object_size (the size of object_buffer)
* param: content_type (such value will be set in the http respect head,such as (Content-Type:"text/plain")
* return: if store object in specified container success then return xStatusOK
************************************************************************** **/
xStatus xStoreObject(xUserInfo userinfo,
const char* container_name,
const char* object_name,
const char* object_buffer,
const size_t object_size,
const char* content_type);
/** **************************************************************************
*Store an object in the specified container, object data is fetched from a file.
* param: userinfo (user information)
* param: container_name
* param: object_name (the destination object name, e.g. test.txt, foo/bar/test.txt)
* param: filename (the source filename which will be used to read object data)
* param: content_type (the value will be set in the http request head,such as
* (Content-Type:"text/plain")
* return: if an object is successfully stored, then return xStatusOK
************************************************************************** **/
xStatus xStoreObjectFromFile(xUserInfo userinfo,
const char* container_name,
const char* object_name,
const char* filename,
const char* content_type);
/** **************************************************************************
* Store an object in the specified container
* param: userinfo(user information)
* param: container_name
* param: object_name (the destination object name, e.g. test.txt, foo/bar/test.txt)
* param: filename (the source filename which will provide object data)
*param: content_type (such value will be set in the http respect head,such as (Content-Type:"text/plain")
*param: metadata (such value includes your upload file meta data, but you should set such variable NULL)
* return: if it is successfully stored object in specified container, then return xStatusOK
* if using this function, you should assign a save path to your upload file in ExaCloud storage server, what's more, if you prefer to upload your file to the root directory in server, you can assign the save path to be "".
************************************************************************** **/
xStatus xStoreObjectFromFileWithMeta(xUserInfo userinfo,
const char* container_name,
const char* object_name,
const char* file_name,
const char* content_type,
const char* metadata);
/** **************************************************************************
*Get the object size
* param: userinfo (user information)
* param: container_name
* param: object_name
* out: size (the size of the specified object)
* return: if size of the object is successfully fetched ,then return xStatusOK
************************************************************************** **/
xStatus xGetObjectSize(xUserInfo userinfo,
const char* container_name,
const char* object_name,
size_t* size);
/** **************************************************************************
*Get an object in specified container and store the object data in a provided buffer. This
* function should only be used for downloading a small object from ExaCloud, a recommended
* size limit is 10MB
* param: userinfo (user information)
* param: container_name
* param: object_name
* out: buffer (the buffer to put object data. It must be release by user , otherwise it will cause memory leak!)
* out: size (size of the object data)
* return: if the object is successfully fetched, then return xStatusOK
************************************************************************** **/
xStatus xGetObject(xUserInfo userinfo,
const char* container_name,
const char* object_name,
char** buffer,
size_t* size);
/** **************************************************************************
*Get an object in the specified container. This function is recommended to use for downloading
* any size of object.
* param: userinfo (user information)
* param: container_name
* param: object_name
* param: save_file_name (you must make sure such file path exist on your computer, it may
* include both file path and file name, which is an absolute path, or just a relative path.)
* return: if the object is successfully fetched, then return xStatusOK
************************************************************************** **/
xStatus xGetObjectWithFile(xUserInfo userinfo,
const char* container_name,
const char* object_name,
const char* save_file_name);
/** **************************************************************************
*Release and destory an object_list struct
* param: object_list
* return: if object list is successfully released and destoried ,return xStatusOK
************************************************************************** **/
xStatus xClearObjectList(xObjectList* object_list);
/** **************************************************************************
*Delete the object
* param: userinfo (user information)
* param: object_name
* return: if the object is successfully deleted, then return xStatusOK
************************************************************************** **/
xStatus xDeleteObject(xUserInfo userinfo,
const char* container_name,
const char* object_name);
/** **************************************************************************
* Create a path (but not any of the sub portions of the path) in the specified container. Thus, if
* “foo/bar” doesn’t exist, this function will fail on creating “foo/bar/goo”.
* param: userinfo (user information)
* param: container_name
* param: path(create relative path in container)
* return: if the path is successfully created, then return xStatusOK
************************************************************************** **/
xStatus xCreatePath(xUserInfo userinfo,
const char* container_name,
const char* path);
/** **************************************************************************
* Create all of the path elements for the entire tree for a given path. Thus, passing “foo/bar/goo”
* will creates the paths “foo”, “foo/bar”, “foo/bar/goo”.
* param: userinfo (user information)
* param: container_name
* param: fullpath
* return: if the path is successfully created, then return xStatusOK
************************************************************************** **/
xStatus xCreateFullPath(xUserInfo userinfo,
const char* container_name,
const char* fullpath);
/** **************************************************************************
* Get container name of an xObject struct
* param: xobject
* out: container_name
* return: if container name is successfully fetched,then return xStatusOK
************************************************************************** **/
xStatus xGetContainerNameFromXobject(xObject* xobject, const char** container_name);
/** **************************************************************************
* Get object name from an xObject struct
* param: xobject
* out: object_name
* return: if object name is successfully fetched,then return xStatusOK
************************************************************************** **/
xStatus xGetNameFromXobject(xObject* xobject, const char** object_name);
/** **************************************************************************
* Get object size from an xobject struct
* param: xobject
* out: object_size
* return: if object size is successfully fetched, then return xStatusOK
************************************************************************** **/
xStatus xGetSizeFromXobject(xObject* xobject, size_t* object_size);
/** **************************************************************************
* Get object mime type from an xObject struct
* param: xobject
* out: object_mime_type
* return: if object mime type is successfully fetched,then return xStatusOK
************************************************************************** **/
xStatus xGetMimeTypeFromXobject(xObject* xobject, const char** object_mime_type);
/** **************************************************************************
* Get object last modified time from an xObject struct
* param: xobject
* out: Last_Modifed time that an specified object be changed
* return: if last modified time is successfully fetched,then return xStatusOK
************************************************************************** **/
xStatus xGetLastModifiedFromXobject(xObject* xobject, const char** last_modified);
/** **************************************************************************
* Get object content MD5 from an xObject struct
* param: xobject
* out: object_Md5Sum
* return: if content MD5 is successfully fetched,then return xStatusOK
************************************************************************** **/
xStatus xGetMd5SumFromXobject(xObject* xobject, const char** object_md5sum);
#ifdef __cplusplus
}
#endif
#endif
4.API实现
#define _CRT_SECURE_NO_DEPRECATE
#include "xUserInfo.h" // need to be include before exacloudlib.h
#include "xObject.h"
#include "FileUtil.h"
#include "ExacloudClient.h"
#include "exacloudlib.h"
using namespace qunhe;
#define CONTAINER_NUMBER 1024
typedef std::map<std::string, std::string> map_meta_data;
/************************************************************************/
/* this function will return the version string */
/************************************************************************/
char* cloneString(const char* str) {
char* str_clone = (char*) malloc(strlen(str) + 1);
if (str_clone == NULL)
return NULL;
strcpy(str_clone, str);
return str_clone;
}
/** **************************************************************************
* General Library Functions
************************************************************************** **/
xStatus xDefaultInitialize(xUserInfo* userinfo) {
CURLcode return_code = curl_global_init(CURL_GLOBAL_ALL);
if (return_code != CURLE_OK) {
curl_global_cleanup();
return xStatusCurlInitFail;
}
if (userinfo == NULL)
return xStatusUserInfoNull;
xUserInfoInstance * client_instance = (xUserInfoInstance*) new ExacloudClient();
if (client_instance == NULL)
return xStatusMemoryAllocationFail;
*userinfo = (xUserInfo) client_instance;
return xStatusOK;
}
xStatus xInitialize(const char* username,
const char* password,
const int connection_timeout,
xUserInfo* userinfo) {
CURLcode return_code = curl_global_init(CURL_GLOBAL_ALL);
if (return_code != CURLE_OK) {
curl_global_cleanup();
return xStatusCurlInitFail;
}
if (username == NULL)
return xStatusUserNameNull;
if (password == NULL)
return xStatusPasswordNull;
if (userinfo == NULL)
return xStatusUserInfoNull;
*userinfo = (xUserInfo) new ExacloudClient(username, password, " ", connection_timeout);
if (*userinfo == NULL)
return xStatusMemoryAllocationFail;
return xStatusOK;
}
xStatus xDeinitialize(xUserInfo userinfo) {
curl_global_cleanup();
if (userinfo == NULL)
return xStatusOK;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
delete exacloudclient;
userinfo = NULL;
return xStatusOK;
}
void xParseMetaData(const char* metadata,
map_meta_data& meta_data) {
size_t len = strlen(metadata);
char* metas = (char*) calloc(len + 1, 1);
strncpy(metas, metadata, len);
char* temp = strtok(metas, ";");
char *key, *value;
while (temp) {
char* ptr = temp;
while (*ptr != '\0') {
if (*ptr == '=')
break;
++ptr;
}
*ptr = '\0';
++ptr;
std::string Key = temp;
std::string Value = ptr;
meta_data.insert(make_pair(Key, Value));
temp = strtok(NULL, ";");
}
free((void*) metas);
}
xStatus xLogin(xUserInfo userinfo) {
if (userinfo == NULL)
return xStatusLoginFail;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
return exacloudclient->Login();
}
xStatus xListContainers(xUserInfo userinfo,
xContainerList** container_list) {
return xListContainersWithLimit(userinfo, -1, "", container_list);
}
xStatus xListContainersWithLimit(xUserInfo userinfo,
const int limit,
const char* marker,
xContainerList** container_list) {
int current_container_number = 0;
if (userinfo == NULL)
return xStatusUserInfoNull;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
std::list<FilesContainer> filecontainer = exacloudclient->ListContainers(limit, marker);
if (filecontainer.size() <= 0)
return xStatusListContainrIsEmpty;
*container_list = (xContainerList*) malloc(sizeof (xContainerList));
if (container_list == NULL)
return xStatusMemoryAllocationFail;
(*container_list)->containner_number = filecontainer.size();
(*container_list)->containner_names = (char**) malloc((*container_list)->containner_number * (sizeof (char*)));
if (((*container_list)->containner_names) == NULL)
return xStatusMemoryAllocationFail;
memset((*container_list)->containner_names, 0, (*container_list)->containner_number * sizeof (char*));
std::list<FilesContainer>::iterator ptr = filecontainer.begin();
for (; ptr != filecontainer.end(); ++ptr) {
std::string container_name = ptr->GetName();
if (container_name.length() <= 0)
continue;
(*container_list)->containner_names[current_container_number] = cloneString(container_name.c_str());
if (((*container_list)->containner_names[current_container_number]) == NULL)
continue;
++current_container_number;
}
return xStatusOK;
}
xStatus xClearContainerList(xContainerList* container_list) {
if (container_list == NULL)
return xStatusOK;
for (int i = 0; i < container_list->containner_number; ++i) {
if (container_list->containner_names[i] == NULL)
continue;
free((void*) container_list->containner_names[i]);
}
free((void*) container_list->containner_names);
free((void*) container_list);
return xStatusOK;
}
xStatus xListObjects(xUserInfo userinfo,
const char* container_name,
xObjectList** object_list) {
return xListObjectsWithLimitAndPath(userinfo, container_name, -1, "", object_list);
}
xStatus xListObjectsWithLimit(xUserInfo userinfo,
const char* container_name,
const int limit,
xObjectList** object_list) {
return xListObjectsWithLimitAndPath(userinfo, container_name, limit, "", object_list);
}
xStatus xListObjectsWithLimitAndPath(xUserInfo userinfo,
const char* container_name,
const int limit,
const char* path,
xObjectList** object_list) {
int current_object_number = 0;
if (userinfo == NULL)
return xStatusUserInfoNull;
if (container_name == NULL)
return xStatusContainerNameNull;
if (path == NULL)
return xStatusFilePathError;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
std::list<FileObject> fileobject = exacloudclient->listObjectsStartingWith(container_name, "", path, limit, "", NULL);
if (fileobject.empty())
return xStatusListObjectEmpty;
(*object_list) = (xObjectList*) malloc(sizeof (xObjectList));
if ((*object_list) == NULL)
return xStatusMemoryAllocationFail;
(*object_list)->object_number = fileobject.size();
(*object_list)->objects = (xObject**) malloc((*object_list)->object_number * sizeof (xObject*));
if ((*object_list) == NULL)
return xStatusMemoryAllocationFail;
memset((*object_list)->objects, 0, (*object_list)->object_number * sizeof (xObject*));
std::list<FileObject>::iterator fileobjectptr = fileobject.begin();
for (; fileobjectptr != fileobject.end(); ++fileobjectptr) {
(*object_list)->objects[current_object_number] = (xObject*) malloc(sizeof (xObject));
if ((*object_list) == NULL)
continue;
memset((*object_list)->objects[current_object_number], 0, sizeof (xObject));
(*object_list)->objects[current_object_number]->container = cloneString(container_name);
(*object_list)->objects[current_object_number]->name = cloneString(fileobjectptr->getName().c_str());
(*object_list)->objects[current_object_number]->mime_type = cloneString(fileobjectptr->getmime_type().c_str());
(*object_list)->objects[current_object_number]->size = fileobjectptr->getSize();
(*object_list)->objects[current_object_number]->md5sum = cloneString(fileobjectptr->getMd5sum().c_str());
(*object_list)->objects[current_object_number]->lastModified = cloneString(fileobjectptr->getLastModified().c_str());
(*object_list)->objects[current_object_number]->userinfo = &userinfo;
++current_object_number;
}
return xStatusOK;
}
xStatus xClearObjectList(xObjectList* object_list) {
if (object_list == NULL)
return xStatusOK;
if (object_list->object_number == 0) {
free((void*) object_list);
return xStatusListObjectEmpty;
}
for (int i = 0; i < object_list->object_number; ++i) {
if (!object_list->objects[i])
continue;
free((void*) object_list->objects[i]->container);
free((void*) object_list->objects[i]->lastModified);
free((void*) object_list->objects[i]->md5sum);
free((void*) object_list->objects[i]->mime_type);
free((void*) object_list->objects[i]->name);
free((void*) object_list->objects[i]);
}
free((void*) object_list->objects);
free((void*) object_list);
return xStatusOK;
}
xStatus xContainerExists(xUserInfo userinfo,
const char* container_name) {
if (userinfo == NULL)
return xStatusUserInfoNull;
if (container_name == NULL)
return xStatusContainerNameNull;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
return exacloudclient->ContainerExists(container_name);
}
size_t xGetContainerInfoBufferSize(xUserInfo userinfo,
const char* container_name) {
if (userinfo == NULL || container_name == NULL)
return 0;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
std::string containerinfo = exacloudclient->GetContainerInfo(container_name);
if (!strcmp(containerinfo.c_str(), ""))
return 0;
return strlen(containerinfo.c_str());
}
xStatus xGetContainerInfo(xUserInfo userinfo,
const char* container_name,
char* container_info_buffer) {
if (userinfo == NULL)
return xStatusUserInfoNull;
if (container_name == NULL)
return xStatusContainerNameNull;
if (container_info_buffer == NULL)
return xStatusMemoryAllocationFail;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
std::string containerinfo = exacloudclient->GetContainerInfo(container_name);
if (!strcmp(containerinfo.c_str(), ""))
return xStatusContainerInfoNull;
strcpy(container_info_buffer, containerinfo.c_str());
return xStatusOK;
}
xStatus xCreateContainer(xUserInfo userinfo,
const char* container_name) {
if (userinfo == NULL)
return xStatusUserInfoNull;
if (container_name == NULL)
return xStatusContainerNameNull;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
return exacloudclient->CreateContainer(container_name);
}
xStatus xDeleteContainer(xUserInfo userinfo,
const char* container_name) {
if (userinfo == NULL)
return xStatusOK;
if (container_name == NULL)
return xStatusContainerNameNull;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
return exacloudclient->DeleteContainer(container_name);
}
xStatus xStoreObjectWithMeta(xUserInfo userinfo,
const char* container_name,
const char* object_name,
const char* object_buffer,
const size_t object_size,
const char* content_type,
const char* metadata) {
if (!userinfo)
return xStatusUserInfoNull;
if (!container_name)
return xStatusContainerNameNull;
if (!object_name || !object_buffer || object_size <= 0 || !content_type)
return xStatusStoreObjectFail;
map_meta_data meta_data;
if (metadata != NULL)
xParseMetaData(metadata, meta_data);
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
return exacloudclient->StoreObject(container_name, object_buffer, object_size, content_type, object_name, meta_data);
}
xStatus xStoreObject(xUserInfo userinfo,
const char* container_name,
const char* object_name,
const char* object_buffer,
const size_t object_size,
const char* content_type) {
return xStoreObjectWithMeta(userinfo, container_name, object_name, object_buffer, object_size, content_type, NULL);
}
xStatus xStoreObjectFromFile(xUserInfo userinfo,
const char* container_name,
const char* object_name,
const char* file_name,
const char* content_type) {
return xStoreObjectFromFileWithMeta(userinfo, container_name, object_name, file_name, content_type, NULL);
}
xStatus xStoreObjectFromFileWithMeta(xUserInfo userinfo,
const char* container_name,
const char* object_name,
const char* file_name,
const char* content_type,
const char* metadata) {
if (userinfo == NULL)
return xStatusUserInfoNull;
if (container_name == NULL)
return xStatusContainerNameNull;
if (object_name == NULL || file_name == NULL || content_type == NULL)
return xStatusObjctNameOrFilenameOrContentTypeIsNull;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
if (metadata == NULL)
return exacloudclient->StoreObjectAs(container_name, file_name, object_name, content_type);
map_meta_data meta_data;
if (metadata != NULL)
xParseMetaData(metadata, meta_data);
return exacloudclient->StoreObjectAs(container_name, file_name, object_name, content_type, meta_data);
}
xStatus xDeleteObject(xUserInfo userinfo,
const char* container_name,
const char* object_name) {
if (userinfo == NULL)
return xStatusOK;
if (container_name == NULL)
return xStatusContainerNameNull;
if (object_name == NULL)
return xStatusObjctNameOrFilenameOrContentTypeIsNull;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
return exacloudclient->DeleteObject(container_name, object_name);
}
xStatus xGetObjectSize(xUserInfo userinfo,
const char* container_name,
const char* object_name,
size_t* size) {
return xGetObject(userinfo, container_name, object_name, NULL, size);
}
xStatus xGetObject(xUserInfo userinfo,
const char* container_name,
const char* object_name,
char** buffer, size_t* size) {
if (userinfo == NULL)
return xStatusUserInfoNull;
if (container_name == NULL)
return xStatusContainerNameNull;
if (object_name == NULL)
return xStatusObjctNameOrFilenameOrContentTypeIsNull;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
return exacloudclient->GetObject(container_name, object_name, buffer, size);
}
xStatus xGetObjectWithFile(xUserInfo userinfo,
const char* container_name,
const char* object_name,
const char* save_file_name) {
if (userinfo == NULL)
return xStatusUserInfoNull;
if (container_name == NULL)
return xStatusContainerNameNull;
if (object_name == NULL)
return xStatusObjctNameOrFilenameOrContentTypeIsNull;
if (save_file_name == NULL)
return xStatusFilePathError;
FILE* file_hander = fopen(save_file_name, "wb");
if (file_hander == NULL)
return xStatusOpenFileFail;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
xStatus result = exacloudclient->GetObjectAs(container_name, object_name, file_hander);
fclose(file_hander);
return result;
}
xStatus xGetObjectNums(xUserInfo userinfo,
const char* container_name,
const char* path,
size_t* count) {
if (userinfo == NULL)
return xStatusUserInfoNull;
if (container_name == NULL)
return xStatusContainerNameNull;
if (path == NULL)
return xStatusFilePathError;
xObjectList* object_list;
xStatus result;
if ((result = xListObjectsWithLimitAndPath(userinfo, container_name, -1, path, &object_list)) == xStatusOK) {
if (object_list == NULL)
return xStatusObjectNotExist;
*count = object_list->object_number;
}
return result;
}
xStatus xCreatePath(xUserInfo userinfo,
const char* container_name,
const char* path) {
if (userinfo == NULL)
return xStatusUserInfoNull;
if (container_name == NULL)
return xStatusContainerNameNull;
if (path == NULL)
return xStatusFilePathError;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
return exacloudclient->CreatePath(container_name, path);
}
xStatus xCreateFullPath(xUserInfo userinfo,
const char* container_name,
const char* fullpath) {
if (userinfo == NULL)
return xStatusUserInfoNull;
if (container_name == NULL)
return xStatusContainerNameNull;
if (fullpath == NULL)
return xStatusFilePathError;
ExacloudClient* exacloudclient = (ExacloudClient*) userinfo;
return exacloudclient->CreateFullPath(container_name, fullpath);
}
xStatus xGetContainerNameFromXobject(xObject* xobject, const char** object_in_container) {
if (xobject == NULL)
return xStatusObjectNotExist;
*object_in_container = xobject->container;
return xStatusOK;
}
xStatus xGetSizeFromXobject(xObject* xobject, size_t* object_size) {
if (xobject == NULL)
return xStatusObjectNotExist;
*object_size = xobject->size;
return xStatusOK;
}
xStatus xGetNameFromXobject(xObject* xobject, const char** object_name) {
if (xobject == NULL)
return xStatusObjectNotExist;
*object_name = xobject->name;
return xStatusOK;
}
xStatus xGetMimeTypeFromXobject(xObject* xobject, const char** object_mime_type) {
if (xobject == NULL)
return xStatusObjectNotExist;
*object_mime_type = xobject->mime_type;
return xStatusOK;
}
xStatus xGetMd5SumFromXobject(xObject* xobject, const char** object_md5sum) {
if (xobject == NULL)
return xStatusObjectNotExist;
*object_md5sum = xobject->md5sum;
return xStatusOK;
}
xStatus xGetLastModifiedFromXobject(xObject* xobject, const char** object_last_modified) {
if (xobject == NULL)
return xStatusObjectNotExist;
*object_last_modified = xobject->lastModified;
return xStatusOK;
}
5.说明 这部分代码只是实现了上层的API,底层的实现我将会放在github上,方便大家下载,另外在使用时如果出现什么问题,请给我留言,转载须注明