#ifndef ANSULT_H #define ANSULT_H #define ANSULT_API __declspec(dllexport) #pragma once #include "LabVIEWHeader/extcode.h" #include #include #include #include "ANSLicense.h" #include #include "CkAuthGoogle.h" #include "CkByteData.h" #include #include #include #include #include #include #include #include namespace ANSCENTER { class ANSULT_API ANSUtilities { private: // Protects all shared mutable data mutable std::recursive_mutex _mutex; bool _isUnlockCodeValid{ false}; bool _isLicenseValid{ false}; std::string _licenseKey; std::string _unlockCode; std::string _proxyHost; int _proxyPort{ 0 }; std::string _proxyUsername; std::string _proxyPassword; bool _bProxy{ false }; std::string _fireBaseSessionToken; bool _bTls{ true }; int _port{ 443 }; bool _bAutoReconnect{ true }; bool _isAWSConnected{ false }; // Google Cloud Storage Authentication CkAuthGoogle _authGoogle; bool _isAuthenticated{ false }; SPDLogger& _logger = SPDLogger::GetInstance("ANSUtilities", false); std::chrono::system_clock::time_point tokenGeneratedTime; bool tokenInitialized = false; static const int TOKEN_EXPIRY_SECONDS = 3600; public: ANSUtilities(); ~ANSUtilities(); [[nodiscard]] bool Initialize(const std::string& licenseKey); void CheckLicense(); void CheckUnlockCode(); [[nodiscard]] bool SetServerProxy(const std::string& proxyHost, int proxyPort, const std::string& proxyUsername, const std::string& proxyPassword); [[nodiscard]] std::string GetFirebaseCloudMessageAcccessToken(std::string privateKey); //AWS SNS Functions [[nodiscard]] std::string CreateAWSSNSTopic(const std::string& topicName); // Will return the ARN of the topic [[nodiscard]] bool DeleteAWSSNSTopic(const std::string& topicARN); // Will return the ARN of the topic [[nodiscard]] std::string ListAWSSNSTopic(); // Will return the list ARN of the topic in string with ; concatenated [[nodiscard]] std::string SubcribeSMSPhoneNumber(const std::string& topicARN, const std::string& phoneNumber); [[nodiscard]] std::string SubscribeEmailAddress(const std::string& topicARN, const std::string& emailAddress); [[nodiscard]] std::string SendMessageToTopic(const std::string& topicARN, const std::string& subjectContent, const std::string& messageContent);// Return the message ID [[nodiscard]] std::string SendMessageToPhoneNumber(const std::string& phoneNumber, const std::string& messageContent);// Return the message ID // Google Cloud Storage Upload using Chilkat [[nodiscard]] bool AuthenticateGCS(const std::string& jsonKeyString); [[nodiscard]] bool UploadMatToGCS(const std::string& bucketName, const std::string& objectName, const cv::Mat& image); [[nodiscard]] bool UploadMatToGCS(const std::string& bucketName, const std::string& objectName, unsigned char* jpeg_string, int32 bufferLength); [[nodiscard]] static bool CheckUnlockCode_S(); [[nodiscard]] static std::string AESEncryption(const std::string& inputString, const std::string& inputKey); [[nodiscard]] static std::string AESDecryption(const std::string& encryptString, const std::string& inputKey); [[nodiscard]] static std::string MD5HashFile(const std::string& inputFilePath); // SMTP for office360 email sending [[nodiscard]] static bool SendEmail(const std::string& smtpServer, int port, const std::string& userName, const std::string& password, const std::string& subjectContent, const std::string& bodyHTMLContent, const std::string& bodyTextContent, const std::string& fromEmailSender, const std::vector& toEmails, const std::vector& ccEmails, const std::vector& bccEmails); // Restart PC [[nodiscard]] static bool RestartPC(); // Convert a UTF-8 encoded string to UTF-16LE byte string. // Useful for LabVIEW which can display UTF-16LE Unicode text on Windows. static std::string ConvertUTF8ToUTF16LE(const std::string& utf8Str); // Decode JSON Unicode escape sequences (\uXXXX) to UTF-16LE byte string. // Input: ASCII string with \uXXXX escapes (e.g., "\\u6c5f\\u6771 599") // Output: UTF-16LE byte string for LabVIEW display. static std::string DecodeJsonUnicodeToUTF16LE(const std::string& escapedStr); // Convert a UTF-16LE byte string to UTF-8. // Useful for receiving Unicode text from LabVIEW and converting to UTF-8 for internal processing. static std::string ConvertUTF16LEToUTF8(const char* utf16leBytes, int byteLen); // Convert UTF-16LE byte string (with optional BOM) to Unicode escape sequences (\uXXXX). // Input: raw UTF-16LE bytes (BOM is auto-stripped if present). // Output: ASCII string with \uXXXX for non-ASCII codepoints, plain ASCII chars preserved. static std::string ConvertUTF16LEToUnicodeEscapes(const char* utf16leBytes, int byteLen); // Convert Unicode escape sequences (\uXXXX) to UTF-8 string. // Input: ASCII string with \uXXXX escapes (e.g., "\\u6c5f\\u6771 599") // Output: UTF-8 encoded Unicode string. static std::string ConvertUnicodeEscapesToUTF8(const std::string& escapedStr); // Convert a UTF-8 string to Unicode escape sequences (\uXXXX). // ASCII chars (0x20-0x7E) are preserved, all others become \uXXXX. // Useful for encoding Unicode text into JSON-safe ASCII. static std::string ConvertUTF8ToUnicodeEscapes(const std::string& utf8Str); // Repair mixed-encoding input from LabVIEW text controls. // LabVIEW may produce a mix of UTF-16LE pairs and UTF-8 multi-byte // sequences in a single byte stream. It may also insert space (0x20) as // a single byte without the 0x00 high byte. // This function normalizes everything to proper UTF-16LE pairs. // Input: raw bytes from LStrHandle (BOM should already be stripped). // Output: clean UTF-16LE with proper 2-byte alignment. static std::vector RepairLabVIEWUTF16LE(const unsigned char* data, int len); // Check if a byte sequence is valid UTF-8. // Returns true if all bytes form valid UTF-8 sequences. static bool IsValidUTF8(const unsigned char* data, int len); // Double-escape \uXXXX sequences: \u1ee7 becomes \\u1ee7. // Useful when the string will be embedded in JSON and the literal \uXXXX must survive parsing. static std::string DoubleEscapeUnicode(const std::string& str); // Convert UTF-8 to double-escaped Unicode: "Thủy" becomes "Th\\u1ee7y". // Combines ConvertUTF8ToUnicodeEscapes + DoubleEscapeUnicode in one call. static std::string ConvertUTF8ToDoubleEscapedUnicode(const std::string& utf8Str); // Unescape double-escaped Unicode: "Th\\u1ee7y" becomes "Th\u1ee7y". // Reverses DoubleEscapeUnicode so other languages can parse \uXXXX correctly. static std::string UnescapeDoubleEscapedUnicode(const std::string& str); }; // Connection bundle for pool struct S3Connection { CkRest rest; CkSocket socket; CkAuthAws authAws; }; class ANSULT_API ANSAWSS3 { private: bool _isUnlockCodeValid{ false }; bool _isLicenseValid{ false }; // Atomic because upload threads read _bConnected without a lock // while Connect() / RetryLoop() can write it. std::atomic _bConnected{ false }; bool _bAwsPath{ true }; // true = virtual-hosted (AWS), false = path-style (MinIO) std::string _licenseKey; std::string _unlockCode; // ── Connection pool (replaces single _rest/_socket/_authAws) ── std::mutex _poolMutex; std::vector> _pool; // ── Config (read-only after setup, protected by _configMutex) ── std::mutex _configMutex; std::string _fullAWSURL; // AWS S3 service URL bool _bTls{ true }; int _port{ 443 }; bool _bAutoReconnect{ true }; std::string _serviceName; std::string _bucketRegion; std::string _baseDomain; std::string _accessKey; std::string _secretKey; bool _authReady{ false }; // Request timeouts applied to every new S3Connection. // _connectTimeoutMs : max time to wait for TCP/TLS connect. // _idleTimeoutMs : max gap between bytes on a send/recv. // Atomic so SetTimeouts can update them without holding _configMutex. std::atomic _connectTimeoutMs{ 10000 }; // 10 s std::atomic _idleTimeoutMs { 20000 }; // 20 s // Proxy settings std::string _proxyHost; int _proxyPort{ 0 }; std::string _proxyUsername; std::string _proxyPassword; bool _bProxy{ false }; SPDLogger& _logger = SPDLogger::GetInstance("ANSAWSS3", false); // Pool helpers std::unique_ptr CreateConnection(); std::unique_ptr AcquireConnection(); void ReleaseConnection(std::unique_ptr conn); std::string ExtractFileName(const std::string& filePath); std::string GetContentType(const std::string& filePath); // ---- Retry helper for transient / network-stability failures ---- // Each upload function delegates its per-attempt body to a lambda. // The lambda returns one of these outcomes: // Success -> stop, UploadWithRetry returns true // Transient -> retry (up to kUploadMaxAttempts total) // Permanent -> stop, UploadWithRetry returns false // The lambda should write a short human-readable reason into // `lastError` on any non-Success outcome so it can be logged. enum class AttemptResult { Success, Transient, Permanent }; static constexpr int kUploadMaxAttempts = 20; static constexpr int kUploadRetryDelayMs = 100; bool UploadWithRetry( const std::string& opName, const std::function& attemptFn); // Background retry std::thread _retryThread; std::atomic _stopRetry{ false }; std::atomic _retryInProgress{ false }; void StopRetry(); void RetryLoop(); bool TryConnect(bool& awsPath); public: ANSAWSS3(); ~ANSAWSS3(); [[nodiscard]] bool Initialize(const std::string& licenseKey); void CheckLicense(); void CheckUnlockCode(); [[nodiscard]] bool SetServerProxy(const std::string& proxyHost, int proxyPort, const std::string& proxyUsername, const std::string& proxyPassword); // Returns: 1 = connected, 0 = failed (bad auth/URL), 2 = no internet (background retry started) [[nodiscard]] int Connect(const std::string& baseDomain, const std::string& bucketRegion, const std::string& serviceName, int port, bool bTls, bool autoReconnect, bool& awsPath); [[nodiscard]] bool SetAuthentication(const std::string& accessKey, const std::string& secretKey); // Pre-populate the connection pool with `count` ready-to-use // S3Connections. Creating a connection performs a TLS handshake // inside CreateConnection(); doing it up-front in parallel keeps // the first `count` concurrent uploads from serializing on handshake. // Safe to call after Connect() + SetAuthentication() have succeeded. // Returns the number of connections actually added to the pool // (may be less than `count` on transient network issues). int PrewarmConnectionPool(int count); // Update request timeouts used by every new connection, and // propagate them to all already-pooled connections so the new // values take effect on the very next request. // connectMs: max time to wait for TCP/TLS connect (>= 1000 ms) // idleMs : max gap between bytes on send/recv (>= 1000 ms) // Returns false on invalid input (values are left unchanged). bool SetTimeouts(int connectMs, int idleMs); [[nodiscard]] std::vector ListBuckets(); [[nodiscard]] std::vector ListBucketObjects(const std::string& bucketName); [[nodiscard]] std::vector ListBucketObjectsWithPrefix(const std::string& bucketName, const std::string& prefix); [[nodiscard]] bool CreateBucket(const std::string& bucketName); [[nodiscard]] bool DeleteBucket(const std::string& bucketName); [[nodiscard]] bool CreateFolder(const std::string& bucketName, const std::string& prefix); [[nodiscard]] bool DeleteFolder(const std::string& bucketName, const std::string& prefix); [[nodiscard]] bool DeleteBucketObject(const std::string& bucketName, const std::string& objectName); [[nodiscard]] std::string GetBucketRegion(const std::string& bucketName); // Upload data to AWS S3 [[nodiscard]] bool UploadTextData(const std::string& bucketName, const std::string &textFilePath, std::string& uploadedFilePath); [[nodiscard]] bool UploadFileStream(const std::string& bucketName, const std::string& dataFilePath, std::string& uploadedFilePath); [[nodiscard]] bool UploadBinaryData(const std::string& bucketName, const std::string& dataFilePath, std::string& uploadedFilePath); [[nodiscard]] bool UploadPrefixBinaryData(const std::string& bucketName, const std::string& prefix, const std::string& dataFilePath, const std::string& objectName, std::string& uploadedFilePath); [[nodiscard]] bool UploadMultipartData(const std::string& bucketName, const std::string& dataFilePath, std::string& uploadedFilePath, int partSize=5242880); [[nodiscard]] bool UploadPrefixMultipartData(const std::string& bucketName, const std::string& prefix, const std::string& dataFilePath, const std::string& fileName, std::string& uploadedFilePath, int partSize= 5242880); [[nodiscard]] bool UploadPrefixJpegImage(const std::string& bucketName, const std::string& prefix, unsigned char* jpeg_string, int32 bufferLength, const std::string& fileName, std::string& uploadedFilePath); [[nodiscard]] bool UploadJpegImage(const std::string& bucketName, unsigned char* jpeg_string, int32 bufferLength, const std::string& fileName, std::string& uploadedFilePath); [[nodiscard]] bool DownloadFile(const std::string& bucketName, const std::string& objectName, const std::string& saveFilePath); }; } extern "C" ANSULT_API int CreateANSUtilityHandle(ANSCENTER::ANSUtilities** Handle, const char* licenseKey); extern "C" ANSULT_API int ReleaseANSUtilityHandle(ANSCENTER::ANSUtilities** Handle); extern "C" ANSULT_API int GetFCMAccessToken(ANSCENTER::ANSUtilities** Handle, const char* privateKey, LStrHandle accessToken); extern "C" ANSULT_API int CreateAWSSNSTopic(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, LStrHandle arnTopic); extern "C" ANSULT_API int DeleteAWSSNSTopic(ANSCENTER::ANSUtilities** Handle, const char* arnTopic); extern "C" ANSULT_API int ListASWTopics(ANSCENTER::ANSUtilities** Handle, LStrHandle arnTopics); extern "C" ANSULT_API int AESEncryption(const char* inputString, const char* inputKey, LStrHandle encryptionMessage); extern "C" ANSULT_API int AESDecryption(const char* encryptedString, const char* inputKey, LStrHandle decryptionMessage); extern "C" ANSULT_API int MD5HashFile(const char* filePath, LStrHandle decryptionMessage); extern "C" ANSULT_API int SubcribeSMSPhoneNumberAWSSNSTopic(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, const char* phoneNumber, LStrHandle subscribedARN); extern "C" ANSULT_API int SubcribeEmailAddressAWSSNSTopic(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, const char* emailAddress, LStrHandle subscribedARN); extern "C" ANSULT_API int SendMessageToAWSSNSTopic(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, const char* subjectContent,const char * messageContent, LStrHandle messageId); extern "C" ANSULT_API int SendMessageToPhoneNumber(ANSCENTER::ANSUtilities** Handle, const char* phoneNumber, const char* messageContent, LStrHandle messageId); extern "C" ANSULT_API int GetFCMAccessTokenCpp(ANSCENTER::ANSUtilities** Handle, const char* privateKey, std::string &accessToken); extern "C" ANSULT_API int CreateAWSSNSTopicCpp(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, std::string& arnTopic); extern "C" ANSULT_API int SubcribeSMSPhoneNumberAWSSNSTopicCpp(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, const char* phoneNumber, std::string& subscribedARN); extern "C" ANSULT_API int SubcribeEmailAddressAWSSNSTopicCpp(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, const char* emailAddress, std::string& subscribedARN); extern "C" ANSULT_API int SendMessageToAWSSNSTopicCpp(ANSCENTER::ANSUtilities** Handle, const char* snsTopicName, const char* subjectContent, const char* messageContent, std::string& messageId); extern "C" ANSULT_API int SendMessageToPhoneNumberCpp(ANSCENTER::ANSUtilities** Handle, const char* phoneNumber, const char* messageContent, std::string& messageId); extern "C" ANSULT_API int ListASWTopicsCpp(ANSCENTER::ANSUtilities** Handle, std::string& arnTopics); // Static functions extern "C" ANSULT_API int AESEncryptionCpp(const char* inputString, const char* inputKey, std::string& encryptedString); extern "C" ANSULT_API int AESDecryptionCpp(const char* encryptedString, const char* inputKey, std::string& decryptionMessage); // Google Cloud Storage extern "C" ANSULT_API int SetupServerProxy(ANSCENTER::ANSUtilities** Handle, const char* hostName, int port, const char* userName, const char* passWord); extern "C" ANSULT_API int AuthenticateGCS(ANSCENTER::ANSUtilities** Handle, const char* jsonKeyString); extern "C" ANSULT_API int UploadMatToGCS(ANSCENTER::ANSUtilities** Handle, const char* bucketName, const char* objectName, unsigned char* jpeg_string, int32 bufferLength); extern "C" ANSULT_API int UploadImageToGCS(ANSCENTER::ANSUtilities** Handle, const char* bucketName, const char* objectName, cv::Mat image); extern "C" ANSULT_API int SendEmail(const char* smtpServer, int port, const char* userName, const char* password, const char* title, const char* bodyHTMLContent, const char* bodyTextContent, const char* fromEmailSender, const char* toEmails, const char* ccEmails, const char* bccEmails); extern "C" ANSULT_API int RebootSystem(); // Unicode conversion utilities for LabVIEW extern "C" ANSULT_API int ANSConvertUTF8ToUTF16LE(const char* utf8Str, LStrHandle result, int includeBOM = 1); extern "C" ANSULT_API int ANSDecodeJsonUnicodeToUTF16LE(const char* escapedStr, LStrHandle result); extern "C" ANSULT_API int ANSConvertUTF16LEToUTF8(const unsigned char* utf16leBytes, int byteLen, LStrHandle result); extern "C" ANSULT_API int ANSConvertUTF16LEToUnicodeEscapes(const unsigned char* utf16leBytes, int byteLen, LStrHandle result); extern "C" ANSULT_API int ANSConvertUnicodeEscapesToUTF8(const char* escapedStr, LStrHandle result); // LStrHandle-safe versions: input is LStrHandle (preserves null bytes in UTF-16LE data) extern "C" ANSULT_API int ANSConvertUTF16LEToUTF8_LV(LStrHandle input, LStrHandle result); extern "C" ANSULT_API int ANSConvertUTF16LEToUnicodeEscapes_LV(LStrHandle input, LStrHandle result); extern "C" ANSULT_API int ANSConvertUTF8ToUnicodeEscapes(const char* utf8Str, LStrHandle result); extern "C" ANSULT_API int ANSDoubleEscapeUnicode(const char* str, LStrHandle result); extern "C" ANSULT_API int ANSConvertUTF8ToDoubleEscapedUnicode(const char* utf8Str, LStrHandle result); extern "C" ANSULT_API int ANSUnescapeDoubleEscapedUnicode(const char* str, LStrHandle result); // AWS S3 class extern "C" ANSULT_API int CreateANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* licenseKey); extern "C" ANSULT_API int ReleaseANSAWSHandle(ANSCENTER::ANSAWSS3** Handle); extern "C" ANSULT_API int ConnectANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* baseDomain, const char* bucketRegion, const char* serviceName, int port, int bTls, int autoReconnect, int* awsPath); extern "C" ANSULT_API int SetProxyANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* proxyHost, int proxyPort, const char* proxyUsername, const char* proxyPassword); extern "C" ANSULT_API int SetAuthenticationANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* accessKey, const char* secretKey); extern "C" ANSULT_API int ListBucketANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, std::string &bucketList); extern "C" ANSULT_API int ListBucketObjectsANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, std::string& bucketNameList); extern "C" ANSULT_API int ListBucketObjectsWithPrefixANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, std::string& bucketNameList); extern "C" ANSULT_API int GetRegionANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, std::string& region); extern "C" ANSULT_API int ListBucketANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, LStrHandle bucketList); extern "C" ANSULT_API int ListBucketObjectsANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, LStrHandle bucketNameList); extern "C" ANSULT_API int ListBucketObjectsWithPrefixANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, LStrHandle bucketNameList); extern "C" ANSULT_API int GetRegionANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, LStrHandle region); extern "C" ANSULT_API int CreateBucketANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName); extern "C" ANSULT_API int DeleteBucketANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName); extern "C" ANSULT_API int CreateBucketPrefixANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char *prefix); extern "C" ANSULT_API int DeleteBucketPrefixANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix); extern "C" ANSULT_API int DeleteBucketObjectANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* bucketObject); extern "C" ANSULT_API int UploadTextDataANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* textDataPath, LStrHandle uploadedFilePath); extern "C" ANSULT_API int UploadBinaryDataANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* binaryDataPath, LStrHandle uploadedFilePath); extern "C" ANSULT_API int UploadFileStreamDataANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* fileDataPath, LStrHandle uploadedFilePath); extern "C" ANSULT_API int UploadMultiPartDataANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* fileDataPath, int fileSize, LStrHandle uploadedFilePath); extern "C" ANSULT_API int UploadJpegImageANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, unsigned char* jpeg_string, int32 bufferLength, const char* fileName, LStrHandle uploadedFilePath); extern "C" ANSULT_API int UploadPrefixBinaryDataANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, const char* binaryDataPath, const char* objectName, LStrHandle uploadedFilePath); extern "C" ANSULT_API int UploadPrefixMultiPartDataANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, const char* fileDataPath, const char* objectName, int fileSize, LStrHandle uploadedFilePath); extern "C" ANSULT_API int UploadPrefixJpegImageANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, unsigned char* jpeg_string, int32 bufferLength, const char* fileName, LStrHandle uploadedFilePath); extern "C" ANSULT_API int DownloadFileStreamANSAWSHandle(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* objectName, const char* savedFilePath); // C++ test APIs (use std::string& instead of LStrHandle) extern "C" ANSULT_API int UploadTextDataANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* textDataPath, std::string& uploadedFilePath); extern "C" ANSULT_API int UploadBinaryDataANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* binaryDataPath, std::string& uploadedFilePath); extern "C" ANSULT_API int UploadFileStreamDataANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* fileDataPath, std::string& uploadedFilePath); extern "C" ANSULT_API int UploadMultiPartDataANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* fileDataPath, int fileSize, std::string& uploadedFilePath); extern "C" ANSULT_API int UploadJpegImageANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, unsigned char* jpeg_string, int32 bufferLength, const char* fileName, std::string& uploadedFilePath); extern "C" ANSULT_API int UploadPrefixBinaryDataANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, const char* binaryDataPath, const char* objectName, std::string& uploadedFilePath); extern "C" ANSULT_API int UploadPrefixMultiPartDataANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, const char* fileDataPath, const char* objectName, int fileSize, std::string& uploadedFilePath); extern "C" ANSULT_API int UploadPrefixJpegImageANSAWSHandle_CPP(ANSCENTER::ANSAWSS3** Handle, const char* bucketName, const char* prefix, unsigned char* jpeg_string, int32 bufferLength, const char* fileName, std::string& uploadedFilePath); #endif